Какие шаблоны дизайна являются наихудшими или наиболее узкими? [закрыто]


28

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

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

Какие шаблоны дизайна вы использовали, что отбросило вас назад в целом? Какие наихудшие шаблоны проектирования следует рассмотреть, за исключением одной ситуации, в которой они имеют смысл (читай: какие шаблоны проектирования определены очень узко)? (Как будто я искал негативные отзывы об общем хорошем продукте Amazon, чтобы понять, что больше всего мешает людям при использовании шаблонов дизайна.) И здесь я говорю не об анти-шаблонах, а о шаблонах, которые обычно рассматриваются как «хорошие» шаблоны.

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


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

Все из них в книге «Банды четырех».
Майлз Рут

Ответы:


40

Я не верю в плохие паттерны, я верю, что паттерны могут быть плохо применены!

  • ИМХО, синглтон является наиболее злоупотребляемым и наиболее неправильно применяемым паттерном. Люди, кажется, заболевают синглтоном и начинают видеть возможности для синглетонов повсюду, не рассматривая альтернативы.
  • ИМХО шаблон посетителя имеет самое узкое применение и почти никогда не будет оправдывать добавленную сложность. Хороший PDF можно получить здесь . Действительно, только когда у вас есть структура данных, которую, как вы знаете, будет проходить при выполнении различных операций над структурой данных, не зная заранее всех способов, дайте паттерну посетителя шанс для борьбы. Это красиво, хотя :)

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


Я вижу очень мало применений для посетителей. Одиночки ... не заводи меня. Если ситуация не идеальна, не используйте ее.
Майкл К

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

12
Шаблон Visitor имеет решающее значение для уменьшения (или устранения) цикломатической сложности в программном обеспечении. Каждый раз, когда у вас есть дерево if / else или оператор switch, высоки шансы, что посетитель сможет их заменить, предлагая гарантированное выполнение и проверку во время компиляции. «Посетитель» - один из самых мощных шаблонов, которые я знаю, и мы регулярно используем его с большим эффектом. Это также делает испытание мечтой.
Les Hazlewood

@LesHazlewood Разве тогда Visitor - это только обходной путь для неадекватных языков программирования? Подобные ML языки (Haskell, SML, OCaml и т. Д.) Имеют алгебраические типы данных («объединение на стероидах») и сопоставление с образцом («переключение на стероидах»), которые производят более простой код, чем Visitor, но полностью проверяются компилятором. По сравнению с посетителем, у вас не так много методов, состоянием которых вы должны управлять вручную через свойства объекта. В ML-подобных языках все различия в регистре должны быть полными, иначе он не скомпилируется.
ВОГ

14

Кроме Синглтона и Посетителя, уже упомянутых другими авторами, я не знаю «пресловутых» шаблонов дизайна. ИМХО, самые большие проблемы не в том, что конкретный шаблон дизайна является «неправильным», а в том, что разработчики слишком охотно применяют шаблоны.

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

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


Абсолютно. Шаблоны не являются ни хорошими, ни злыми, они хорошо применяются или неправильно применяются.

Я бы лучше научил людей тому, как я учился: сначала ОО, понимая, как соотносятся объекты, а затем изучая названия паттернов. Это слишком легко думать с точки зрения шаблонов, чем то, что нужно сделать. Они являются средством коммуникации.
Майкл К

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

14

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

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


10

Singleton. Это один из паттернов GOF, который сейчас чаще называют анти-паттерном. Одна из причин этого заключается в том, что Singleton делает код более сложным для тестирования.


4
В синглтон-паттерне есть множество фундаментальных недостатков, большинство из которых хорошо иллюстрированы в этой статье Стива Йегге - Синглтон считается глупым
ocodo

Сломохо: Хорошая статья. С этого момента я буду называть это «простой шаблон»:-)
Никто

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

Почему все связывают обычную (и хлопотную) реализацию Singleton с шаблоном Singleton? Одно почти всегда плохо, другое нет.
Квентин-старин

1
@qes> Singleton ставит важные проблемы реализации (особенно с многопоточностью). Это уже плохой момент. Но вы также узнаете, что синглтон - это образец того, как подан иск на класс, а не как он работает. То, как используется класс, должно обрабатываться кодом, использующим класс, поэтому Singleton - это разрыв разделения интересов.
Deadalnix

7

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

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

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

Доктор WPF сделал ироничный пост об этом в своей статье MV-poo .


@Akku: Конечно, вы должны знать, как его использовать, чтобы вы могли решить, подходит ли он для вашего проекта. Так что да, это важно для разработки WPF и очень полезно.
Стивен Джеурис

