什么是装饰模式?
在运行的过程中,给一个对象动态地添加一些额外的行为。每一个具体的装饰类都为被装饰类添加一个功能。
装饰模式的类图
1.需要被装饰的对象所在的类和装饰类都有一个共同的父类Component,该类中拥有需要添加额外功能的函数:operation();
class ConcreteComponent() extends Component{
public void operation(){
//本函数原本就要做的事情
}
}
2.ConcreteComponent是需要被装饰的类;Decorator是装饰类。
3.Decorator类中持有被装饰对象的引用,客户端通过setComponent(Component)设置;
4.Decorator类的operation()函数中,执行了被用户set进去的component对象中的operation()函数,也就是首先执行被装饰类原本的功能;
class Decorator() extends Component{//需要被装饰的对象private Component component;//提供给客户端将需要被装饰的对象设置进来public void setComponent(Component component){this.component = component;}//执行需要被装饰对象原本的operation函数public void operation(){this.component.operation();}}
Decorator的子类们的operation()函数,拥有被装饰类原本的功能和新需要增加的功能。
class ConcreteDecorator() extends Decorator{
//需要被装饰的对象
private Component component;
//提供给客户端将需要被装饰的对象设置进来
public void setComponent(Component component){
this.component = component;
}
//执行需要被装饰对象原本的operation函数+附加的功能
public void operation(){
//新的功能……………………
super.operation();
//新的功能……………………
}
}
客户端代码:
public static void main(String[] args) {
//创建一个需要被装饰的对象
ConcreteComponent concreteComponent = new ConcreteComponent();
//创建一系列修饰类的对象
Decorator decoratorA = new ConcreteDecoratorA();
Decorator decoratorB = new ConcreteDecoratorB();
//先使用ConcreteDecoratorA包装被装饰对象
decoratorA.setComponent(concreteComponent);
//再使用ConcreteDecoratorB包装decoratorA对象
decoratorB.setComponent(decoratorA);
}
此时,decoratorB对象就是原本需要被装饰的concreteComponent对象,只不过这个对象的operation()函数在原本operation()的基础上增加了ConcreteDecoratorA和ConcreteDecoratorB新的功能。
装饰模式和建造者模式的异同?
相同点:建造者模式和装饰模式都使用了面向切面编程的思想,装饰模式中的装饰类和建造者模式中建造者类的一个个函数都是为被装饰对象附加函数额外功能或为对象中的属性赋值。
不同点:建造者给对象添砖加瓦的顺序是固定的,在Director类中写好的;
而装饰模式中需要添加哪些操作是由客户端决定的。
建造者模式的详细介绍请移步至:https://cloud.tencent.com/developer/article/1055941
装饰模式的优点
装饰模式是为已有的功能动态添加更多功能的一种方式。
以往在设计程序的过程中,当系统需要新功能时,就在旧的类中添加新的代码。
但这种方式的问题在于,如果它们在类中添加了新的方法、新的字段、新的逻辑,就会增加主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才回执行的特殊行为的需要。
而装饰模式提供了一种非常好的解决方案,
它把每一个要额外添加的功能单独封装在一个个类中,并让这个类包装它所要装饰的对象。
因此,当一个类需要执行特殊行为时,客户端就可以在运行时有选择地添加所需要的附加功能。