учебник

Принцип подстановки Лискова, третий твердый принцип

Дочерние классы никогда не должны влиять на файлы или изменять их. defiоператоры типа родительского класса.

Концепция этого принципа была представлена ​​Барбарой Лисков в программном докладе конференции 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-> ускорять ();

    }

}

Клиентский класс должен иметь возможность использовать оба, если он может использовать Vehicle.

Это подводит нас к простой реализации шаблона проектирования метода шаблона, который мы использовали в OCP.

Вас также может заинтересовать второй принцип SOLID: https://bloginnovazione.ru / открытый-закрытый-второй-твердый-принцип / 3906 /

Основываясь на нашем предыдущем опыте работы с принципом открытия / закрытия, мы можем сделать вывод, что принцип замещения Лискова тесно связан с OCP. Фактически, «нарушение LSP - это скрытое нарушение OCP» (Роберт С. Мартин), а шаблон проектирования метода шаблонов - классический пример соблюдения и реализации LSP, который, в свою очередь, является одним из решений, позволяющих также соблюдать с OCP.

Пример нарушения LSP

класс Прямоугольник {

    частный $ 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

Инновационный бюллетень
Не пропустите самые важные новости об инновациях. Зарегистрируйтесь, чтобы получать их по электронной почте.

АРТИКОЛИ recenti

Издатели и OpenAI подписывают соглашения, регулирующие поток информации, обрабатываемой искусственным интеллектом.

В прошлый понедельник Financial Times объявила о сделке с OpenAI. FT лицензирует свою журналистику мирового уровня…

Апрель 30 2024

Онлайн-платежи: вот как потоковые сервисы заставляют вас платить вечно

Миллионы людей платят за стриминговые сервисы, выплачивая ежемесячную абонентскую плату. Распространено мнение, что вы…

Апрель 29 2024

Veeam предлагает наиболее полную поддержку программ-вымогателей: от защиты до реагирования и восстановления.

Coveware от Veeam продолжит предоставлять услуги по реагированию на инциденты, связанные с кибер-вымогательством. Coveware предложит возможности криминалистики и исправления…

Апрель 23 2024

Зеленая и цифровая революция: как прогнозируемое обслуживание меняет нефтегазовую отрасль

Прогнозируемое техническое обслуживание производит революцию в нефтегазовом секторе благодаря инновационному и упреждающему подходу к управлению предприятием…

Апрель 22 2024

Читайте «Инновации» на вашем языке

Инновационный бюллетень
Не пропустите самые важные новости об инновациях. Зарегистрируйтесь, чтобы получать их по электронной почте.

Следуйте за нами