Одна из проблем заключается в том, что люди неправильно понимают модель MVVM. Это не "сложно, как в аду". Люди делают это таким образом, думая, что все другие паттерны, такие как паттерн командования и паттерн посредника, являются его частью. Сам по себе MVVM, на мой взгляд, является одним из самых простых шаблонов. Я согласен, что просто следовать глупостям.
БК

5

Некоторые шаблоны в книге GOF специфичны для C ++, в том смысле, что они менее применимы в языках с отражением, например, шаблон Prototype менее важен в Java.

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


1
большая часть GOF применима только к ООП на основе статических классов. немного отклониться от такого рода языков, и книга станет просто развлекательным анекдотом.
Хавьер

5

Тот, о котором я сожалею чаще всего (хотя и не очень сильно): когда я должен был просто создать функцию, но я реализовал решение ООП.


1
Зачем? Что заставило вас сожалеть об этом? Пожалуйста, расширьте свой ответ и добавьте свой опыт.
Уолтер

В самом деле, я думаю, что класс с локальными переменными и методами очистки НАМНОГО проще использовать повторно, чем одну 200-строчную функцию, которая может быть повторно применена только посредством копирования, и тогда не будет только одного места, чтобы выглядеть уродливым и непонятным.
Акку

2
KISS подразумевает, что вы сначала сделаете его функцией, а затем при необходимости выполните рефакторинг в класс.
Ева

5

Завод. Я видел код, реализующий его, который создает только один тип. Это совершенно бесполезный код ИМО. Не помогает то, что многие примеры в Интернете полностью придуманы. Пиццерия?

Возможно, фабрику проще тестировать из-за внедрения зависимости. Но добавлять этот код, когда он вам не нужен, бессмысленно для меня, и аргумент теста исчезает, когда вы можете использовать фиктивные фреймворки, такие как JMockit. Чем проще вы можете сделать программу, тем лучше. Фабрики действительно имеют смысл только с большим количеством типов (под более крупным я имею в виду, по крайней мере, больше 2).


Да, фабрика по производству пиццы, спасибо за «Head First Design Pattern» ~
Niing

2

одиночка

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

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

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

посетитель

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

Можно, хотя и грязно, разрешить расширение в обоих направлениях, но это не полностью использует шаблон посетителя в его обычной форме. Самым распространенным приложением для этого является печать объектов: у вас есть разные способы печати объектов и различных объектов, которые необходимо распечатать. Вы должны быть в состоянии расширить это в обоих направлениях. (Печать означает любой вид превращения объектов в поток: сохранение в файле / запись в консоль / графический интерфейс пользователя и т. Д.).

(Примечание: вы не должны путать это с архитектурой представления документов, которая немного отличается).


2
Ваше решение использует старый аргумент. В частности, вы публикуете событие, а какой-то другой парень обрабатывает событие и регистрирует его. Это хорошо, потому что все отделены друг от друга! НЕПРАВИЛЬНО! Раньше я делал это, какая это была королевская боль. Я понял, что если я хочу, чтобы что-то было зарегистрировано, я хочу явно сказать, записывать именно эту вещь, прямо здесь, прямо сейчас, в коде в тот момент, когда это произошло. Не заставляйте некоторый другой объект выяснить, что должно быть зарегистрировано, с возможными другими событиями, вставленными другими обработчиками, если это вообще зарегистрировано. Это не что иное, как замысловатый дизайн.
Данк

2

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

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


Я также считаю, что MVC следует использовать везде, но не везде применять одинаково. И многие люди этого не понимают. Когда я впервые захотел его использовать, я создал три класса: Model, View (форма Windows) и Controller. Это был беспорядок, так как формы не были сделаны для MVC.
Акку

1

Нет плохих шаблонов, только плохие люди.

Я бы предпочел унаследовать легко читаемый код, который делает что-то ясное, но немного многословно или нет (повторяю злобную музыку), может быть повторно использован (задыхается!), Чем какая-то миш-мес InheritAbstractTemplateFaucetSink<Kitchen>.

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

Для дальнейшего чтения взломайте, откройте часть кода на C в разумных реализациях заголовков posix или clibs и играйте в паттерн. Этот код был написан одними из самых умных и самых преданных программистов в мире. Вы знаете, сколько абстрактных фабричных шаблонов вы увидите? ... НИКТО!. Еще больше шансов, что если вы поймете другие части происходящего, вы найдете логику очень простой для понимания и отслеживания.

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

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

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

  • Тони Хоар (изобретатель быстрой сортировки, отец современного дизайна ОС, создатель логики Хоара и лауреат премии Тьюринга)

0

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

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