Следует ли нам избегать использования шаблонов проектирования в постоянно меняющихся проектах?


32

Мой друг работает в небольшой компании над проектом, который ненавидит каждый разработчик: он вынужден выпустить как можно быстрее, он единственный, кто, похоже, заботится о техническом долге, у клиента нет технической подготовки и т. Д.

Он рассказал мне историю, которая заставила меня задуматься о целесообразности шаблонов проектирования в подобных проектах. Вот история.

Пришлось выставлять товары в разных местах на сайте. Например, менеджеры контента могут просматривать продукты, а также конечных пользователей или партнеров через API.

Иногда в продуктах отсутствовала информация: например, у некоторых из них не было цены, когда продукт был только что создан, но цена еще не указана. У некоторых не было описания (описание представляло собой сложный объект с историями изменений, локализованным контентом и т. Д.). Некоторым не хватало информации о доставке.

Вдохновленный моими недавними чтениями о шаблонах проектирования, я подумал, что это отличная возможность использовать волшебный шаблон Null Object . Я так и сделал, и все было гладко и чисто. Нужно было просто позвонить, product.Price.ToString("c")чтобы отобразить цену или product.Description.Currentпоказать описание; никаких условных вещей не требуется. До тех пор, пока однажды заинтересованная сторона не попросила отображать его по-другому в API, добавив nullв JSON. А также по-разному для контент-менеджеров, показывая «Цена не указана [Изменить]». И мне пришлось убить мою любимую модель Null Object, потому что в ней больше не было необходимости.

Таким же образом мне пришлось удалить несколько абстрактных фабрик и несколько сборщиков, в итоге я заменил свой красивый шаблон Facade прямыми и некрасивыми вызовами, потому что базовые интерфейсы менялись два раза в день в течение трех месяцев, и даже Singleton оставил меня когда требования говорят, что соответствующий объект должен быть различным в зависимости от контекста.

Более чем три недели работы состояли из добавления шаблонов проектирования, а затем разрыва их на месяц позже, и мой код, наконец, стал достаточно спагетти, чтобы его никто не мог поддерживать, включая меня самого. Не лучше ли вообще никогда не использовать эти шаблоны?

Действительно, мне приходилось работать над проектами тех типов, где требования постоянно меняются и диктуются людьми, которые на самом деле не имеют в виду сплоченность или согласованность продукта. В этом контексте не важно, насколько вы гибки, вы получите элегантное решение проблемы, и когда вы, наконец, внедрите его, вы узнаете, что требования изменились настолько радикально, что ваше элегантное решение не подходит больше

Каково было бы решение в этом случае?

  • Не использовать какие-либо шаблоны проектирования, перестать думать и писать код напрямую?

    Было бы интересно провести опыт, когда одна команда пишет код напрямую, а другая дважды подумает, прежде чем набирать текст, рискуя тем, что несколько дней спустя выбрасывает оригинальный дизайн: кто знает, может быть, обе команды получат тот же технический долг. В отсутствие таких данных я бы только утверждал, что он не считает нужным набирать код без предварительного обдумывания при работе над проектом на 20 человеко-месяцев.

  • Сохранить шаблон проектирования, который больше не имеет смысла, и попытаться добавить больше шаблонов для вновь созданной ситуации?

    Это тоже не кажется правильным. Шаблоны используются для упрощения понимания кода; положить слишком много шаблонов, и код станет беспорядок.

  • Начать думать о новом дизайне, который охватывает новые требования, а затем постепенно преобразовать старый дизайн в новый?

    Как теоретик и тот, кто предпочитает Agile, я полностью увлечен этим. На практике, когда вы знаете, что вам придется возвращаться к доске каждую неделю и переделывать большую часть предыдущего дизайна, и что у клиента просто не хватает средств, чтобы заплатить вам за это, или не хватает времени ждать это, вероятно, не сработает.

Итак, есть предложения?


43
Я думаю, что это ложная дилемма. По собственному признанию вашего друга, код теперь является непоправимой тарелкой спагетти. Это не вина шаблонов программного обеспечения; это неспособность вашего друга правильно использовать эти шаблоны таким образом, чтобы повысить удобство обслуживания, а не уменьшить его. Когда я смогу привести конкретные примеры, я выложу правильный ответ.
Роберт Харви

