1/52
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced | Call with Kai | Chat |
|---|
No analytics yet
Send a link to your students to track their progress
Що таке SOLID?
SOLID — це п’ять принципів об’єктно-орієнтованого дизайну, які допомагають писати код, який легше змінювати, тестувати й підтримувати.
Для чого потрібен SOLID на практиці?
SOLID потрібен, щоб зменшити хаос у коді: менше жорстких залежностей, менше дублювання логіки, простіше додавати нову поведінку без поломки старої.
Що означає SRP?
SRP означає, що клас або модуль має мати одну основну відповідальність і одну головну причину для зміни.
Наведи простий приклад порушення SRP.
Якщо один клас одночасно рахує бізнес-логіку, зберігає дані в базу і відправляє email, це порушення SRP.
Як виправити порушення SRP?
Потрібно розділити відповідальності: окремо сервіс для бізнес-логіки, окремо репозиторій для збереження, окремо сервіс для відправки повідомлень.
Що означає OCP?
OCP означає, що код має бути відкритий для розширення, але закритий для постійної зміни вже існуючої логіки.
Як на практиці реалізувати OCP?
Зазвичай через інтерфейси, абстракції, поліморфізм, Strategy або Factory, щоб нову поведінку можна було додати новим класом, а не переписуванням старого.
Який типовий приклад порушення OCP?
Великий if або switch по типах, куди при кожному новому типі треба додавати нову гілку.
Що означає LSP?
LSP означає, що об’єкт дочірнього класу має нормально замінювати об’єкт базового класу без поломки очікуваної поведінки.
Простими словами, у чому суть LSP?
Якщо код працює з базовим типом, він не повинен ламатися або поводитися дивно, коли йому передали будь-яку реалізацію цього типу.
Наведи приклад порушення LSP.
Клас Bird має метод fly, але Penguin наслідується від Bird і не може літати. Це погана модель, бо підтип не виконує контракт базового типу.
Як виправити порушення LSP з птахами?
Краще винести здатність літати в окремий інтерфейс, наприклад Flyable, і реалізовувати його тільки для тих птахів, які реально літають.
Що означає ISP?
ISP означає, що клієнт не повинен залежати від методів, які він не використовує.
Який приклад порушення ISP?
Один великий інтерфейс Worker з методами work, eat, sleep, manage, report змушує різні класи реалізовувати зайві методи, які їм не потрібні.
Як виправити порушення ISP?
Потрібно розділити великий інтерфейс на кілька менших і точніших, наприклад Workable, Eatable, Reportable.
Що означає DIP?
DIP означає, що високорівнева логіка не повинна залежати від конкретних низькорівневих класів, вона має залежати від абстракцій.
Навіщо потрібен DIP?
DIP робить код гнучкішим і тестованішим, бо конкретні реалізації можна замінювати, наприклад на mock у тестах.
Який простий приклад DIP?
Сервіс авторизації залежить не від конкретного ApiClient, а від інтерфейсу AuthRepository, тому реалізацію можна легко замінити.
Що таке dependency injection?
Dependency injection — це підхід, коли залежності передаються класу ззовні, найчастіше через конструктор, а не створюються всередині класу.
Чому створювати залежності через new всередині класу часто погано?
Тому що клас стає жорстко прив’язаний до конкретної реалізації, і його складніше тестувати або змінювати.
Що таке інкапсуляція?
Інкапсуляція — це приховування внутрішнього стану об’єкта і контроль доступу до нього через публічні методи або властивості.
Навіщо потрібна інкапсуляція?
Вона захищає об’єкт від некоректного використання і дозволяє змінювати внутрішню реалізацію без поломки зовнішнього коду.
Що таке абстракція?
Абстракція — це виділення головного контракту або поведінки без прив’язки до конкретної реалізації.
Що таке поліморфізм?
Поліморфізм — це можливість працювати з різними об’єктами через спільний інтерфейс або базовий тип, не знаючи їх конкретного класу.
Наведи приклад поліморфізму.
Ми можемо мати інтерфейс PaymentMethod і різні реалізації: CardPayment, ApplePayPayment, GooglePayPayment. Код викликає pay, не знаючи деталей оплати.
Що таке наслідування?
Наслідування — це механізм, коли один клас бере поведінку або властивості іншого класу і може їх розширювати або змінювати.
Коли наслідування краще не використовувати?
Коли між класами немає справжнього відношення “is-a”. У таких випадках частіше краще використати композицію.
Що означає composition over inheritance?
Це принцип, що поведінку часто краще збирати з окремих залежностей, а не будувати глибоку ієрархію наслідування.
Чому композиція часто краща за наслідування?
Композиція дає менше жорсткого зв’язку між класами і дозволяє легше міняти частини поведінки.
Що таке абстрактний клас?
Абстрактний клас — це клас, який задає спільний контракт або базову поведінку, але зазвичай не створюється напряму.
Чим інтерфейс відрізняється від абстрактного класу?
Інтерфейс описує контракт, що об’єкт має вміти робити, а абстрактний клас може ще містити спільну базову реалізацію.
Що таке coupling?
Coupling — це рівень залежності одного модуля або класу від іншого. Чим він нижчий, тим легше змінювати код.
Що таке cohesion?
Cohesion — це наскільки добре логіка всередині класу або модуля зібрана навколо однієї зрозумілої відповідальності.
Що краще: high cohesion чи low cohesion?
Краще high cohesion, бо клас має бути сфокусований на одній зрозумілій задачі, а не містити все підряд.
Що краще: tight coupling чи loose coupling?
Краще loose coupling, бо класи менше залежать від конкретних реалізацій і їх легше тестувати та замінювати.
Що таке DRY?
DRY означає не дублювати знання в коді. Якщо одна й та сама бізнес-логіка повторюється в кількох місцях, її краще винести в одне місце.
Чи означає DRY, що не можна повторювати жодного рядка коду?
Ні. DRY більше про дублювання знання або правил, а не про механічне видалення кожного схожого рядка.
Що таке KISS?
KISS означає, що рішення має бути настільки простим, наскільки це можливо без втрати якості.
Що таке YAGNI?
YAGNI означає не робити функціональність або абстракції наперед, якщо зараз у них немає реальної потреби.
Що таке code smell?
Code smell — це ознака в коді, яка не завжди є багом, але показує, що дизайн може бути проблемним.
Назви приклади code smells.
Великий клас, великий метод, дублювання логіки, довгі if/switch, багато залежностей у конструкторі, змішування UI і бізнес-логіки.
Як SOLID пов’язаний з тестуванням?
SOLID робить код менш залежним від конкретних реалізацій, тому його легше покривати unit-тестами і підміняти залежності mock-ами.
Як SOLID пов’язаний з Clean Architecture?
Clean Architecture активно використовує SOLID, особливо DIP, щоб бізнес-логіка не залежала від UI, бази даних або мережі.
Як DIP застосовується у Flutter?
Наприклад, Cubit або UseCase залежить від абстрактного Repository, а не від конкретного API-клієнта або Firebase-класу.
Чому не варто тримати бізнес-логіку прямо у Widget?
Тому що Widget має відповідати за UI, а бізнес-логіку краще винести в окремий шар, щоб її було легше тестувати й підтримувати.
Що таке Repository у Flutter-архітектурі?
Repository — це шар, який ховає джерело даних і дає бізнес-логіці простий контракт для отримання або збереження інформації.
Чому Repository краще робити через абстракцію?
Так бізнес-логіка не залежить від конкретного API, бази даних або кешу, і реалізацію можна замінити без зміни use case.
Що таке UseCase?
UseCase — це клас або функція, яка представляє одну конкретну бізнес-дію, наприклад login, getUserProfile або submitOrder.
Який принцип SOLID найчастіше порушують у Flutter?
Найчастіше порушують SRP, коли в одному Widget або Cubit змішують UI, навігацію, API-запити, валідацію і бізнес-правила.
Який принцип SOLID найважливіший для тестів?
Найчастіше DIP, бо без залежності від абстракцій складно нормально підміняти реальні сервіси mock-ами.
Що відповісти, якщо на співбесіді питають, чи завжди треба використовувати SOLID?
Ні, SOLID не треба застосовувати механічно всюди. Його треба використовувати там, де код реально буде змінюватися, тестуватися і підтримуватися.
Яка головна помилка при використанні SOLID?
Головна помилка — створювати занадто багато абстракцій без реальної потреби, через що код стає складнішим, а не простішим.