У світі розробки програмного забезпечення написання коду є простим завданням, але написання чистого, підтримуваного та масштабованого коду – це справжнє мистецтво. Саме тут на допомогу приходять принципи SOLID. SOLID – це п’ять принципів проектування, які допомагають розробникам створювати надійні, гнучкі та ефективні системи. Ці принципи є основою «Low-Level Design (LLD)» і необхідні для створення програмного забезпечення, яке витримає випробування часом.
Я зроблю для вас розуміння кожного принципу SOLID простим та надам приклади з реального світу, щоб продемонструвати, як вони сприяють створенню ефективних систем і програм.
Що таке принципи SOLID?
SOLID – це набір з п’яти принципів проектування, які були запропоновані Робертом К. Мартіном (Uncle Bob). Ці принципи спрямовані на те, щоб допомогти розробникам писати код, який легко зрозуміти, підтримувати та розширювати. П’ять принципів:
- Single Responsibility Principle (SRP)
- Open/Closed Principle (OCP)
- Liskov Substitution Principle (LSP)
- Interface Segregation Principle (ISP)
- Dependency Inversion Principle (DIP)
Давайте розглянемо кожен принцип із прикладами з реального світу.
Single Responsibility Principle (SRP)
Клас має мати лише одну причину для зміни, тобто лише одну відповідальність.
Приклад з реального світу:
Уявімо систему управління рестораном. Клас **Chef**
(Шеф-кухар) повинен бути відповідальним лише за приготування їжі, а не за управління замовленнями чи обробку платежів. Якщо клас Chef
також відповідає за розрахунок, його буде складніше підтримувати та змінювати.
Як це допомагає:
Зручність підтримки: Зміни в логіці розрахунків не впливатимуть на логіку приготування.
Повторне використання: Клас **Chef**
може бути повторно використаний в інших системах без зайвих обов’язків.
Open/Closed Principle (OCP)
Програмні сутності (класи, модулі, функції) повинні бути відкритими для розширення, але закритими для модифікації.
Приклад з реального світу:
Розгляньмо систему платіжного шлюзу (Payment Gateway System). Ви можете почати з підтримки лише кредитних карток, але пізніше може знадобитися додати підтримку PayPal, UPI або криптовалют. Замість модифікації існуючого коду для обробки платежів, його можна розширити.
Як це допомагає:
Масштабованість: Нові методи оплати можна додати без змін існуючого коду.
Стабільність: Існуюча функціональність залишається незмінною, зменшуючи ризик виникнення помилок.
Liskov Substitution Principle (LSP)
Об'єкти базового класу повинні бути замінні на об'єкти підкласів без порушення коректності програми.
Приклад з реального світу
Уявімо клас Bird (Птах) із методом fly()
(літати). Підклас Penguin
(Пінгвін) не може літати, тому це порушує LSP, якщо він успадковується від Bird
. Замість цього створіть підклас FlyingBird
для птахів, які можуть літати.
Як це допомагає:
Надійність: Гарантує, що підкласи поводяться так, як очікується, коли використовуються замість свого батьківського класу.
Гнучкість: Сприяє правильному успадкуванню та запобігає неочікуваній поведінці.
Interface Segregation Principle (ISP)
Клієнти не повинні залежати від інтерфейсів, які вони не використовують. Замість одного великого інтерфейсу створюйте менші та конкретні.
Приклад з реального світу
Уявімо інтерфейс Printer (Принтер) із методами **print**()
, **scan**()
і **fax**()
. Простий принтер може потребувати лише print()
, але його змушують реалізовувати scan()
і fax()
без потреби.
Як це допомагає:
Простота: Клієнти залежать лише від методів, які їм потрібні.
Модульність (Modularity): Інтерфейси більш зосереджені та простіші у впровадженні.
Принцип Інверсії Залежностей (Dependency Inversion Principle, DIP)
Модулі високого рівня не повинні залежати від модулів низького рівня. Обидва мають залежати від абстракцій. Абстракції не повинні залежати від деталей; деталі повинні залежати від абстракцій.
Приклад з реального світу
У системі сповіщень (Notification System) модуль високого рівня (наприклад, **NotificationService**
) не повинен залежати від конкретних методів сповіщення (наприклад, **EmailNotification**
чи **SMSNotification**
). Натомість він повинен залежати від абстракції, такої як **Notification**
.
Як це допомагає:
Гнучкість: Легко змінювати реалізації (наприклад, перейти з email на SMS).
Тестування: Можна створювати моки для залежностей під час тестування.
Чому принципи SOLID важливі
- Зручність підтримки (Maintainability): Код за принципами SOLID легше розуміти, модифікувати та розширювати.
- Масштабованість (Scalability): Системи, побудовані за принципами SOLID, можуть рости без перетворення на заплутану структуру.
- Повторне використання (Reusability): Компоненти є модульними та можуть використовуватись повторно в різних проєктах.
- Тестованість (Testability): Код, написаний за SOLID, легше тестувати, що зменшує кількість помилок.
- Співпраця (Collaboration): Чистий та добре структурований код робить роботу в команді ефективнішою.
— -
Принципи SOLID – це не просто теоретичні концепти; це практичні інструменти, які допомагають розробникам створювати ефективні, зручні в підтримці та масштабовані системи. Завдяки застосуванню цих принципів ви можете уникнути поширених проблем, таких як тісно пов’язаний код, негнучкі дизайни та важкокеровані системи.
Чи будуєте ви невеликий додаток чи великомасштабну систему, принципи SOLID допоможуть вам створити програмне забезпечення, яке буде надійним, гнучким і готовим до майбутнього.
— -
Подобається? Залишайтеся з нами для щоденних порад щодо розробки програмного забезпечення, архітектури систем і найкращих практик програмування! Діліться думками в коментарях. Успішного кодування! 🚀**
Перекладено з: SOLID Principles: Low Level Designing