Файл: уфимский университет науки и технологий факультет математики и информационных технологий кафедра программирования и экономической информатики.docx
Добавлен: 10.11.2023
Просмотров: 178
Скачиваний: 8
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Принцип подстановки Лисков
Принцип подстановки Лисков (Liskov Substitution Principle) - это один из принципов SOLID, который устанавливает, что объекты должны быть заменяемыми своими подтипами, не нарушая правильное выполнение программы. Согласно этому принципу, если S является подтипом T, то объекты типа T могут быть заменены объектами типа S без изменения корректности программы.
Основные идеи принципа подстановки Лисков:
-
Подтипы должны сохранять поведение базового типа: Классы-наследники (подтипы) должны сохранять все контракты, специфицированные базовым типом. Это означает, что все методы базового типа должны иметь те же предусловия, постусловия и инварианты в подтипах. -
Необходимость согласованности интерфейсов: Подтипы должны сохранять интерфейс базового типа, чтобы их можно было использовать везде, где ожидается базовый тип. Это обеспечивает возможность замены объектов базового типа на объекты подтипа без нарушения функциональности программы. -
Правильное использование исключений: Подтипы не должны усиливать предусловия методов базового типа и не должны ослаблять постусловия методов базового типа. Это означает, что подтипы не должны бросать исключения, которые не предусмотрены базовым типом, и не должны подавлять исключения, которые базовый тип должен бросать.
Плюсы
-
Гибкость и переиспользуемость: Принцип подстановки Лисков обеспечивает гибкость взаимозаменяемости объектов, позволяя использовать объекты подтипов вместо объектов базового типа. Это повышает переиспользуемость кода и упрощает модификацию системы без необходимости внесения изменений во все места, где используется базовый тип. -
Расширяемость: При соблюдении принципа подстановки Лисков добавление новых подтипов не влияет на клиентский код, который работает с базовым типом. Это позволяет легко расширять систему путем добавления новых классов или модулей, соответствующих базовому типу. -
Облегчение тестирования: Принцип подстановки Лисков упрощает тестирование кода, поскольку клиентский код, работающий с базовым типом, может быть протестирован независимо от конкретных подтипов. Это позволяет более эффективно тестировать и проверять функциональность системы. -
Улучшение архитектуры: Соблюдение принципа подстановки Лисков способствует лучшей архитектуре системы, поскольку подтипы должны соблюдать контракты и интерфейсы базового типа. Это помогает упростить проектирование и позволяет создавать системы с более четкими и модульными структурами. -
Расширение функциональности: Принцип подстановки Лисков обеспечивает возможность добавления новой функциональности путем создания новых подтипов, не нарушая существующий код, который работает с базовым типом. Это позволяет системе эволюционировать и расти, сохраняя совместимость с предыдущими версиями.
Минусы
-
Сложность соблюдения: Соблюдение принципа подстановки Лисков может быть сложной задачей, особенно в больших и сложных системах. Это требует тщательного планирования и проектирования и может потребовать дополнительных усилий от разработчиков. -
Ограничение на изменение базового типа: Если базовый тип уже используется в различных частях системы, изменение его контракта может потребовать изменений во всех клиентских кодах. Это может стать проблемой, особенно в больших проектах, где сложно отследить все зависимости. -
Возможность нарушения инвариантов: При несоблюдении принципа подстановки Лисков могут возникнуть проблемы с нарушением инвариантов, которые должны быть сохранены для корректной работы программы. Это может привести к неожиданному поведению и ошибкам в работе системы. -
Зависимость от документации и контрактов: Для успешной реализации принципа подстановки Лисков требуется хорошо задокументированная спецификация базового типа и подтипов. Недостаточная документация или неполное понимание контрактов может привести к неправильной реализации и нарушению принципа. -
Возможность нарушения эффективности: В некоторых случаях строгое соблюдение принципа подстановки Лисков может привести к неэффективности программы. Например, для соблюдения инвариантов могут потребоваться дополнительные проверки и операции, что может замедлить выполнение кода.
Принцип подстановки Лисков полезен во многих ситуациях разработки программного обеспечения, где требуется гибкость, переиспользование кода, расширяемость и поддержка модульной архитектуры.
-
Принцип разделения интерфейсов
Принцип разделения интерфейсов (Interface Segregation Principle, ISP) является одним из принципов SOLID. Он утверждает, что клиенты не должны зависеть от интерфейсов, которые они не используют.
Вот основные идеи принципа разделения интерфейсов:
-
Специфичность интерфейсов: Интерфейсы следует проектировать таким образом, чтобы они были специфичны для клиентов. Каждый клиент должен иметь доступ только к тем методам интерфейса, которые ему действительно необходимы, а не к несвязанным с его функциональностью методам. -
Разделение на более мелкие интерфейсы: Если интерфейс становится слишком большим и содержит множество методов, которые не используются всеми клиентами, следует разделить его на более мелкие и специфичные интерфейсы. Это позволяет клиентам выбирать только необходимые им интерфейсы и избегать зависимостей от ненужных методов. -
Избегание "толстых" интерфейсов: Не следует создавать "толстые" интерфейсы, которые содержат большое количество методов. Если клиентам требуется реализовывать все методы интерфейса, это приводит к ненужным зависимостям и сложностям при поддержке кода. Лучше создавать более мелкие и специфичные интерфейсы, каждый из которых отвечает за определенный функциональный контракт.
Плюсы принципа разделения интерфейсов:
-
Улучшение гибкости: ISP способствует улучшению гибкости системы, поскольку каждый клиент зависит только от тех методов, которые ему действительно необходимы. Это позволяет более просто добавлять новые функциональности и изменять существующие, не затрагивая клиентский код. -
Уменьшение связности: ISP помогает уменьшить связность между классами, разделяя интерфейсы на более мелкие и специализированные. Это позволяет классам быть независимыми друг от друга и облегчает их переиспользование. -
Улучшение тестируемости: Более маленькие и специализированные интерфейсы облегчают тестирование, поскольку можно сосредоточиться только на необходимых методах. Тесты становятся более простыми и понятными.
Минусы принципа разделения интерфейсов:
-
Усложнение архитектуры: Применение ISP может привести к увеличению числа интерфейсов и классов в системе, что может усложнить ее архитектуру. Управление большим количеством интерфейсов может быть сложным и требовать дополнительных усилий при разработке и поддержке. -
Нарушение DRY-принципа: ISP может привести к дублированию кода, особенно если несколько классов требуют реализации похожих методов из разных интерфейсов. Это может привести к увеличению объема кода и усложнению его поддержки. -
Несогласованность между интерфейсами: Разделение интерфейсов может привести к несогласованности между различными интерфейсами, которые используются разными клиентами. Это может затруднить работу с кодом и усложнить его понимание.
-
Принцип инверсии зависимостей
Принцип инверсии зависимостей (Dependency Inversion Principle, DIP) является одним из принципов SOLID. Он определяет следующее:
-
Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба типа модулей должны зависеть от абстракций. -
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций. -
Принцип инверсии зависимостей нацелен на устранение прямой зависимости между компонентами системы. Вместо того, чтобы модули верхнего уровня зависели от конкретных реализаций модулей нижнего уровня, они должны зависеть от абстракций или интерфейсов.
Это позволяет создавать более гибкие и масштабируемые системы, так как модули могут быть легко заменены или модифицированы без внесения изменений в другие модули, которые зависят от них. Также это способствует повторному использованию кода и упрощает тестирование, поскольку зависимости могут быть заменены на фиктивные объекты или моки в тестовом окружении.
Принцип инверсии зависимостей обычно достигается с использованием паттернов проектирования, таких как Dependency Injection (DI) или Service Locator. Суть заключается в том, что зависимости передаются модулям извне, а не создаются самими модулями, что позволяет достичь слабой связности и повысить гибкость системы.
В итоге, принцип инверсии зависимостей способствует созданию модульных, гибких и расширяемых систем, где изменения в одной части системы могут быть внесены с минимальным воздействием на другие части.
Плюсы принципа инверсии зависимостей:
-
Гибкость и расширяемость: Применение DIP позволяет создавать более гибкие и расширяемые системы. Зависимости, основанные на абстракциях, обеспечивают возможность легко заменять конкретные реализации модулей без внесения изменений в остальную систему. Это упрощает добавление новых функциональностей и модификацию существующих компонентов. -
Улучшенная тестируемость: Инверсия зависимостей позволяет легко создавать фиктивные объекты или моки для модулей, с которыми выполняется взаимодействие. Это облегчает тестирование отдельных модулей, так как можно изолировать их от реальных зависимостей и сфокусироваться на проверке их функциональности. -
Повторное использование: Использование абстракций и интерфейсов способствует повторному использованию кода. Модули верхнего уровня, зависящие только от абстракций, могут использовать различные реализации нижних уровней без изменений в своем коде.
Минусы принципа инверсии зависимостей:
-
Усложнение архитектуры: Внедрение абстракций и использование механизмов инверсии зависимостей может привести к усложнению архитектуры приложения. Это может затруднить понимание кода и его поддержку в будущем. -
Дополнительные затраты на разработку: Применение принципа инверсии зависимостей требует дополнительных усилий и времени для создания абстракций, интерфейсов и настройки механизмов внедрения зависимостей. Это может привести к увеличению затрат на разработку. -
Сложность отладки: Использование абстракций может затруднить процесс отладки, поскольку требуется отслеживание зависимостей между компонентами и понимание взаимодействия абстракций. Это может усложнить выявление и исправление ошибок. -
Усложнение обучения новых разработчиков: Принцип инверсии зависимостей может быть сложным для понимания и применения новыми разработчиками, особенно если они не имеют достаточного опыта. Это может потребовать дополнительного времени и ресурсов для обучения и внедрения правильного использования этого принципа. -
Потеря производительности: Внедрение механизмов инверсии зависимостей может потребовать дополнительных вычислительных ресурсов и привести к некоторым накладным расходам на производительность приложения. Это особенно актуально в случае больших проектов или систем с высокими требованиями к производительности.
Заключение
В заключение курсовой работы о паттерне "Декоратор" (Decorator), хочу подытожить его основные аспекты и применение.
Паттерн "Декоратор" является структурным паттерном проектирования, который позволяет динамически добавлять новую функциональность объектам путем оборачивания их в объекты-декораторы. Это позволяет гибко расширять функциональность объектов без изменения их основной структуры.
Основные участники паттерна "Декоратор" включают:
-
Компонент (Component): это базовый класс или интерфейс, определяющий общий интерфейс для всех объектов, которые будут декорироваться. -
Конкретный компонент (Concrete Component): это класс, представляющий основной объект, который может быть декорирован. -
Декоратор (Decorator): это базовый класс или интерфейс, который имеет ссылку на объект-компонент и определяет интерфейс, совместимый с компонентом. -
Конкретный декоратор (Concrete Decorator): это класс, который расширяет функциональность базового декоратора и добавляет новые возможности.
Также были рассмотрены преимущества использования паттерна "Декоратор", такие как гибкость и расширяемость системы, возможность добавления новых возможностей без изменения существующего кода, а также возможность комбинирования декораторов для создания различных вариаций объектов.
Литература
1) Тепляков С. Паттерны проектирования на платформе .NET. — СПб.:
Питер, 2015. — 320 с.: ил.
2) Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-
ориентированного проектирования. Паттерны проектирования — СПб:
«Питер», 2007. — С. 366
3) Фриман Э. Паттерны проектирования. — СПб.: Питер, 2003.
4) https://metanit.com/sharp/patterns/
5) https://tproger.ru/translations/design-patterns-simple-words-2/#27
6) https://habr.com/ru/articles/86255/