孙悟空有七十二般变化,他的每一种变化都给他带来一种附加本领。而不管孙悟空怎么变化在二郎神眼里,他永远是那只猢狲。
装饰器模式以对客户透明的方式动态的给一个对象附加上更多的责任。
在孙悟空的例子里,老孙变成的鱼儿相当于老孙的子类。
装饰模式的类图如下:
装饰模式的角色介绍:
抽象构件角色(ComponentDec):给出一个抽象接口,以规范准备接收附加责任的对象
具体构件(Concrete ComponentDec):定义一个将要接收附加责任的类
装饰角色(Decortor):持有一个构件对象的实例,并顶一个与抽象构件接口一致的接口
具体装饰(Concrete Decorator):负责给构件对象“贴上”附加的责任
public interface Component {
void simpleOperation();
}
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
super();
this.component = component;
}
public Decorator() {
super();
}
/**
* 商业方法,委派给构件
*/
public void simpleOperation() {
component.simpleOperation();
}
}
1、上面的修饰类中有一个私有的属性Component,其数据类型是构件类型
2、此装饰类实现了构件接口
3、接口的实现方法也值得注意,每一个实现的方法都委派给父类,当并不是单纯的委派,而是有功能的增强。
虽然Decorator类不是一个抽象类,但是由于他的功能是一个抽象角色,因此也常常称它为抽象修饰。
public class ConcreteComponent implements Component {
public ConcreteComponent() {
super();
}
/**
* 商业方法
*/
public void simpleOperation() {
}
}
public class ConcreteDecorator extends Decorator {
public void simpleOperation(){
super.simpleOperation();
}
}
齐天大圣的例子:
Component的角色便是大名鼎鼎的齐天大圣孙悟空扮演的;ConcreteComponent的角色属于大圣的本尊,就是猢狲本人;大圣的72变便是Decorator角色;而ConcreteDecorator便是花、鸟、鱼、虫等72般变化。
装饰模式应该在什么情况下使用?
1、需要扩展一个类的功能,或给一个类增加附加功能
2、需要动态的给一个对象增加功能,这些功能可以再动态的撤销
3、需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使得继承关系不现实
装饰模式的优缺点
优点:
1、与继承关系目的都是要扩展对象的功能,但装饰模式可以提供比继承更多的灵活性
装饰模式允许系统动态的决定贴上一个需要的装饰,或者除掉一个不需要的装饰。继承关系则不同,继承关系是静态的,他在系统运行前就已经决定了。
2、通过使用不同的具体修饰类及这些装饰类的排列组合,设计师可以创造出很多不同的行为组合。而继承没有这个关系优势。每一种不同的组合均需要事先通过子类继承的方式设计好。
3、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加容易出错
缺点
使用装饰模式会产生比使用继承关系更多的类。特别是这些类看上去都比较相近