Паттерн декоратора: паттерн для динамического расширения классов

Если вы хотите расширить функциональные возможности существующего класса в объектно-ориентированном программном обеспечении, у вас есть два варианта. Самый простой вариант — реализовать подклассы, которые дополняют базовый класс. Но это может быть запутанным. В качестве альтернативы вы можете использовать сущность-декоратор в соответствии с так называемым паттерном проектирования декоратора. Этот паттерн, который является одним из 23 паттернов проектирования GoF, позволяет динамически расширять классы во время работы программы. Он работает без бесконечно длинных, сложных для понимания иерархий наследования.

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

Что такое паттерн декоратора?

Паттерн проектирования декораторов (сокращенно паттерн декораторов) — это стратегия проектирования, разработанная в 1994 году для расширения функциональности классов в объектно-ориентированном программном обеспечении. Согласно паттерну, любой объект может быть расширен желаемым поведением без влияния на функциональность других объектов тех же классов. Структурно паттерн декоратора напоминает паттерн «цепочка ответственности». Но в отличие от паттерна «цепочка ответственности», запросы поступают ко всем классам через центральный процессор.

Программный компонент, который должен быть расширен, «декорируется» в соответствии с паттерном проектирования декоратора. Один или несколько классов-декораторов полностью окружают компонент. Каждый декоратор имеет тот же тип, что и вложенный компонент, и, следовательно, имеет тот же интерфейс. Таким образом, входящие вызовы методов могут быть легко делегированы на связанный компонент во время выполнения функциональности. Вызовы также могут быть обработаны непосредственно в декораторе.

Какова цель паттерна проектирования декоратора?

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

Примечание

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

Паттерн декоратора: UML-диаграмма для визуализации

Декоратор или класс-декоратор (ConcreteDecorator) имеет тот же интерфейс, что и декорируемый программный компонент (ConcreteComponent), и имеет тот же тип. Это необходимо для обработки вызовов, которые передаются либо без изменений, либо с изменениями, если декоратор их не обрабатывает. Концептуально паттерн декоратора определяет элементарный интерфейс — который, по сути, является абстрактным суперклассом — как «компонент».

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

Преимущества и недостатки паттерна декоратора

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

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

Однако разработка с использованием паттерна декоратора имеет некоторые недостатки. Использование паттерна увеличивает сложность программного обеспечения. В частности, интерфейс декоратора обычно содержит много кода и часто связан с большим количеством терминов, что делает его далеко не дружественным для новичков. Другим недостатком является большое количество объектов-декораторов, для которых рекомендуется отдельная систематизация, чтобы избежать аналогичных проблем с обзором при работе с подклассами. Длинные цепочки вызовов декорированных объектов (т.е. расширенных программных компонентов) затрудняют выявление ошибок и отладку в целом.

Преимущества Недостатки
Высокая степень гибкости Высокая сложность программного обеспечения (особенно интерфейса декоратора)
Расширение функций классов без наследования Не дружелюбен к новичкам
Нечитаемый программный код Большое количество объектов
Оптимизированные по ресурсам функциональные возможности Сложный процесс отладки

Паттерн проектирования декоратора: типичные примеры использования

Паттерн декоратор обеспечивает основу для динамических и прозрачных расширяемых объектов программного обеспечения. Компоненты графических пользовательских интерфейсов (GUI) являются распространенной областью применения паттерна. Например, если текстовое поле должно быть обрамлено, декоратор может быть добавлен «незаметно» между объектом текстового поля и вызовом для вставки нового элемента интерфейса.

Известным примером реализации паттерна проектирования декоратора являются так называемые потоковые классы библиотеки Java, которые отвечают за обработку ввода и вывода данных. Здесь классы-декораторы используются для добавления новых свойств и информации о состоянии потока данных или для предоставления новых интерфейсов.

Но Java — не единственный язык программирования, широко использующий паттерны декораторов. Следующие языки программирования также полагаются на этот паттерн проектирования:

  • C++
  • C#
  • Go
  • JavaScript
  • Python
  • PHP

Практические примеры реализации паттерна декоратор

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

В данном случае отправной точкой является программное обеспечение, которое делает имена людей доступными через абстрактный класс «Сотрудники». Однако первая буква извлекаемых имен всегда строчная. Поскольку последующая корректировка невозможна, реализуется класс-декоратор «EmployeeDecorator», который работает через тот же интерфейс и также позволяет вызывать метод getName(). Кроме того, декоратор получает логику, обеспечивающую правильное написание первой буквы заглавными буквами. Соответствующий пример кода выглядит следующим образом:

public class EmployeeDecorator implements Person {
private Employee employee;
public Employee Decorator(Employee employee){
	this.employee = employee;
}
public String getName(){
	// call the method of employee class 
	String name = employee.getName();
	// Ensure first letter is capitalized
	name = Character.toUpperCase(name.charAt(0)) 
	+ name.substring(1, name.length());
	return name;
}
}

Оцените статью
cdelat.ru
Добавить комментарий