5
Кроме того, FWIW, любой клиент, у которого нет некоторой терпимости к дрейфующим затратам, вероятно, не должен делать Agile, если только нет затрат, встроенных в затраты на изменение требований.
Роберт Харви

5
я подозреваю, что без шаблонов проектирования код достиг бы неустранимого состояния гораздо раньше
Стивен А. Лоу

28
Этот вопрос не имеет никакого смысла. Единственный способ «избежать шаблонов проектирования» - вообще не писать никакого программного обеспечения. Такие вещи, как «XYZ Pattern» - это просто названия, которые даны общим стратегиям кодирования, чтобы позволить нам, программистам, более удобно передавать информацию и советы о нашей структуре и выборе кода. Любой выбор дизайна в вашем коде может быть назван и назван «шаблоном дизайна», хотя и не обязательно широко известным (если, я полагаю, вы не гордитесь своим уникальным дизайном и не достаточно мотивированы, чтобы дать ему имя и вести блог о это или что-то).
Джейсон С

9
Т.е. вы можете не называть свою ногу "ногой", но у вас все еще есть эта нога, просто с кем-то об этом говорить сложнее, если вы не называете ее "ногой". Вы можете подумать, что вы «избегаете шаблонов проектирования», но если вы придумали достойный дизайн, который работает, а затем отступите и посмотрите, вы, вероятно, обнаружите, что ваш проект в конечном итоге вписался в один из общих именованных шаблонов в любом случае, называете ли вы это так или нет.
Джейсон С

Ответы:


86

Я вижу некоторые неправильные предположения в этом вопросе:

  • Код с шаблонами проектирования, хотя и применяется правильно, требует больше времени для реализации, чем код без этих шаблонов.

Шаблоны проектирования не являются самоцелью, они должны служить вам, а не наоборот. Если шаблон проектирования не делает код более легким для реализации или, по крайней мере, лучше развивающимся (что означает: его легче адаптировать к изменяющимся требованиям), тогда шаблон не соответствует своему назначению. Не применяйте шаблоны, если они не облегчают жизнь команде. Если новый шаблон объекта Null служил вашему другу в течение того времени, когда он его использовал, то все было в порядке. Если это должно было быть устранено позже, тогда это могло бы быть также хорошо. Если шаблон объекта Null замедлял (правильную) реализацию, то его использование было неправильным. Обратите внимание, что из этой части истории пока нельзя сделать вывод о какой-либо причине «кода спагетти».

  • клиент виноват, потому что у него нет технической подготовки и он не заботится о сплоченности или согласованности продукта

Это не его работа и не его вина! Ваша задача - заботиться о сплоченности и согласованности. Когда требования меняются два раза в день, ваше решение не должно жертвовать качеством кода. Просто скажите клиенту, сколько времени это займет, и если вы считаете, что вам нужно больше времени для «правильного» проектирования, то добавьте достаточно большой запас прочности к любой оценке. Особенно, когда у вас есть клиент, пытающийся оказать на вас давление, используйте «принцип Скотти» . И, споря с нетехническим клиентом об усилиях, избегайте таких терминов, как «рефакторинг», «модульные тесты», «шаблоны проектирования» или «документация кода» - это вещи, которые он не понимает и, вероятно, считает «ненужными». ерунда ", потому что он не видит в этом никакой ценности. или, по крайней мере, понятным для клиента (функции, подфункции, изменения поведения, пользовательские документы, исправления ошибок, оптимизация производительности и т. д.).

  • решение для быстро меняющихся требований заключается в быстром изменении кода

Честно говоря, если «базовые интерфейсы меняются два раза в день в течение трех месяцев», то решением не должно быть реагирование путем изменения кода два раза в день. Реальное решение состоит в том, чтобы спросить, почему требования так часто меняются и возможно ли внести изменения в этой части процесса. Может быть, поможет еще какой-то предварительный анализ. Возможно, интерфейс слишком широкий, потому что граница между компонентами выбрана неправильно. Иногда это помогает запросить дополнительную информацию о том, какая часть требований является стабильной, а какие все еще обсуждаются (и фактически откладывают реализацию обсуждаемых вопросов). И иногда некоторых людей просто «пинают в задницы» за то, что они не передумали дважды в день.


30
+1 - вы не можете решать проблемы людей с помощью технических решений.
Теластин

1
+1, но "или, по крайней мере, лучше развиваться (это означает: легче адаптироваться к меняющимся требованиям)" - я бы отнес это к разумно меняющимся требованиям, верно?
Фурманатор

