Скільки зусиль потрібно вкласти у створення нещільно зв'язаних конструкцій?


10

В даний час я дізнаюся про схеми дизайну.

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

Маючи це на увазі:

Книга, яку я читаю (Head First Pattern Patterns), часто підкреслює важливість нещільного зв'язку . Це розв'язане з'єднання здійснюється за допомогою таких принципів, як "програма на інтерфейс, а не реалізація" та "інкапсуляція того, що залежить".

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

Я розумію важливість і переваги сипучих з’єднань.

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

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

Що я хотів би знати, - скільки зусиль я повинен докласти, щоб створити додаткові рівні абстрагування та дизайну, лише щоб дозволити моїй програмі слідувати принципам OO, таким як вільне з'єднання, програмування на інтерфейс тощо. Чи справді це варто? це? Скільки зусиль я повинен докласти до цього?


Деякі люди вкладають це все життя, наприклад, Кент Бек, люди, які цінують це, побачили б ваше старання.
Нінг

Відповіді:


14

Невпинна відповідь: чим більше ти робиш, тим менше зусиль.

В основному, побудувати слабо зв'язаний код не дуже важко. З іншого боку, навчити свій розум мислити з точки зору слабкої зв'язку. І, ну, я вважаю, це цілком того варте того.

Припустимо, ви приймаєте роботу, яка використовує ітеративний підхід до розробки програмного забезпечення, як це рекомендували більшість всіх за останні 20 років. Ви створюєте щось, що прекрасно працює в ітерації 1. В ітерації 2 ви будуєте поверх цього, додаючи нові функції та трохи згинаючи одну чи дві речі, коли вони не вписуються у вашу концепцію ітерації 1, як все має працювати. . Тепер приходить ітерація 3, і ви дізнаєтесь, які вимоги вимагають переосмислити базову архітектуру. Як ви розірвіть свій код і відновите його, не повертаючись до прямого?

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

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


5

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

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

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

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

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

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

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


4

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

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

Сам OO в основному є моделлю для створення слабко з'єднаних компонентів. Інкапсуляція робить внутрішню частину об'єктів вільно поєднаною з іншими об'єктами. Функціональне програмування може бути навіть тим більше, оскільки виконання функції слабко поєднується з виконанням інших функцій в крайньому випадку.

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

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


3

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

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

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

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

Серед правил (не вичерпний перелік):

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

Ці правила дотримуються по-різному, залежно від мови, методології розробки, яку дотримується ваша команда (наприклад, TDD), часових обмежень бюджету тощо.

Наприклад, у Java є хорошою практикою визначати свій інтерфейс як interfaceта записувати клієнтський код на цьому (тоді інстанціювати інтерфейс класом реалізації).

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

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

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

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

Що я хотів би знати, - скільки зусиль я повинен докласти, щоб створити додаткові рівні абстрагування та дизайну, лише щоб дозволити моїй програмі слідувати принципам OO, таким як вільне з'єднання, програмування на інтерфейс тощо. Чи справді це варто? це? Скільки зусиль я повинен докласти до цього?

Ваші запитання роблять (нестандартним) припущення, що єдиною перевагою нещільного з’єднання є можливість легко впроваджувати дизайнерські шаблони. Це не так.

Серед переваг сипучої муфти:

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

... і кілька інших, які зараз не приходять мені в голову.

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