Відповіді на запитання по OOP, FP та Патернам проектування

Тут ти знайдеш відповіді на питання, які часто зустрічаються на співбесідах

Об'єктно орієнтоване програмування включає 4 принципи:

  • Абстракція (Abstraction) - це дуже простий принцип, дотримуючись якого, ви створюєте класи та їх об'єкти, що описують об'єкти реального світу. Наприклад, клас Car буде містити поля та методи відповідні властивостям реального автомобіля, які потрібні вам для реалізації функціональності у вашій програмі. Клас Car може містити поля марки та моделі автомобіля, рік випуску, а також методи розрахунку витрати палива та контролю мікроклімату в салоні.
  • Спадкування (Inheritance) - дозволяє створити новий клас на основі існуючого (батьківський клас або суперклас). При цьому новий клас-нащадок успадковує всі поля та методи класу-батька, і ви можете додати потрібні вам поля чи методи до нового класу яких немає в батьківському.
    Спадкування дозволяє скоротити кількість коду, що повторюється. Наприклад, якщо у вас є класи для різних типів співробітників і у них є однакові поля або методи, типу імені, контактів або методу нарахування зарплати, ви можете винести все це в батьківський клас Співробітник. А в дочірник класах вже описувати унікальні властивості та методи співробітника, чи то розробник чи бухгалтер.
  • Інкапсуляція (Encapsulation) - це приховування внутрішніх даних і методів класу, і надання методів для управління ним (API). Це сприяє прискоренню розробки та налагодження коду, оскільки код одних класів не використовує код інших на пряму, і вони взаємодіють лише за допомогою API.
    Слід зазначити, що інкапсуляція це не тільки про класи. Вона застосовна до програмування цілком, тобто будь-який модуль або підсистема повинна розглядатися вами як чорна скринька, доступ до якої здійснюється лише через API.
  • Поліморфізм (Polymorphism) - це принцип, який означає, що той самий метод може набувати різних форм і поводитися по-різному у різних контекстах. Завдяки поліморфізму можна написати код, який працюватиме з різними типами даних, не залежно від конкретної реалізації. Поліморфізм реалізується за допомогою механізмів успадкування та перевизначення методів. Для того щоб використовувати поліморфізм, необхідно визначити базовий клас із набором методів, які будуть використовуватись у похідних класах. При наслідуванні похідний клас може перевизначити методи базового класу та реалізувати їх по-своєму.
    Нижче приклад поліморфізму на TypeScript.
class Animal { public name: string; constructor(name: string) { this.name = name; } public makeSound(): void { console.log('Animal sound'); } } export class Dog extends Animal { public makeSound(): void { console.log(`${this.name} barking`); } } class Cat extends Animal { public makeSound(): void { console.log(`${this.name} meows`); } } const tom: Animal = new Cat('Tom'); tom.makeSound(); // Tom meows const spike: Animal = new Dog('Spike'); spike.makeSound(); // Spike barking

У класовому наслідуванні екземпляри створюються від класів. Класи створюють ієрархійне дерево наслідування.
Наявність вертикальної архітектури класів може призводити до труднощів зміни базових класів.

У прототипному наслідуванні екземпляри успадковуються з інших екземплярів. Це здійснюється через фабрики або методом Object.create.
Прототипне успадкування дозволяє створювати горизонтальну архітектуру та більш гнучкі зв'язки між екземплярами. Ви можете зв'язувати об'єкти з іншими об'єктами, використовуючи прототипи делегатів. Або просто копіювати властивості одного екземпляра в інший, використовуючи конкатенативне успадкування.

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

  • Single Responsibility Principle (Принцип єдиної відповідальності) - клас має бути відповідальним лише за один аспект функціональності. Якщо клас виконує кілька завдань, його складові стають пов'язаними один з одним. І змінюючи якусь функціональність такого класу, ви з великою ймовірністю зачепите функціональність класу, що залишилася. У такому разі клас треба розділити на кілька дрібніших класів, щоб вони виконували тільки щось одне.
  • Open/Closed Principle (Принцип відкритості/закритості) - класи повинні бути відкриті для розширення, але закриті для зміни. Це означає, що клас повинен надавати інтерфейс для розширення своєї функціональності, але не повинен змінюватись при додаванні нової функціональності.
  • Liskov Substitution Principle (Принцип підстановки Барбари Лисків) - класи-спадкоємці повинні мати можливість замінити суперклас від якого вони утворені, без зміни у правильності роботи програми.
  • Interface Segregation Principle (Принцип поділу інтерфейсу) - класи, що імплементують якийсь інтерфейс не повинні залежати від методів, які вони не використовують. Це означає, що інтерфейси мають бути маленькими та специфічними, і кожен клас повинен використовувати лише ті методи інтерфейсу, які йому потрібні.
  • Dependency Inversion Principle (Принцип інверсії залежностей) - модулі верхнього рівня не повинні залежати від модулів нижнього рівня. Обидва мають залежати від абстракцій. Це означає, що класи повинні залежати від абстракцій, а не від конкретних реалізацій, що робить програму гнучкішою та легко розширюваною.

Інші питання

Якщо у тебе є питання чи пропозиції, напиши мені: Telegram | LinkedIn
© 2023 All rights reserved