Рубрики
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
Принцип подстановки Барбары Лисков

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