1
@Fuhrmanator: Я думаю, что это трудно обсуждать в общих чертах. ИМХО очевидно, что никакой шаблон проектирования не поможет вам, когда ваше первое требование - «нам нужен текстовый процессор», а это изменится на «нам нужен симулятор полета». Для менее радикальных изменений требований не всегда легко решить, что поможет вам поддерживать ваше программное обеспечение в развитии. ИМХО лучше всего не применять слишком много шаблонов, но некоторые принципы - в основном принципы SOLID и YAGNI. И я согласен на 100% с Теластином - когда требования меняются слишком часто, это, вероятно, не техническая проблема.
Док Браун

4
+1 - «Честно говоря, если« базовые интерфейсы меняются два раза в день в течение трех месяцев », то решение не должно заключаться в том, чтобы реагировать путем изменения кода два раза в день. Реальное решение состоит в том, чтобы спросить, почему требования меняются так часто, и если в этой части процесса можно внести изменения. «Если вам постоянно дают новые указания, лучше всего сесть со всеми заинтересованными сторонами и подтвердить свои ожидания. Разберитесь со своими различиями и, надеюсь, не тратьте впустую время и деньги, поставив перед проектом более ясную цель.
крильгар

1
@Cornelius Док Браун сказал, что это сложно без конкретности. Требования, предъявляемые к текстовому процессору к летному симулятору, не будут разумными; никакой шаблон дизайна не поможет. Между его примером и, скажем, добавлением нового формата файла в функцию сохранения текстового процессора (что вполне разумно) есть много серой области. Без конкретики это сложно обсуждать. Кроме того, это не значит, что никто не хотел бы меняться. Дело в том, что такие изменения трудны, если вы уже сделали выбор дизайна на основе требований. Текстовый процессор и симулятор полета - отличный пример раннего выбора.
Фурманатор

43

Мое скромное мнение, что вы не должны избегать или не избегать использования шаблонов дизайна.

Шаблоны проектирования - это просто хорошо известные и надежные решения общих проблем, которым были даны имена. Они не отличаются в техническом отношении от любого другого решения или дизайна, о котором вы только можете подумать.

Я думаю, что корень проблемы может заключаться в том, что ваш друг думает с точки зрения «применения или не применения шаблона проектирования», а не с точки зрения «что является лучшим решением, которое я могу придумать, включая, но не ограничиваясь шаблонами» Я знаю".

Возможно, этот подход заставляет его использовать шаблоны частично искусственным или принудительным образом, в местах, где они не принадлежат. И это то, что приводит к беспорядку.


13
+1 «Шаблоны проектирования - это просто хорошо известные и заслуживающие доверия решения общих проблем, которым были даны имена. Они не отличаются технически от любого другого решения или дизайна, которые вы можете придумать». В точку. Люди настолько увлекаются именованными шаблонами проектирования, что забывают, что это не что иное, как имена, данные различным стратегиям, чтобы нам, программистам, было проще общаться друг с другом о нашем коде и наших вариантах проектирования. Такое отношение очень часто связано с попыткой навязать неуместные «шаблоны» для проблем, которые не обязательно приносят пользу - большой беспорядок.
Джейсон С

14

В вашем примере использования шаблона Null Object я считаю, что в конечном итоге он потерпел неудачу, потому что он отвечал потребностям программиста, а не потребностям клиента. Клиент должен был отобразить цену в форме, соответствующей контексту. Программист должен был упростить некоторые коды отображения.

Итак, если шаблон проектирования не соответствует требованиям, мы говорим, что все шаблоны проектирования - пустая трата времени, или мы говорим, что нам нужен другой шаблон проектирования?


9

Казалось бы, ошибка заключалась скорее в удалении объектов шаблона, чем в их использовании. В первоначальном проекте Нулевой Объект, по-видимому, обеспечил решение проблемы. Это, возможно, не было лучшим решением.

Быть единственным человеком, работающим над проектом, дает вам возможность испытать весь процесс разработки. Большим недостатком является отсутствие кого-то, чтобы быть вашим наставником. Потратив время на изучение и применение лучших или лучших практик, вы быстро окупитесь. Хитрость в том, чтобы определить, какую практику учить когда.

