digital-garden/dev/architecture/Liskov Substitution Principle.md
Struchkov Mark 2c945630a3
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
Обновление и рефакторинг
2024-11-23 21:34:40 +03:00

4.7 KiB
Raw Blame History

aliases tags date
LSP
Принцип подстановки Барбары Лисков
maturity/🌱
2024-09-27

Принцип подстановки Лисков (Liskov Substitution Principle, LSP) утверждает, что ==объекты подклассов должны быть взаимозаменяемы с объектами базового класса без изменения поведения программы==. Это означает, что ==подклассы не должны нарушать контракт базового класса или изменять его логику==. LSP является третьим принципом в наборSOLIDID и играет ключевую роль в создании устойчивой и понятной иерархии классов.

Чтобы соответствовать LSP:

  • Подклассы должны расширять функциональность базового класса, не изменяя его поведение.
  • Контракт взаимодействия, задаваемые базовыми классами, должны строго соблюдаться.
  • Следует избегать переопределения методов, если это изменяет их ожидаемое поведение.

Преимущества соблюдения LSP:

  1. Предсказуемость: Код, использующий базовый класс, будет работать одинаково независимо от того, какие подклассы используются.
  2. Упрощение тестирования: Система становится менее подверженной ошибкам, так как базовый контракт всегда соблюдается.
  3. Гибкость и масштабируемость: Добавление новых подклассов не требует модификации существующего кода, если соблюден принцип LSP.
  4. Улучшенная читаемость: Четкое разделение обязанностей между базовыми и дочерними классами упрощает понимание системы.

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

Рассмотрим иерархию классов для птиц:

public class Bird {
    public void fly() {
        // Логика полета
        System.out.println("I can fly!");
    }
}

public class Penguin extends Bird {
    @Override
    public void fly() {
        // Пингвин не может летать — нарушение LSP
        throw new UnsupportedOperationException("Penguins cannot fly");
    }
}

В данном случае класс Penguin нарушает контракт базового класса Bird. Код, который ожидает, что любой объект типа Bird может летать, перестанет работать корректно при использовании Penguin. Это ведет к непредсказуемому поведению программы и увеличивает сложность сопровождения.

Для устранения нарушения следует пересмотреть иерархию классов, чтобы явно выделить летающих и нелетающих птиц:

public abstract class Bird {
    // Общие свойства и методы для всех птиц
}

public interface Flyable {
    void fly();
}

public class FlyingBird extends Bird implements Flyable {
    @Override
    public void fly() {
        // Реализация полета
        System.out.println("I can fly!");
    }
}

public class Penguin extends Bird {
    // Пингвин остается нелетающей птицей
}

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


Мета информация

Область:: ../../meta/zero/00 Архитектура ПО Родитель:: SOLID Источник:: Создана:: 2024-09-27 Автор::

Дополнительные материалы

Дочерние заметки