Чи потрібно завжди писати об'єктно-орієнтований код, дотримуючись схему дизайну?


37

Чи можлива схема дизайну для будь-якої об'єктно-орієнтованої програми? Я запитую це тому, що нещодавно я побачив реалізацію Doorкласу з a Lock. Це було частиною тесту, у відповіді сказано, що код відповідає шаблону Null Object:

class Lock
{
public:
    virtual void close() = 0;
    virtual void open() = 0;
    virtual bool is_open() const = 0;
    virtual ~Lock() { }
};

class DummyLock
    : public Lock
{
private:
    DummyLock();
    DummyLock(const DummyLock&) = delete;
    DummyLock& operator=(const DummyLock&) = delete;

private:
    void close() { }
    void open() { }
    bool is_open() const { return true; }

public:
    static DummyLock m_instance;
};

class Door
{
public:
    Door() : m_lock(DummyLock::m_instance) { }
    Door(Lock &lock) : m_lock(lock) { }

public:
    Lock& get_lock() const { return m_lock; }

private:
    Lock &m_lock;
};

Це змусило мене задуматися: Цей код відповідає гарній схемі дизайну, хоча опис такий простий (цей клас проектує дверний клас із замком), тому, якщо я пишу більш складний код, чи повинен завжди бути якийсь шаблон дизайну, який я я стежу?



51
Як ви думаєте, ви могли повністю говорити в ідіомах? Ні? Тоді не слід створювати свої програми, обробляючи схеми дизайну.
Кіліан Фот

4
У вашому прикладі шаблон об’єкта Null додається лише в академічних цілях, він не вводить "хороший дизайн" в цей код.
Док Браун

4
@djechlin: іншими словами, використовуйте схему дизайну "два слова" :)
Майкл Шоу

11
Проблема полягає в тому, що занадто багато людей вважають, що дизайнерські зразки - це заміна думки та заміна досвіду (що передбачає певну кількість спроб та помилок). Ви не можете взяти книгу, повну дизайнерських моделей, і скласти їх, як Tinker Toys, щоб створити додаток з нетривіальним розміром і складністю та пристойною якістю. Навіть досвідченим програмістам часто потрібно спробувати два-три дизайни, перш ніж вони знайдуть той, який працює.
Даніель Р Хікс

Відповіді:


143

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

Шановний Боже НІ!

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

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

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


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

11
@Cerad: Звичайно, доки ти не обіцяєш також писати уроки Бога!
yatima2975

9
Джон Доу - інженер-
технік,

1
Можливо, дизайн повинен використовувати шаблони, де це доречно, і класи повинні бути названі такими. Вони є важливим інструментом. Боятися the_cult(тм) так само небезпечно.
Гусдор

25
Чудова відповідь! Моя одна критика полягає в тому, що "Шановний Боже НІ!" недостатньо великий
tobyink

37

Ні.

Про це сказала Банда четвірок (яка спочатку популяризувала дизайнерські зразки) у своїй книзі :

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

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

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


7
Книга - « Шаблони дизайну: Елементи багаторазового об’єктно-орієнтованого програмного забезпечення » Еріха Гамми, Річарда Хельма, Ральфа Джонсона та Джона Вліссайдса.
developerwjk

4
+1 Для фактичного цитування джерел моделей дизайну.
Фарап

29

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

Ні. Шаблони дизайну - це саме те: закономірності у відносинах між об'єктами. Іншими словами, стосунки, які використовуються та використовуються досить часто, що хтось сказав: "Ей, ми, здається, робимо це багато, давайте назвати це". Список моделей дизайну не був визначений відразу на початку OOP, а потім переданий GOF ! Вони були виявлені і врешті задокументовані, а потім популяризовані книгою.

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

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


10

Моделі дизайну мають дві переваги

  1. Їх легко описати іншим розробникам, тому що люди, як правило, погоджуються щодо того, що це за зразки
  2. Вони, як правило, були попередньо подумані нашими попередниками, тому їх сильні та слабкі сторони добре зрозуміли.

Цілі кожної програми повинні бути

  1. Це працює. Він повинен виконувати будь-яку кінцеву мету, або не має значення, скільки моделей дизайну ви використовуєте. OO-шаблони дизайну дозволяють легко розрізати проблему на легко зрозумілі біти, тому простіше довести, що вона працює.
  2. Це легко читати. Ось де шаблони дизайну приємні. Проблеми ОО, які вони вирішують, є складними. Якщо ви вирішите їх "стандартним" способом, простіше наступному розробнику
  3. Легко вирощувати. Майже 0 сучасних програм закінчують там, де кожен планував їх. Кожна програма зростає після її початкового випуску. Моделі ОО відомі тим, що цікаво хороші у вирощуванні.

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

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

Використовуйте дизайнерські зразки, коли вони покращують ваш продукт; уникайте їх, коли вони погіршать ваш продукт.


2
Я думаю, що останнє речення має бути вгорі жирним шрифтом або як короткий виклад.
Фарап

5

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

Нетривіальна програма без будь-яких моделей дизайну вказує на:

  • Ваша програма настільки унікальна, що жодна її частина не схожа на загальні проблеми, з якими стикалися програмісти раніше. Або
  • У вашій програмі є ті поширені проблеми, але ви вирішили їх кращим чином, про який раніше ніхто не думав.

Обидва сценарії вкрай малоймовірні, без образи.

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

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

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

Бачите різницю? Це тонка, але важлива відмінність.


5
Існує набагато більше поширених проблем (і їх загальних рішень), ніж є моделей дизайну. Шаблони дизайну - це каталогізований підмножина загальних OO-рішень, а не сукупність усіх загальних рішень.
Майкл Шоу