Связывание ссылок в форме product.Price.toString ('c') нарушает закон Деметры . Я видел все виды проблем с этой практикой, многие из которых относятся к нулям. Такой метод, как product.displayPrice ('c'), может внутренне обрабатывать нулевые цены. Аналогично product.Description.Current может обрабатываться product.displayDescription (), product.displayCurrentDescription (). или product.diplay («Текущий»).

Обработка нового требования к менеджерам и поставщикам контента должна выполняться с учетом контекста. Существует множество подходов, которые можно использовать. Методы фабрики могут использовать разные классы продуктов в зависимости от класса пользователя, которому они будут отображаться. Другой подход заключается в том, чтобы методы отображения класса продукта создавали разные данные для разных пользователей.

Хорошая новость в том, что ваш друг понимает, что все выходит из-под контроля. Надеюсь, у него есть код в контроле версий. Это позволит ему отвергать плохие решения, которые он всегда будет принимать. Часть обучения состоит в том, чтобы попробовать разные подходы, некоторые из которых потерпят неудачу. Если он справится со следующими несколькими месяцами, он может найти подходы, которые упростят его жизнь и очистят спагетти. Он мог попытаться исправить одну вещь каждую неделю.


2
Кроме того, это также может указывать, видя, что вы «должны» нарушить закон Деметры, что модель, используемая на поверхности, не подходит. Почему «модель представления» (используемая в широком смысле) не просто имеет описание для отображения? (Т.е. почему на уровне пользовательского интерфейса есть нечто большее, чем просто текущее описание?) Бизнес-уровень может подготовить соответствующим образом заполненный объект для уровня пользовательского интерфейса, который уже имеет различное содержимое, в зависимости от того, является ли он менеджером или нет.
Корнелиус

7

Вопрос кажется неправильным во многих аспектах. Но вопиющие из них:

  • Для упомянутого вами шаблона нулевого объекта после изменения требований вы немного меняете код. Это хорошо, но это не значит, что вы «убиваете» шаблон нулевого объекта (кстати, будьте осторожны с вашей формулировкой, это звучит слишком экстремально, некоторые люди с слишком паранойей не будут воспринимать это как смешное).

Многие люди правильно сказали, что шаблоны проектирования - это очень много общего с маркировкой и наименованием. Так что подумайте о рубашке, у рубашки есть воротник, по какой-то причине вы снимаете воротник или часть воротника. Меняется название и маркировка, но по сути это все-таки рубашка. Это именно тот случай, незначительные изменения в деталях, которые не означают, что вы «убили» этот шаблон. (снова возражаю против крайних формулировок)

  • Дизайн, о котором вы говорили, плох, потому что, когда изменения требований становятся незначительными, вы вносите масштабные стратегические изменения повсюду. Если бизнес-проблема высокого уровня не изменится, вы не сможете оправдать масштабные изменения дизайна.

По моему опыту, когда появляются незначительные требования, вам нужно изменить только небольшую часть кода. Некоторые могут быть немного хакерскими, но ничего слишком серьезного, чтобы существенно повлиять на удобство обслуживания или читабельность, и часто достаточно нескольких строк комментария для объяснения хакерской части. Это очень распространенная практика.


7

Давайте на минуту остановимся и рассмотрим фундаментальную проблему - создание системы, в которой архитектурная модель слишком связана с низкоуровневыми функциями в системе, что приводит к частым сбоям архитектуры в процессе разработки.

Я думаю, что мы должны помнить, что использование архитектуры и связанных с этим шаблонов проектирования должно быть заложено на соответствующем уровне, и что анализ того, что является правильным уровнем, не является тривиальным. С одной стороны, вы могли бы легко поддерживать архитектуру вашей системы на слишком высоком уровне только с очень простыми ограничениями, такими как «MVC» или тому подобное, что может привести к упущенным возможностям, как в четких рекомендациях и использовании кода, и где спагетти-код может легко процветать во всем этом свободном пространстве.

С другой стороны, вы можете с таким же успехом перепроектировать свою систему, как и при установке ограничений на детальный уровень, когда вы предполагаете, что можете полагаться на ограничения, которые в действительности более изменчивы, чем вы ожидаете, постоянно нарушая свои ограничения и заставляя вас постоянно переделывать и перестраивать, пока вы не начнете отчаиваться.

Изменения в требованиях к системе всегда будут в той или иной степени. И потенциальные преимущества использования архитектурных и дизайнерских шаблонов всегда будут присутствовать, поэтому на самом деле не стоит вопрос использования шаблонов проектирования или нет, но на каком уровне вы должны их использовать.

