Які шаблони дизайну є найгіршими або вузько визначеними? [зачинено]


28

Для кожного проекту програмування менеджери з минулим досвідом програмування намагаються сяяти, коли рекомендують певні шаблони дизайну для вашого проекту. Мені подобаються шаблони дизайну, коли вони мають сенс або якщо вам потрібно масштабоване рішення. Наприклад, я використовував схеми проксі, спостерігачів і команд позитивно, і роблю це щодня. Але я дуже вагаюсь, щоб сказати, що є "Фабрична схема", якщо існує лише один спосіб створити об'єкт, оскільки фабрика може полегшити це в майбутньому, але ускладнює код і є чистою накладною витратою.

Отже, моє запитання стосується моєї майбутньої кар’єри та моєї відповіді щодо типів менеджера, які кидають випадкові назви шаблонів:

Які дизайнерські зразки ви використовували, які відкинули вас в цілому? Які найгірші схеми дизайну , ті, які слід розглянути, за винятком однієї єдиної ситуації, коли вони мають сенс (читайте: які шаблони дизайну дуже вузько визначені)? (Це схоже на те, що я шукав негативні відгуки про загальний хороший продукт Amazon, щоб побачити, що найбільше клопоче людей у ​​використанні дизайнерських моделей.) І я не говорю тут про анти-патерни, а про патерни, про які зазвичай думають як "хороші" зразки.

Редагувати: Як відповіли деякі, найчастіше проблема полягає в тому, що шаблони не "погані", а "неправильно використовуються". Якщо ви знаєте зразки, які часто неправомірно використовуються або навіть є складними у використанні, вони також підійдуть як відповідь.


Більшість моделей спрощують майбутні зміни на деяких осях змін, але вони можуть зробити більш важкими зміни на інших осях змін. Банда з чотирьох книг особливо добре говорить, коли застосовується візерунок. Багато наступних книг про зразки пропускають цю точку зору. Візьмемо для прикладу шаблон відвідувачів. Це полегшує додавання нових алгоритмів обходу дерев, але ускладнює додавання до дерева нових видів вузлів. Це також дозволяє алгоритмам переходу знаходитись у більш високому шарі, ніж дерево. Потрібно врахувати, яка вісь змін є найменш стійкою, і спроектувати, щоб легко змінити її.
Теодор Норвелл

Всі з них у книзі "Банда чотирьох".
Майлз Рут

Відповіді:


40

Я не вірю в погані зразки, я вважаю, що шаблони можуть бути погано застосовані!

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

Для цієї відповіді я розглядав лише схеми ГОФ. Я не знаю всіх можливих зразків досить добре, щоб їх також врахувати.


Я бачу дуже мало використання для відвідувачів. Сінглтон ... не запускайте мене. Якщо ситуація для вас не ідеальна, не використовуйте її.
Майкл К

1
Користувачів для відвідувачів може бути дуже мало, але коли він є, він, безумовно, вирішує проблеми. Я розумію, що Vistor має важливе значення для LINQ.
квентин-зірин

12
Шаблон відвідувачів має вирішальне значення для зменшення (або усунення) цикломатичної складності програмної програми. Кожен раз, коли у вас є дерево if / else або оператор переключення, шанси високі, що відвідувач може замінити їх, пропонуючи гарантоване виконання та перевірку часу компіляції. Відвідувач - одна з найпотужніших моделей, про які я знаю, і ми регулярно користуємось нею з великим ефектом. Це робить тестування і сном.
Les Hazlewood

@LesHazlewood Чи не тоді для відвідувачів лише вирішення невідповідних мов програмування? Мови, подібні до ML (Haskell, SML, OCaml тощо), містять алгебраїчні типи даних ("об'єднання на стероїди") та відповідність шаблонів ("перемикання на стероїди"), які створюють простіший код, ніж Visitor, але повністю перевірений компілятором. У порівнянні з відвідувачем, у вас не так багато методів, статусом обміну якими потрібно керувати вручну за допомогою властивостей об'єкта. У мовах, подібних до ML, і всі відмінності у випадку мають бути повними, інакше вони не збираються.
vog

14

Крім Singleton та Visitor, про які вже говорили інші відповіді, я не знаю про "горезвісні" моделі дизайну. Найбільші проблеми IMHO випливають не з того, що конкретна модель дизайну є "неправильною", а скоріше від розробників, які занадто охоче застосовують шаблони.

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

Врешті-решт, більшість із нас переживає цю фазу і починає вчитися використовувати шаблони для вирішення реальних проблем, а не заради себе. Шаблони мають свою ціну, що є додатковою складністю, і застосування будь-якої конкретної моделі виправдане лише тоді, коли вона окупиться за додаткову складність, допомагаючи спростити деяку іншу частину системи, тим самим полегшивши розуміння та підтримку коду / конфігурації. Якщо це не так, часто краще триматися осторонь, дотримуючись найпростішого рішення, яке могло б працювати.


Абсолютно. Візерунки не є ні добрими, ні злими, вони добре застосовуються або неправильно застосовуються.