1
Чи можете ви визначити, що ви маєте на увазі під "нетривіальним", я мав враження, що термін "нетривіальний" є суб'єктивним.
Фарап

1
Це суб'єктивно. Я маю на увазі таку програму, яку ви писали б для команди в роботі, що вимагає постійного обслуговування декількох обслуговуючих служб.
Карл Білефельдт

Якщо вам пощастило побачити свою проблему після цього. Нульові чеки, звичайно. Уразливості безпеки? Іншими підступними способами програма прорветься при технічному обслуговуванні? Проблеми виявить лише наступний інженер? Набагато більше юкі.
djechlin

"Мені потрібно моделювати двері та замок. Яким повинен бути інтерфейс? Чи буде виконання частиною договору? Чи потрібно використовувати послугу чи бібліотеку? Як передаватимуться ресурси?" всіх слід запитати, і ви повинні мати відповіді, які в основному розглядаються як шаблони дизайну.
djechlin

4

Зламане питання. Дозвольте дати вам нове визначення шаблону дизайну, який би скасував велику шкоду, випущену GoF: модель дизайну є хорошою практикою кодування . Це воно.

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

"Шаблон дизайну" - це ламаний термін, який погано популяризується GoF, і це звучить так, ніби всі зразки знаходяться на одному рівні або вам слід використовувати лікаря, рекомендованого від 3 до 5 в класі. Кожен раз, коли ви робите щось правильно, що хтось інший зробив правильно, це модель дизайну . A for(;;)- це звичайний зразок, який використовується, наприклад, для зображення нескінченного циклу.

Не варто намагатися вивчити купу моделей дизайну. Знання програмування не індексуються моделями дизайну! Швидше вам слід навчитися писати хороший код , читаючи книги, блоги та відвідуючи конференції у вашій галузі. Наприклад, якщо ви вже використовуєте ін'єкцію залежностей, але просто не позначили її, вам може бути корисно завжди використовувати DI або використовувати IoC-фреймворк. Або якщо ви намагаєтеся кодувати прямо в подіях і зворотних дзвінках, перейдіть, вивчіть Haskell, щоб ви ознайомилися з функціональними моделями дизайну, і вам стане легко.

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


2
Якою мовою for(;;)ідіоматично? Це, мабуть, не найкращий приклад того, що хтось зробив «правильно».
Теластин

1
@Telastyn C, C ++, Java, Javascript, C #.
djechlin

2
Я ніколи не бачив, щоб хтось віддав перевагу над while(true)(або while(1)) в C, C ++, Java або C # за мої 20+ років програмування.
Теластин

1
@Telastyn stackoverflow.com/a/2611744/1339987 FWIW Я почав віддають перевагу поки (правда) , тому що він виглядає більш читабельним для мене.
djechlin

1
Я завжди використовую для (;;). Ніякої конкретної причини, я, мабуть, читав її десь. Мені подобається те, що змінних чи констант не задіяно. У будь-якому випадку, @Telastyn зараз ти когось зустрів .
Мураха

0

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

Візерунки - це рішення загальних проблем дизайну. Ці проблеми виникають з одного з двох місць (або поєднання обох): проблемного простору (наприклад, програмного забезпечення для управління людськими ресурсами в компанії) та простору рішення . Програми ОО - це екземпляр у просторі рішення (наприклад, один із багатьох способів ви могли розробити програму ОО для полегшення управління персоналом).

Не так просто дізнатися, коли використовувати візерунок. Деякі зразки є низькорівневими, ближчими до кодування та простору рішення (наприклад, Singleton, Null object, Iterator). Інші мотивуються вимогами в проблемному просторі (наприклад, шаблон команди для підтримки скасування / повторення, стратегія підтримки декількох типів файлів вводу / виводу).

Багато моделей випливає з необхідності підтримувати варіанти програмного забезпечення в майбутньому. Якщо вам ніколи не потрібно робити ці варіанти, візерунок може бути надмірним дизайном. Прикладом може бути використання моделі Адаптер для роботи з існуючою зовнішньою базою даних HR. Ви вирішили застосувати адаптер, оскільки поточна база даних працює з Oracle, і ви, можливо, захочете підтримати NoSQL в майбутньому. Якщо NoSQL ніколи не приходить до вашої організації, цей код адаптера цілком може бути марним. Дивіться YAGNI . Підтримка варіантів, які ніколи не зловживають, зловживає дизайнерським малюнком.


0

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

Однак, моя відповідь - ні, але так, ви завжди дотримуєтесь своєї власної моделі. Як справедливо стверджує Держфінпослуг,

Візерунок однієї людини - це примітивний будівельний блок іншої людини.

Чудова цитата.


це , здається, не пропонує нічого істотного по точкам зроблених і роз'яснено в попередніх 7 відповідей
комар

Чудово. Зауважте, я зробив загальний пункт ... це застосовно до моделей дизайну як теоретичної дискусії.
Сиєд Приома

"На цьому веб-сайті ви знайдете відповіді . Це не дискусійний форум ..." ( тур )
gnat

Я відповів на питання. Дякую. На цьому розмова закінчується.
Сиєд Приома

@gnat це чорт набагато більш лаконічний.
djechlin

0

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

Ось стаття про застосування принципів OOD, використовуючи шаблони дизайну, і в ній є приклади коду (на C ++). Він показує, як і коли слід застосовувати деякі схеми дизайну для написання чистого коду.


2
Ця стаття була написана лише вчора; Ви взагалі пов’язані з блогом? Якщо так, будь ласка, розкрийте цю приналежність .
Martijn Pieters
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.