Это требует, чтобы вы не только понимали текущие требования к предлагаемой системе, но и определяли, какие ее аспекты можно рассматривать как стабильные основные свойства системы, и какие свойства могут измениться в ходе разработки.

Если вы обнаружите, что вам постоянно приходится бороться с неорганизованным спагетти-кодом, вы, вероятно, недостаточно работаете с архитектурой или на высоком уровне. Если вы обнаружите, что ваша архитектура часто ломается, вы, вероятно, делаете слишком подробную архитектуру.

Использование архитектурных и дизайнерских шаблонов - это не то, что можно просто «покрыть» системой, как если бы вы нарисовали стол. Это методы, которые следует применять вдумчиво, на уровне, где ограничения, на которые вы должны полагаться, имеют высокую вероятность быть стабильными, и где эти методы действительно стоят задач моделирования архитектуры и реализации фактических ограничений / архитектуры / шаблонов. как код

Относительно вопроса о слишком детальной архитектуре, вы также можете приложить немало усилий в архитектуре, где она не дает особой ценности. См. Ориентированную на риск архитектуру для справки, мне нравится эта книга - Достаточно программной архитектуры , возможно, вам тоже.

редактировать

Уточнил свой ответ, поскольку я понял, что часто выражал себя как «слишком много архитектуры», где я действительно имел в виду «слишком детальную архитектуру», что не совсем то же самое. Слишком детальная архитектура, вероятно, часто может рассматриваться как «слишком большая» архитектура, но даже если вы поддерживаете архитектуру на хорошем уровне и создаете самую красивую систему, которую когда-либо видело человечество, это все равно может быть слишком большим усилием для архитектуры, если приоритеты на особенности и время выхода на рынок.


+1 Это очень хорошие мысли об очень высоком уровне, я думаю, вы должны смотреть в систему, но, как вы сказали, это требует большого опыта в разработке программного обеспечения.
Самуил

4

Ваш друг, кажется, сталкивается с многочисленными встречными ветрами, основанными на его анекдоте. Это прискорбно и может быть очень сложной средой для работы. Несмотря на трудности, он был на правильном пути использования шаблонов, чтобы облегчить свою жизнь, и это позор, что он ушел с этого пути. Код спагетти - это конечный результат.

Поскольку существуют две разные проблемные области, техническая и межличностная, я буду решать каждую из них отдельно.

Межличностные

Борьба вашего друга связана с быстро меняющимися требованиями и с тем, как это влияет на его способность писать поддерживаемый код. Прежде всего, я бы сказал, что требования, меняющиеся два раза в день, каждый день в течение такого длительного периода времени, являются более серьезной проблемой и имеют нереалистичные неявные ожидания. Требования меняются быстрее, чем код может измениться. Мы не можем ожидать, что код или программист будут в курсе. Этот быстрый темп изменений является симптомом неполной концепции желаемого продукта на более высоком уровне. Это проблема. Если они не знают, чего они на самом деле хотят, они потратят много времени и денег, чтобы никогда этого не получить.

Это может быть хорошо, чтобы установить границы для изменений. Сгруппируйте изменения в наборы каждые две недели, затем заморозьте их на две недели, пока они будут внедрены. Создайте новый список на следующие две недели. У меня есть чувство, что некоторые из этих изменений перекрываются или противоречат друг другу (например, колеблются между двумя вариантами). Когда изменения происходят быстро и яростно, все они имеют высший приоритет. Если вы позволите им накапливаться в списке, вы можете работать с ними, чтобы упорядочить и расставить приоритеты, что является наиболее важным для максимизации усилий и производительности. Они могут видеть, что некоторые из их изменений глупы или менее важны, давая вашему другу немного передышки.

Эти проблемы не должны мешать вам писать хороший код. Плохой код приводит к худшим проблемам. Рефакторинг от одного решения к другому может занять некоторое время, но сам факт того, что это возможно, показывает преимущества хорошей практики кодирования через шаблоны и принципы.

В условиях частых изменений, технический долг будет поступать из - за какими - то момент. Гораздо лучше совершать платежи к нему, чем бросать полотенце и ждать, пока оно не станет слишком большим, чтобы его преодолеть. Если шаблон больше не полезен, отредактируйте его, но не возвращайтесь к способам кодирования ковбоя.

технический

