一 简介
装修者形式(decorator pattern
): 归于结构型规划形式。动态地将职责附加到目标上, 若要扩展功用, 装修者供给了比承继更有弹性的替代计划。
二 目的
为目标动态增加功用: 允许你经过将目标放入包含行为的特别封装目标中来为原目标绑定新的行为。
三 结构
装修者(Decorator
)和详细组件(ConcreteComponent
)都完成了接口组件(Component
),详细组件的办法完成不需要依赖于其它目标,而装修者聚合了一个组件,这样它能够装修其它装修者或许详细组件。所谓装修,便是把这个装修者套在被装修者之上,然后动态扩展被装修者的功用。装修者的办法有一部分是自己的,这归于它的功用,然后调用被装修者的办法完成,然后也保留了被装修者的功用。能够看到,详细组件应当是装修层次的最低层,由于只要详细组件的办法完成不需要依赖于其它目标。
Component:组件声明封装器和被封装目标的公用接口。
ConcreteComponent:详细组件是被封装目标所属的类。它定义了基础行为,但装修类能够改变这些行为。
Decorator:装修者基类拥有一个指向被封装目标的引证成员变量。该变量的类型应当被声明为通用部件接口,这样它就能够引证详细的部件和装修。装修基类会将一切操作委派给被封装的目标。
ConcreteDecorator(A B…):详细装修类定义了可动态增加到组件的额定行为。详细装修类会重写装修基类的办法,并在调用父类办法之前或之后进行额定的行为。
四 代码完成
规划不同种类的饮料,饮料能够增加配料,比方能够增加牛奶,而且支持动态增加新配料。每增加一种配料,该饮料的价格就会增加,要求核算一种饮料的价格。
组件:Component
public interface Beverage {
double cost();
}
详细组件:ConcreteComponent
public class DarkRoast implements Beverage {
@Override
public double cost() {
return 1;
}
}
装修者基类:Decorator
public abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
}
详细装修类:ConcreteDecorator(A B…)
public class Milk extends CondimentDecorator {
public Milk(Beverage beverage) {
this.beverage = beverage;
}
@Override
public double cost() {
return 1 + beverage.cost();
}
}
public class Mocha extends CondimentDecorator {
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public double cost() {
return 1 + beverage.cost();
}
}
客户类调用:
public class Client {
public static void main(String[] args) {
Beverage beverage = new DarkRoast();
beverage =new Mocha(beverage);
beverage =new Milk(beverage);
System.out.println(beverage.cost());
}
}
五 总结
长处
- 无需创立新子类即可扩展目标的行为。
- 能够在运行时增加或删除目标的功用。
- 能够用多个装修封装目标来组合几种行为。
- 单一职责原则。能够将完成了许多不同行为的一个大类拆分为多个较小的类。
缺点
- 在封装器栈中删除特定封装器比较困难。
- 完成行为不受装修栈顺序影响的装修比较困难。
- 各层的初始化装备代码看上去可能会很糟糕。
运用场景
- 假如期望在无需修正代码的情况下即可运用目标,且期望在运行时为目标新增额定的行为,能够运用装修者形式。
- 假如用承继来扩展目标行为的计划难以完成或许根本不可行(比方:运用
final
润饰的某个类),能够运用该形式。