Повышение читабельности кода и удобства сопровождения за счет следования принципам SOLID

«Чистый код всегда выглядит так, как будто его написал кто-то, кому не все равно»
- Майкл Фезерс

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

Принцип замены Лискова

До сих пор мы видели Принцип единой ответственности (S) и Принцип открытой и закрытости (O) в SOLID. Пришло время изучить следующий. Следующий принцип, начинающийся с L, - это принцип замещения Лискова, сокращенно LSP, названный в честь Барбары Лисков, которая ввела этот принцип.

Согласно статье Барабары, определение LSP:

Пусть Φ (t) - свойство, доказуемое для объектов t типа T. Тогда Φ (s) должно быть истинным для объектов s типа S, где S - подтип T.

Я думаю, что это сложно понять за один раз. По крайней мере, я почувствовал это, когда впервые прочитал это. Но не волнуйтесь, я здесь. Давайте разберемся с этим более простыми словами.

Упрощенный LSP

У нас есть два класса T и S, где S является подклассом T. Базовый класс имеет некоторые методы, которые также присутствуют в подклассе (Φ (t) и Φ (s)). Если объекты базового класса в программе могут быть заменены объектами подкласса, а методы по-прежнему работают нормально для новых объектов, то считается, что программа соответствует LSP.

Следовательно, более упрощенное определение будет:

Объекты суперкласса должны быть заменены объектами его подклассов без нарушения работы приложения (& ведут себя точно так же).

Так просто :

Предположим, вы собираетесь купить новую машину. Ваша старая машина больше не подходит для вашего использования. Но он был лучшим на то время, когда вы его купили. У него были лучшие функции кондиционирования воздуха, отличный двигатель, подушки безопасности, роскошные автомобильные сиденья и многое другое. Но он уже не в прежнем состоянии и управлять им неудобно.

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

Но решите ли вы купить его, если автокресла не такие королевские, как в старом?
Купите ли вы новую модель, если нет мер безопасности, таких как подушки безопасности в новом один?

Без прав? Мы не принимаем новую модель, которая не может заменить старую. По крайней мере, он должен иметь старые функции. Но если этого не сделать, то он неприемлем и не заменим старую машину.

Та же концепция для классов более сложным образом объясняется LSP. Надеюсь, вы это поняли.

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

Теперь мы расширим этот класс счетов, чтобы в нашем банке были другие типы счетов, такие как сберегательный, текущий, фиксированный депозит и т. Д.

Здесь мы видим, что со сберегательной учетной записью все в порядке. Но есть серьезная проблема с нашим счетом с фиксированным депозитом. Он переопределяет метод debitAmount (), чтобы предоставить его собственную реализацию, в которой говорится, что это недопустимая операция, и учетная запись FD не может выполнять дебетовые транзакции. Это логически правильно. Но программно, ТВЕРДЫМ способом это очень неправильно, поскольку нарушает принцип LSP.

Да, теперь, когда он выдает исключения, мы не можем заменить объекты базового класса объектами дочернего класса и ожидать того же поведения. И поскольку мы добавляем новые исключения в наш дочерний класс, мы также должны пойти и добавить их в сигнатуру метода базового класса. Следовательно, касаясь производственного кода как такового. И это определенно не рекомендуется. Так какое же решение? Давай обсудим и это.

Нарушение иерархии

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

Такой способ разрушения иерархии - один из способов решения этой проблемы. Есть и другие способы, которые я оставляю вам для изучения.

Как выявить нарушения LSP?

  • Когда метод не реализован в подклассе.
  • Исключение в подклассе для поведения из родительского класса, которое не выполняется.
  • Метод подкласса переопределяет базовый класс, чтобы дать новое значение.

Следовательно, в этом принципе четко указано, что вы можете реализовать менее строгие правила проверки, но вам не разрешено применять более строгие правила в своем подклассе. Его также можно рассматривать как расширение SRP и OCP, поскольку он правильно разделяет классы, дает правильные обязанности и сохраняет классы точными. Это также помогает определить базовый класс и подкласс, принадлежат ли они к одной и той же иерархии или нет.

Спасибо, что прочитали эту статью! Я надеюсь, что вы нашли в этом ценность, и это полезно для вас. Не стесняйтесь делиться своими мыслями в комментариях!

Давайте вместе сделаем программирование увлекательным! Подпишитесь, чтобы получить больше контента!

Присоединяйтесь к FAUN: Веб-сайт 💻 | Подкаст 🎙️ | Twitter 🐦 | Facebook 👥 | Instagram 📷 | Группа Facebook 🗣️ | Группа Linkedin 💬 | Slack 📱 | Cloud Native Новости 📰 | Еще .

Если этот пост был полезен, нажмите несколько раз кнопку хлопка 👏 ниже, чтобы выразить поддержку автору 👇