Кажется, ваш друг хорошо разбирается в основных шаблонах дизайна. Нулевой объект - это хороший подход к проблеме, с которой он столкнулся. По правде говоря, это все еще хороший подход. Там, где он, кажется, испытывает трудности, понимает принципы, лежащие в основе шаблонов, почему они есть. В противном случае, я не верю, что он отказался бы от своего подхода.

(Далее следует набор технических решений, которые не запрашивались в первоначальном вопросе, но которые показывают, как мы могли придерживаться шаблонов в иллюстративных целях.)

Принцип, лежащий в основе нулевого объекта - это идея инкапсулирования того, что меняется . Мы скрываем, что меняется, поэтому нам не приходится иметь дело с этим повсюду. Здесь нулевой объект инкапсулировал дисперсию в product.Priceэкземпляре (я назову это Priceобъектом, и цена нулевого объекта будет равна NullPrice). Priceэто предметный предмет, бизнес-концепция. Иногда в нашей бизнес-логике мы еще не знаем цену. Это случилось. Идеальный вариант использования для нулевого объекта. PriceУ него есть ToStringметод, который выводит цену или пустую строку, если она неизвестна (или NullPrice#ToStringвозвращает пустую строку). Это разумное поведение. Тогда требования меняются.

Мы должны вывести a nullв представление API или строку, отличную от представления менеджеров. Как это влияет на нашу бизнес-логику? Ну, это не так. В приведенном выше утверждении я дважды использовал слово «просмотр». Это слово, вероятно, не было сказано явно, но мы должны научиться слышать скрытые слова в требованиях. Так почему же «вид» так важен? Потому что это говорит нам, где действительно должны произойти изменения: на наш взгляд.

Кроме того : неважно, используем мы фреймворк MVC или нет. В то время как MVC имеет очень специфическое значение для «View», я использую его в более общем (и, возможно, более применимом) значении фрагмента кода представления.

Так что нам действительно нужно это исправить в представлении. Как мы могли это сделать? Самым простым способом сделать это было бы ifутверждение. Я знаю, что нулевой объект был предназначен, чтобы избавиться от всех ifs, но мы должны быть прагматичными. Мы можем проверить строку, чтобы увидеть, если она пуста, и переключиться:

if(product.Price.ToString("c").Length == 0) { // one way of many
    writer.write("Price unspecified [Change]");
} else {
    writer.write(product.Price.ToString("c"));
}

Как это влияет на инкапсуляцию? Наиболее важной частью здесь является то, что логика представления инкапсулирована в представление . Таким образом, мы можем сохранить нашу бизнес-логику / доменные объекты полностью изолированными от изменений в логике представления. Это некрасиво, но это работает. Это не единственный вариант, хотя.

Мы могли бы сказать, что наша бизнес-логика немного изменилась: мы хотим выводить строки по умолчанию, если цена не установлена. Мы можем внести незначительные изменения в наш Price#ToStringметод (фактически создать перегруженный метод). Мы можем принять возвращаемое значение по умолчанию и вернуть его, если цена не установлена:

class Price {
    ...
    // A new ToString method
    public string ToString(string c, string default) {
        return ToString(c);
    }
    ...
}

class NullPrice {
    ...
    // A new ToString method
    public string ToString(string c, string default) {
        return default;
    }
    ...
}

И теперь наш код представления становится:

writer.write(product.Price.ToString("c", "Price unspecified [Change]"));

Условие ушло. Однако, если вы сделаете это слишком много, это может привести к распространению специальных методов case в ваши доменные объекты, так что это имеет смысл только в том случае, если будет только несколько примеров этого.

Вместо этого мы могли бы создать IsSetметод, Priceкоторый возвращает логическое значение:

class Price {
    ...
    public bool IsSet() {
        return return true;
    }
    ...
}

class NullPrice {
    ...
    public bool IsSet() {
        return false;
    }
    ...
}

Посмотреть логику:

if(product.Price.IsSet()) {
    writer.write(product.Price.ToString("c"));
} else {
    writer.write("Price unspecified [Change]");
}

Мы видим возврат условного в представлении, но дело в том, что бизнес-логика говорит, установлена ​​ли цена. Мы можем использовать в Price#IsSetдругом месте сейчас, когда у нас есть в наличии.

Наконец, мы можем заключить в себе идею представления цены полностью в качестве помощника для представления. Это скрыло бы условное выражение, сохранив объект домена столько, сколько мы хотели бы:

class PriceStringHelper {
    public PriceStringHelper() {}

    public string PriceToString(Price price, string default) {
        if(price.IsSet()) { // or use string length to not change the Price class at all
           return price.ToString("c");
        } else {
            return default;
        }
    }
}

Посмотреть логику:

writer.write(new PriceStringHelper().PriceToString(product.Price, "Price unspecified [Change]"));

Есть еще много способов внести изменения (мы можем обобщить PriceStringHelperв объект, который возвращает значение по умолчанию, если строка пуста), но это несколько быстрых, которые сохраняют (по большей части) как шаблоны, так и принципы, как а также прагматический аспект внесения таких изменений.


3

Сложность шаблона проектирования может укусить вас, если проблема, которую он должен был решить, внезапно исчезнет. К сожалению, из-за энтузиазма и популярности шаблонов проектирования этот риск редко выражается. Анекдот вашего друга очень помогает показать, как шаблоны не окупаются. У Джеффа Этвуда есть несколько слов на эту тему.

Документируйте точки отклонения (это риски) в требованиях

Многие из более сложных шаблонов проектирования (не так много Null Object) содержат концепцию защищенных вариантов , а именно: «Определение точек прогнозируемого изменения или нестабильности; распределение обязанностей по созданию стабильного интерфейса вокруг них». Адаптер, Посетитель, Фасад, Слои, Наблюдатель, Стратегия, Декоратор и т. Д. Используют этот принцип. Они «окупаются», когда программное обеспечение необходимо расширить в аспекте ожидаемой изменчивости, а «стабильные» допущения остаются стабильными.

Если ваши требования настолько нестабильны, что ваши «прогнозируемые отклонения» всегда неверны, то применяемые вами шаблоны причинят вам боль или станут в лучшем случае ненужной сложностью.

Крейг Ларман говорит о двух возможностях применения защищенных вариантов:

  • точки изменения - в существующей, текущей системе или требованиях, таких как несколько интерфейсов, которые должны поддерживаться, и
  • Точки эволюции - спекулятивные точки вариации, которых нет в существующих требованиях.

Предполагается, что оба документа задокументированы разработчиками, но, вероятно, у вас должна быть приверженность клиентов к вариантам.

Чтобы управлять рисками, можно сказать, что любой шаблон проектирования, использующий PV, должен быть прослежен до точки изменения требований, подписанных заказчиком. Если клиент меняет точку изменения в требованиях, ваш дизайн может измениться радикально (потому что вы, вероятно, вложили средства в дизайн [шаблоны], чтобы поддержать это изменение). Не нужно объяснять сплоченность, сцепление и т. Д.

Например, ваш клиент хочет, чтобы программное обеспечение работало с тремя различными устаревшими системами инвентаризации. Это точка вариации, которую вы разрабатываете вокруг. Если заказчик откажется от этого требования, то, конечно, у вас будет куча бесполезной инфраструктуры проектирования. Клиент должен знать, что точки изменения чего-то стоят.

CONSTANTS в исходном коде это простая форма PV

Другая аналогия с вашим вопросом - спросить, является ли использование CONSTANTSв исходном коде хорошей идеей. Ссылаясь на этот пример , скажем, клиент отказался от паролей. Таким образом MAX_PASSWORD_SIZE, постоянное распространение по всему вашему коду станет бесполезным и даже станет помехой в обслуживании и удобочитаемости. Вы бы обвинить использование в CONSTANTSкачестве причины?


2

Я думаю, что это хотя бы частично зависит от характера вашей ситуации.

Вы упомянули постоянно меняющиеся требования. Если клиент говорит: «Я хочу, чтобы это приложение для пчеловодства также работало с осами», то это похоже на ситуацию, в которой тщательный дизайн поможет прогрессу, а не помешает ему (особенно если учесть, что в будущем она может захотеть держать и плодовых мушек тоже.)

С другой стороны, если природа изменения больше похожа на «Я хочу, чтобы это приложение для пчеловодства управляло платежной ведомостью моего конгломерата прачечной самообслуживания», никакое количество кода не вытащит вас из вашей дыры.

В шаблонах дизайна нет ничего хорошего. Они такие же инструменты, как и любые другие - мы используем их только для облегчения нашей работы в средне- и долгосрочной перспективе. Если другой инструмент (такой как коммуникация или исследование ) более полезен, тогда мы используем это.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.