Я вважаю за краще навчати людей так, як я навчився: OO спочатку, розуміючи, як об'єкт співвідноситься, а потім вивчити назви шаблонів. Думати легко з точки зору моделей, ніж те, що потрібно зробити. Вони є засобом зв’язку.
Майкл К

Візерунки - це засіб спілкування, а не перелік приписів. Якщо ви почнете з малюнка на увазі, ви можете неправильно його застосувати. Якщо ви знайдете його чи підказки у своєму дизайні, то каталоги шаблонів можуть допомогти вам зрозуміти, що ще може знадобитися.
Роб Кроуфорд

14

Я збираюся тут вийти на кінцівку і запропонувати надмірне використання спадщини. Безумовно, найбільш застосовна в мовах без міцної поліморфізми під час компіляції, як Java. Успадкування під час виконання - це інструмент, а не якась дивна особливість.

Інші люди вже висловлювали схожу на мою особисту ненависть до Сінглтона, тому я тут не збираюся розширювати це питання.


10

Сінглтон. Це на основі шаблонів GOF, які тепер частіше називають антидіаграмою. Однією з причин цього є те, що Singleton ускладнює тестування коду.


4
У одинарному малюнку є численні основні недоліки, більшість добре проілюстровані в цій статті Стівом Йегге - Singleton вважається дурним
ocodo

Slomojo: Приємна стаття. Я буду називати це "простим малюнком" відтепер:-)
ніхто

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

Чому всі асоціюють загальну (і клопітку) реалізацію Singleton з візерунком Singleton? Один майже завжди поганий, інший - ні.
квентин-зірин

1
@qes> Singleton ставить важливі проблеми з впровадженням (особливо з нанизуванням). Це вже є поганим моментом. Але ви також дізнаєтесь, що синглтон є зразком про те, як подається позов до класу, а не як він працює. Як використовується клас, слід обробляти код за допомогою класу, тому Singleton - це розрив розділення проблем.
deadalnix

7

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

Дотримуючись схеми MVVM для WPF занадто суворо, як це зазначено, наприклад , цим питанням . Деякі люди намагаються дотримуватися настанови про те, що жоден код не слід занадто суворо вводити в код і придумувати всілякі екзотичні хаки.

І звичайно, MVVM важко як пекло, і це просто не варто для невеликих короткострокових проектів.

Доктор WPF зробив іронічну публікацію про це у своїй статті MV-poo .


@Akku: Ви, звичайно, повинні знати, як ним користуватися, щоб ви могли вирішити, чи підходить він для вашого проекту. Так що так, це важливо для розвитку WPF, і дуже корисно.
Стівен Євріс

Одне з питань полягає в тому, що люди неправильно розуміють схему MVVM. Це не так складно, як чорт. Люди роблять це таким чином, думаючи, що всі інші зразки, такі як командний зразок та модель посередника, є його частиною. MVVM сама по собі є однією з найпростіших моделей, на мою думку. Я погоджуюсь, що слідувати що-небудь до Т просто глупо.
BK

5

Деякі з моделей у книзі GOF мають специфіку C ++, в тому сенсі вони менш застосовні для мов з відображенням, наприклад, шаблон прототипу є менш значущим для Java.

Я розглядаю модель Інтерпретатора як "вузьку". Ви повинні мати загальну проблему, яку варто розробити для вирішення загальної проблеми. Це працює лише для особливих проблем, для яких можна вигадати мову, визначити граматику та написати перекладача. Проблемні екземпляри повинні бути представлені як речення у граматиці. Я не думаю, що ти часто стикаєшся з такими ситуаціями.


1
Більшість GOF застосовується лише до OOP на основі статичного класу. злегка відхиляється від подібних мов, і книга стає просто розважальним анекдотом.
Хав'єр

5

Я часто шкодую (хоча і не дуже жорстоко): Коли я повинен був просто створити функцію, але я застосував рішення OOP.


1
Чому? Що змусило вас пошкодувати? Розгорніть свою відповідь та додайте досвід.
Вальтер

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

2
KISS має на увазі, що ви перетворите його на функцію, а потім, якщо потрібно, рефактор на клас.
Єва

5

Заводська. Я бачив, як реалізується код, який створює лише один тип. Це абсолютно марний код ІМО. Не допомагає, що багато прикладів в Інтернеті повністю надумані. Фабрика піци?

Можливо, фабрику простіше перевірити через введення залежності. Але додавати цей код, коли він вам не знадобиться, для мене безглуздо, і тестовий аргумент зникає, коли ви можете використовувати макетні структури, такі як JMockit. Чим простіше ви можете зробити програму, тим краще. Фабрики справді мають сенс лише для більшої кількості видів (маючи на увазі, принаймні, більше ніж 2).


Так, фабрика піци, дякую за головний дизайн шаблону ~
Niing

2

Сінглтон

Я погоджуюся з іншими щодо Сінглтона. Не те, що ви ніколи не повинні їх використовувати, лише це має бути обмежено дуже мало випадків. Вони багато часу використовуються як ліниві глобали.

