Подтвердить что ты не робот

Неправильные шаблоны проектирования

Есть ли в каноническом Gang of Four список любых шаблонов дизайна, которые вы часто считаете неправильно используемыми, неправильно понимаемыми или чрезмерными (за исключением сильно обсуждаемого Singleton)? Другими словами, есть ли шаблон дизайна, который вы бы посоветовали дважды подумать перед использованием? (И почему?)

4b9b3361

Ответ 1

Синтаксический шаблон.. глобальное состояние часто приводит к проблемам при тестировании

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

Ответ 2

Factory Шаблоны...

Я был парашютирован в проект до того, как каждый MyObject в системе имел эквивалент MyObjectFactory для генерации новых экземпляров. Не было понятия абстракции или расширенных классов... просто старые классы ClassX и ClassXFactory.

И никто не мог объяснить, почему... "Это было так, как всегда делалось"

Ответ 3

Единственный (помимо вышеупомянутого Синглтона и его партнера в преступлении, Factory) не будет GoF, он будет сеттерами и геттерами при применении к собственным свойствам объекта.

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

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

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

Есть несколько исключений, о которых я могу думать:

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

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

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

Объекты DAO/DTO Bean. Честно говоря, я считаю, что это неправильное использование шаблона, но это шаблон. Это делает манипуляции с свойствами метаданных вместо кода намного сложнее, чем должно быть, поскольку оно должно быть рефлексивным. Свойства Beans всегда привязаны к некоторому внешнему источнику (формат базы данных, формат передачи данных, свойства компонента,...), так почему мы дублируем работу по определению каждой части?

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

Краткая версия -

if (account1.balance > 1000)
{
    account1.balance = account1.balance - 1000;
    account2.balance = account2.balance + 1000;
}; = BAD CODE. 

account2.deposit(account1.withdraw(1000)); = GOOD CODE. 

Второй не требует доступа к аксессуарам... - кёрю (Немного изменено счетом к, потому что у меня есть немного больше места, чем в его комментарии).

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

Просто для того, чтобы взвесить точку EVEN MORE, обратите внимание, что в стиле "GOOD CODE" довольно очевидно, что вывод .withdraw может быть объектом транзакции, который содержит информацию обо всей транзакции, включая ее успех, источник и назначение и протоколирование способность. Как это могло произойти с тем, кто пишет свой код в стиле "BAD CODE"?

Также как бы вы реорганизовали BAD CODE, чтобы даже использовать такой объект? Это просто беспорядок.

Ответ 4

Собственно, то, что я вижу чаще всего, - это отсутствие использования подходящего шаблона. Типичный сценарий: me: "Привет, модуль A уже имеет кусок кода, который проходит через набор объектов и выполняет операцию с ними на базе X, почему вы не использовали этот код повторно?" кодер: "ну, но я должен был выполнить операцию Y на этих объектах". me: "как насчет использования рефакторинга для использования шаблона Command для выполнения X или Y в зависимости от ситуации?"

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

Ответ 5

Я бы также сказал шаблон factory. Подобный опыт, как Эоин. В моем случае у проекта было множество фабрик, потому что некоторые люди думали, что вы использовали объект A для локальной реализации и объекта B для удаленных, и он был абстрагирован с помощью factory (что разумно делать).

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

Ответ 6

ALL.

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

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

Ответ 7

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

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

Только мои 0,02.

веселит,

Rob

Ответ 8

На самом деле, я бы сказал, что шаблоны проектирования в целом чрезмерно используются, когда требуется только решение KISS ( Keep It Simple, Stupid Keep it Short and Simple)).

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

Ответ 9

Шаблон медиатора определенно может быть использован неправильно, если все виды логики попадают в один огромный класс.

Ответ 10

Шаблон наблюдателя довольно бесполезен в С#, поскольку он имеет события.

Ответ 11

Я просто хотел добавить еще один комментарий, увидев некоторые ответы "Все шаблоны плохие".

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

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

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

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

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

Ответ 12

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

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

Ответ 13

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

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

Ответ 14

REPOSITORY PATTERN

Большинство людей начинают использовать этот шаблон сразу после прочтения книги по дизайну домена Driven Eric Evans.

Сколько людей здесь видели репозитории, созданные как объекты доступа к данным?

Ответ 15

У вас нет прямого ответа на этот вопрос. Это в основном субъективно и зависит от требований приложения.

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

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

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