1. Знайомство з патернами

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

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

Важливо! В українській мові під словом дизайн зазвичай мають на увазі графічний дизайн, в англійській це не так. Англійське слово design за змістом ближче до слова “проєктування” та/або “влаштування”. Наприклад, дизайн двигуна — це не стільки його зовнішній вигляд, як внутрішнє влаштування.

Тому design pattern – це саме патерн/шаблон проєктування. Рекомендую взагалі перестати вживати слово дизайн у сенсі "зовнішній вигляд". Ти – майбутній Software Engineer, і для тебе дизайн – це саме проєктування.

То що таке цей design pattern? Насамперед патерн проєктування – це стандартне вирішення стандартної проблеми. Хороше, ефективне та перевірене часом рішення.

Припустимо, тобі сказала спроєктувати велосипед. Ти можеш зробити йому два колеса, три чи навіть п'ять. Так, до речі, на зорі проєктування й було. Але перевірений часом підхід – два колеса. Адже до нинішнього очевидного підходу дійшли через біль та помилки:

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

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

2. Історія появи патернів проєктування

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

Для організації роботи великої групи людей використовували практики та підходи зі сфери будівництва. До речі, саме звідти до програмування прийшли такі терміни як складання (build), Software Developer (будівельник) та поняття архітектури.

І, як ти вже здогадуєшся, ідею design pattern теж взяли зі сфери будівництва. Концепцію патернів вперше описав Крістофер Александер у книзі “Мова шаблонів. Міста. Будинки. Будівництво”. У цій книзі для опису процесів проєктування міст використано спеціальну мову – патерни.

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

Тому нема нічого дивного в тому, що 1994 року вийшла книга “Прийоми об'єктно-орієнтованого проєктування. Паттерни проєктування”, до якої увійшли 23 патерни, що вирішують різні проблеми об'єктно-орієнтованого дизайну.

Книгу написали 4 автори: Еріх Гамма, Річард Хелм, Ральф Джонсон та Джон Вліссідес. Назва книги була занадто довгою, щоб хтось зміг її запам'ятати. Тому невдовзі всі почали називати її "book by the gang of four", тобто "книга від банди чотирьох", а потім взагалі – "GoF book".

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

Важливо! Патерни – це не якісь супероригінальні рішення, а навпаки – типові рішення тої ж самої проблеми, що часто зустрічається.

3. Список патернів

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

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

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

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

Які бувають патерни?

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

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

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

Але головне – патерни мають призначення. Патерни, з якими ми познайомимося, можна розбити на три основні групи:

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

4. Знайомство з UML

Почнемо з розгляду тих 23 патернів, які описано в книзі банди чотирьох. І самі патерни, і їх назви – це відомі речі навіть для програміста-початківця. Я тебе з ними познайомлю, але рекомендую прочитати ту саму книгу про патерни.

Паттерни проєктування не прив'язані до конкретної мови програмування, тому для їх опису зазвичай використовується мова UML. Вона був дуже популярною років 20 тому, але й зараз нею іноді користуються. До речі, опис патернів – це саме те місце, де використання UML – стандарт.

За допомогою UML ти можеш описати стосунки між різними сутностями. У нашому випадку – це об'єкти та класи.

Відносини між класами описуються чотирма типами стрілок:

композиція (composition) – підвид агрегації, в якій "частини" не можуть існувати окремо від "цілого".
агрегація (aggregation) – описує зв'язок "частина"–"ціле", в якому "частина" може існувати окремо від "цілого". Ромб вказується із боку “цілого”.
залежність (dependency) – зміна в одній сутності (незалежній) може впливати на стан або поведінку іншої сутності (залежної). З боку стрілки зазначається незалежна сутність.
узагальнення (generalization) – відношення наслідування чи реалізації інтерфейсу. З боку стрілки знаходиться суперклас чи інтерфейс.

Насправді тут все дуже просто. Остання стрілочка фактично означає, що один клас успадковується від іншого. А перша та друга стрілочки – це те, що один об'єкт зберігає посилання на другий об'єкт. І це все.

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

5. Список патернів

Види патернів будемо позначати різними кольорами та літерами:

B – Поведінкові (behavioral);

C – Породжувальні (creational);

S- Структурні (structural).

І нарешті список із 23-х патернів проектування:

C – Абстрактна фабрика

S – Адаптер

S – Міст

C – Будівельник

B — Ланцюжок обов'язків

B – Команда

S – Компонувальник

S – Декоратор

S – Фасад

C – Фабричний метод

S — Пристосуванець (Легковаговик)

B – Інтерпретатор

B – Ітератор

B – Посередник

B – Зберігач (Знімок)

C – Прототип

S – Проксі

B – Спостерігач

C – Одинак

B – Стан

B – Стратегія

B – Шаблонний метод

B – Відвідувач


SOLID principles