1.意图:动态地给一个对象添加一些额外的职责。就增加功能而言,Decorator模式比生成子类更加灵活。
2.结构
Component定义一个对象接口,可以给这些对象动态地添加职责;
ConcreteComponent定义一个对象,可以给这个对象添加一些职责;
Decorator维持一个指向Component对象的指针,并定义一个于Component接口一致的接口;
ConcreteDecorator向组件添加职责。
3.适用性:
在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责;
处理那些可以撤销的职责;
当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是,由于类定义被隐藏,或类定义不能用于生成子类。
代码案例:
某发票Invoice由抬头Head部分、正文部分和脚注Foot部分构成。现采用装饰Decorator模式实现打印发票的功能。
软件设计师考试2016年下半年下午题第6题
/**
* 装饰模式
*/
class Invoice{
public void printInvoice(){
System.out.println("This is the content of the invoice!");
}
}
class Decorator extends Invoice{
protected Invoice ticket;
public Decorator (Invoice t){
ticket = t;
}
public void printInvoice(){
if(ticket!=null) {
ticket.printInvoice();
}
}
}
class HeadDecorator extends Decorator{
public HeadDecorator(Invoice t) {
super(t);
}
public void printInvoice(){
System.out.println("This is the header of the invoice!");
super.printInvoice();
}
}
class FootDecorator extends Decorator{
public FootDecorator(Invoice t) {
super(t);
}
public void printInvoice(){
super.printInvoice();
System.out.println("This is the foot of the invoice!");
}
}
class Test{
public static void main(String[] args) {
Invoice t = new Invoice();
Invoice ticket;
ticket = new HeadDecorator(new FootDecorator(t));
ticket.printInvoice();
System.out.println("--------------------");
ticket = new HeadDecorator(new FootDecorator(null));
ticket.printInvoice();
}
}
运行结果: