Концепция этого принципа была представлена Барбарой Лисков в программном докладе конференции 1987 года, а затем опубликована в статье вместе с Джаннет Винг в 1994 году. defiпервоначальная следующая:
Пусть q (x) - демонстрируемое свойство для объектов x типа T. Тогда q (y) должно быть продемонстрировано для объектов y типа S, где S - подтип T.
Впоследствии, с публикацией принципов SOLID Роберта С. Мартина в его книге Agile Software Development, Principles, Patterns, and Practices, а затем переизданной в версии C# книги Agile Principles, Patterns, and Practices in C#, defiЭтот принцип получил название принципа подстановки Лискова.
Это подводит нас к defiинформация, предоставленная Робертом С. Мартином: Подтипы должны быть заменяемыми на их базовые типы.
класс транспортного средства {
function startEngine () {
// Функция запуска двигателя по умолчанию
}
function accelerate () {
// Функция ускорения по умолчанию
}
}
Учитывая класс Vehicle - он может быть абстрактным - и две реализации:
класс Car расширяет Vehicle {
function startEngine () {
$ this-> enableIgnition ();
parent :: startEngine ();
}
закрытая функция EngageIgnition () {
// Процедура розжига
}
}
class ElectricBus расширяет Vehicle {
function accelerate () {
$ this-> Увеличить напряжение ();
$ this-> connectIndividualEngines ();
}
частная функция Увеличить напряжение () {
// Электрическая логика
}
частная функция connectIndividualEngines () {
// Логика подключения
}
}
водитель класса {
function go (Автомобиль $ v) {
$ v-> startEngine ();
$ v-> ускорять ();
}
}
Это подводит нас к простой реализации шаблона проектирования метода шаблона, который мы использовали в OCP.
Вас также может заинтересовать второй принцип SOLID: https://bloginnovazione.ru / открытый-закрытый-второй-твердый-принцип / 3906 /
Основываясь на нашем предыдущем опыте работы с принципом открытия / закрытия, мы можем сделать вывод, что принцип замещения Лискова тесно связан с OCP. Фактически, «нарушение LSP - это скрытое нарушение OCP» (Роберт С. Мартин), а шаблон проектирования метода шаблонов - классический пример соблюдения и реализации LSP, который, в свою очередь, является одним из решений, позволяющих также соблюдать с OCP.
класс Прямоугольник {
частный $ topLeft;
приватная ширина $;
частная высота $;
публичная функция setHeight ($ height) {
$ this-> height = $ height;
}
public function getHeight () {
вернуть $ this-> height;
}
публичная функция setWidth ($ width) {
$ this-> width = $ width;
}
публичная функция getWidth () {
вернуть $ this-> width;
}
}
Начнем с базовой геометрической формы - прямоугольника. Это простой объект данных с установщиками и получателями для ширины и высоты. Представьте, что наше приложение работает и уже развернуто на нескольких клиентах. Теперь им нужна новая функция. Они должны уметь манипулировать квадратами.
В реальной жизни, в геометрии, квадрат - это определенная форма прямоугольника. Итак, мы могли бы попытаться реализовать класс Square, который расширяет класс Rectangle. Часто говорят, что дочерний класс является родительским, и это выражение также соответствует LSP, по крайней мере, на первый взгляд.
класс Square расширяет прямоугольник {
публичная функция setHeight ($ value) {
$ this-> width = $ значение;
$ this-> height = $ значение;
}
публичная функция setWidth ($ value) {
$ this-> width = $ значение;
$ this-> height = $ значение;
}
}
Квадрат - это прямоугольник с равной шириной и высотой, и мы могли бы сделать странную реализацию, как в предыдущем примере. Мы могли бы переопределить оба сеттера, чтобы установить высоту и ширину. Но как это повлияет на клиентский код?
класс Клиент {
function areaVerifier (Прямоугольник $ r) {
$ r-> setWidth (5);
$ r-> setHeight (4);
if ($ r-> area ()! = 20) {
выбросить новое исключение («Плохая зона!»);
}
возвращает истину;
}
}
function area () {
вернуть $ this-> width * $ this-> height;
}
Очевидно, мы добавили вышеуказанный метод в наш класс Rectangle, чтобы указать площадь.
class LspTest расширяет PHPUnit_Framework_TestCase {
function testRectangleArea () {
$ r = новый прямоугольник ();
$ c = новый клиент ();
$ this-> assertTrue ($ c-> areaVerifier ($ r));
}
}
И мы создали простой тест, отправив пустой прямоугольный объект в средство проверки области, и тест прошел успешно. Если наш класс Square defiзавершено правильно, отправка его в AreaVerifier() клиента не должна нарушать его функциональность. В конце концов, квадрат — это прямоугольник во всех математических смыслах. Но наш ли это класс?
function testSquareArea () {
$ r = новый квадрат ();
$ c = новый клиент ();
$ this-> assertTrue ($ c-> areaVerifier ($ r));
}
Итак, наш класс Square все-таки не является Rectangle. Это нарушает законы геометрии. Это не удается и нарушает принцип замены Лискова..
Ercole Palmeri
В прошлый понедельник Financial Times объявила о сделке с OpenAI. FT лицензирует свою журналистику мирового уровня…
Миллионы людей платят за стриминговые сервисы, выплачивая ежемесячную абонентскую плату. Распространено мнение, что вы…
Coveware от Veeam продолжит предоставлять услуги по реагированию на инциденты, связанные с кибер-вымогательством. Coveware предложит возможности криминалистики и исправления…
Прогнозируемое техническое обслуживание производит революцию в нефтегазовом секторе благодаря инновационному и упреждающему подходу к управлению предприятием…