Рубрики
4. Interface segregation principle SOLID

Interface segregation principle «Понятие»

4. Interface segregation principle
Принцип разделения интерфейса

программные сущности не должны зависеть от методов, которые они не используют

  • тесно связан с первым принципом (ответственность)
  • тесно связан с третьим принципом (подстановка)

разбивать толстые интерфейсы (программные сущности)

  • интерфейсы маленькие (узко-специализированные)
  • интерфейсы решают одну задачу

Положительность в принципе

  • избавляем программные сущности от методов, которые они не используют
  • получаем более предсказуемую работу
  • код становится менее связанным в модулях и легче поддерживается
Рубрики
3. Liskov Substitution Principle SOLID

SOLID «EXAMPLE» класс база данных

класс база данных и есть классические операции
class Database {
 connect(){} подключение
 read(){} чтение каких-то данных
 write(){} запись каких-то данных
 joinTables(){} добавляем метод по объединению таблиц
}
класс реляционная база данных MySQLDataBase в которой все данные хранятся в форме связанных таблиц (уместен joinTables)
расширяет поведение базового класса Database

class MySQLDataBase extends Database{
 connect(){}
 read(){}
 write(){}
 joinTables(){}
}

при работе с дочерними классами мы должны быть уверены что ничего не сломается.
у нас есть какая-то стартовая точка в приложении
там мы конфигурируем базу данных и подключаемся к ней
и хотим выполнить какие-то операции.
При замене реляционной базы на не реляционную
например на МонгоБазу нарушается принцип Барбары Лисков

класс не реляционная база данных MongoDB и там данных хранятся в форме коллекции и документов
там таблиц нет и объединять таблицы мы не можем
class MongoDatabase extends Database {
 connect(){}
 read(){}
 write(){}
 переопределяем метод и выбрасываем ошибку
 joinTables(){error}
}

при правильном проектировании было уместнее сделать сделать следующие.
Мы создаём ещё один класс, который наследует от базового. Из него мы удаляем метод joinTables

В таком случае, у нас в базовом классе определены операции, которые доступны только для всех баз данных (подключение, чтение, запись баз данных)

class Database {
 connect(){} подключение
 read(){} чтение каких-то данных
 write(){} запись каких-то данных
 joinTables(){}
}

специфичные методы для конкретного типа базы данных мы вынесли в отдельные классы

class SQLDataBase extends Database{
 connect(){}
 read(){}
 write(){}
 joinTables(){}
}
class NOSQLDatabase extends Database {
 connect(){}
 read(){}
 write(){}
 createIndex(){}
}

class MySQLDataBase extends SQLDatabase{
 connect(){}
 read(){}
 write(){}
 joinTables(){}
}
class MongoDatabase extends NOSQLDatabase {
 connect(){}
 read(){}
 write(){}
 createIndex(){}
 mergerDocuments(){}
}

При запуске приложения мы на входе ожидаем какую-то базу данных. Какую базу данных мы бы не передали, у всех из них должен быть метод connect с предсказуемым поведением, который не замещает, а дополняет поведение базового класса

function startApp(database: Database){
 database.connect();
}
startApp(new MongoDatabase);
startApp(new MySQLDatabase);
Рубрики
3. Liskov Substitution Principle SOLID

Liskov Substitution Principle «Понятие»

3. Liskov Substitution Principle
Принцип подстановки Барбары Лисков

функции, сущности которые используют родительский тип
должны работать точно так же и с дочерними классами
наследуемый класс должен дополнять, а не замещать поведение базового класса

Рубрики
2. Open-closed principle SOLID

SOLID «EXAMPLE» класс оружие Weapon

2. Open-closed principle
Принцип открытости/закрытости

класс оружие Weapon
у него три поля type, damage, range (тип, урон, дистанция)

class Weapon {
 type: string;
 damage: number; // 0 - 100;
 range: number; // 0 - 100;

 contructor(type: string, damage: number, range: number) {
  this.type = type;
  this.damage  = damage;
  this.range = range;
 }
}

класс персонаж Character
который может это оружие Weapon принимать через метод

class Character {
 name: string;
 weapon: Weapon;

 contructor(name: string, weapon: Weapon) {
  this.name = name;
  this.weapon= weapon;
 }
 принимает оружие
 changeWeapon(newWeapon:Weapon) {
  this.weapon = newWeapon;
 }
}
Рубрики
2. Open-closed principle SOLID

Open-closed principle «Понятие»

2. Open-closed principle
Принцип открытости/закрытости

классы, компоненты, модули, функции

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