намерение
Динамически добавлять дополнительные обязанности к объекту.С точки зрения добавления функциональности шаблон Decorator более гибок, чем генерация подклассов.
Псевдоним: Обертка
Рождение шаблона декоратора
Иногда мы хотим добавить некоторые функции к объекту, а не ко всему классу, например: набор инструментов GUI позволяет добавлять некоторые функции, такие как границы, к любому компоненту пользовательского интерфейса.
Использование наследования — эффективный способ добавления функциональности, но он недостаточно гибкий, поскольку выбор границ является статическим, и пользователь не может контролировать, как и когда обрамляется компонент. Более гибкий способ — встроить компонент в другой объект, который добавляет границу, мы называем это украшением встроенного объекта.
Речь это:
[Продукт]: Разработчик, у меня тут есть код. Вам нужно вызвать его функции и дополнить дополнительные функции компании, но вы не можете изменить его собственное содержание. Сможете ли вы это сделать?
【Развитие】: А? как это возможно! Как можно иметь другие функции без изменения кода и иметь дополнительные функции? Хочешь, чтобы я так написал?
void demo () {
// 调用原有代码功能
// do();
// 调用公司功能
// doMine();
}
【БОСС】: Низкий поклон! Вам не кажется, что это очень мало?
[В разработке]: Но как я могу переписать это, если я не напишу это так?
[БОСС]: Посмотрите внимательно на исходный код, все они реализуют один и тот же интерфейс, это точка прорыва
[Развитие]: Я собираюсь исследовать....
Основной код HeadFirst
Итак, мы начали путешествие с чтения классических книг о шаблонах проектирования.
/**
* 装饰器模式共同的接口
*/
public interface Component {
String getName();
double getSpend();
}
/**
* 原本的类
*/
public class ConcreteComponent implements Component {
private String name;
public ConcreteComponent(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public double getSpend() {
return 10;
}
}
/**
* 装饰器类 注意它利用了组合的方式,同时注意函数实现的部分
*/
public class MilkDecorator implements Component {
Component coffe;
MilkDecorator(Component coffe) {
this.coffe = coffe;
}
@Override
public String getName() {
return coffe.getName() + ", 牛奶";
}
@Override
public double getSpend() {
return coffe.getSpend() + 2D;
}
}
Идеи оформления узора декоратор:
- Компонент: определяет интерфейс объекта, унифицированное поведение и родителя.
- ConcreteComponent: определите объект, к которому вы можете добавить некоторые обязанности (методы)
- Декоратор (необязательно): определите интерфейс, совместимый с компонентом, и ограничьте обязанности (методы), которые необходимо реализовать.
- ConcreteDecorator: поддерживает указатель на объект Component и реализует интерфейс Component для улучшения поведения объекта.
Проще говоря,
- Нам нужен интерфейс для унификации родителя и реализации необходимого поведения.
- Класс реализации по умолчанию реализует связанные функции
- Если требуется дополнительная аугментация (украшение), реализуйте интерфейс и удерживайте указатель на объект интерфейса, вызовите метод объекта указателя при реализации метода интерфейса и улучшите
❝Если это выглядит немного двусмысленно, после прочтения этой статьи посетите проект с открытым исходным кодом по шаблонам тематического проектирования, в котором есть конкретные примеры кода, а ссылка находится внизу
❞
Принципы дизайна, которым нужно следовать
- "Открыт для расширения, закрыт для модификации": Отлично достигает цели усовершенствования метода без изменения его кода.
- "Программирование для интерфейса": декоратор имеет того же родителя, что и он сам
Какая сцена подходит для использования
Добавляйте обязанности к отдельным объектам динамично и прозрачно, не затрагивая другие объекты.
Код / практическое применение в жизни
Самое известное применение шаблона декоратора в Java — классы реализации различных InputStream, Reader и Writer в пакете java.io. Если мы хотим прочитать текстовое содержимое из файла, мы можем использовать FileReader (декоратор) и FileInputStream (декоратор);
Но если мы хотим сделать чтение быстрее, то нам нужен BufferedReader (декоратор), чего можно добиться изменением всего одной строчки кода
Наконец
"Прикрепите диаграмму UML для шаблона декоратора в книге GOF:"
Связанные ссылки на код
- С учетом случаев в двух классических данных "HeadFirst" и "GOF"
- Предоставляет дружественное руководство по чтению