Безпека ниток - це одна проблема з однотонними кнопками. Інша обробка винятків - якщо сингл не вдається створити належним чином - ви не завжди знаєте, чи зможете ви спокійно зафіксувати помилку, особливо якщо це був один із тих об'єктів, створених "до основного". І тоді виникає питання прибирання після цього.

Я, як правило, вважаю за краще використовувати один сингтон, а всі інші синтаксиси "хочу" підписатися на ваш. Моє найпоширеніше використання в одиночному режимі - це обробка "кричати події": ви просто "транслюєте у світ", що відбулася подія, і кожен, хто слухає, хто буде керувати подією, робить це. Таким чином ви розв'язуєте події, що насправді відбуваються, з тим, що їх слухає. (Ведення журналів, сигнали тощо)

Відвідувач

Неприємне, що я знаходжу з цього приводу, крім того, що розробники не можуть придумати значущі імена та просто методи виклику visit (), це те, що вона додає розширюваність в одному напрямку, видаляючи її в інший, тобто додає додаткову функціональність, але обмежує кількість об’єктів, скільки відвідувачі повинні знати про всі типи об'єктів, які він може відвідувати.

Можна, хоч і безладно, дозволити розширення в обох напрямках, але це не повністю використовує шаблон відвідувачів у його регулярній формі. Найбільш поширене застосування для цього - це об'єкти друку: у вас є різні способи друку об'єктів та різних об'єктів, які потрібно надрукувати. Ви повинні мати можливість розширити це в обох напрямках. (Друк означає будь-який вид перетворення об'єктів у потік: зберігання у файлі / запис у консоль / GUI .. тощо).

(Примітка: не слід плутати це з архітектурою перегляду документів, що є трохи іншим шаблоном).


2
У вашому рішенні використовується старий аргумент, який розв'язує речі. Зокрема, ви публікуєте подію, а хтось інший хлопець обробляє подію та записує її в журнал. Це гарна річ, адже всі роз’єднані! НЕ ПРАВО! Я колись робив це, яким королівським болем це стало. Я зрозумів, що якщо я хочу щось зареєструвати, я хочу прямо сказати, записувати цю точну річ, прямо тут, прямо зараз, у коді в той момент, коли це сталося. Не майте іншого об'єкта з'ясовувати, що слід реєструвати, з можливими іншими подіями, що втручаються іншими обробниками, якщо він взагалі записаний. Це не що інше, як викрите переоформлення.
Данк

2

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

Найгірший злочинець, про який я можу подумати в цій категорії, - це модель MVC. Навіть якщо ми ігноруємо MVP, існує стільки варіацій ролей кожного з цих предметів, що вам доведеться провести годину в кожному новому рамках, з'ясовуючи, де лежать кордони.


Я також вважаю, що MVC слід використовувати всюди, але не впроваджувати всюди однаково. І багато людей цього не розуміють. Коли я вперше захотів ним скористатися, я склав три класи під назвою Model, View (форма Windows) та Controller. Це було безладдя, оскільки форми для MVC не складалися.
Акку

1

Немає поганих зразків, тільки погані люди.

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

Код для повторного використання - це чудово! Цілком ймовірно, що ви не пишете код, який буде повторно використаний або повторна запис подібної логіки для іншого додатка зайнять у вас менше часу, ніж якась божевільна спроба повторного використання коду іншої програми.

Для подальшого читання тріщини відкрийте частину коду С у розумних реалізаціях заголовків posix або кліпів та відтворіть місце шаблону. Цей код написали одні з найрозумніших і найбільш відданих програмістів у світі. Чи знаєте ви, скільки абстрактних заводських шаблонів ви збираєтесь бачити? ... НІКОЛИ !. Ще кращі шанси на те, що якщо ви зрозумієте інші частини того, що відбувається, ви знайдете логіку дуже легко зрозуміти та простежити.

Думаю, що більшість "шаблонів" не були створені для покращення коду, вони були створені для продажу книг та програмного забезпечення для моделювання. Якщо ви добре займаєтесь програмуванням, ви, ймовірно, ухиляєтесь від більшості з них і пишете чіткий, стислий та грамотно розроблений код, який вирішує вашу проблему. Якщо у вас є інша проблема, ви напишете чіткий, стислий, вміло розроблений код для вирішення цієї проблеми. Якщо ваша мета - написати менше коду, ніж я б подумав, ваш не вирізаний програмістом. Я люблю писати код і хочу його написати якомога більше. Коли я переписую щось, про що я вже писав, я роблю це в десятки разів швидше і позбуваюся позбутися всіх речей, якими я не був задоволений уперше.

З цим я залишу вас, мабуть, найкращою (відповідною) цитатою з інформатики.

" Існує два способи побудови дизайну програмного забезпечення. Один із способів - зробити його таким простим, що явно немає недоліків, а інший спосіб - зробити його таким складним, що явних недоліків немає. Перший спосіб набагато складніше . "

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

0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.