介绍
定义
在不改变现有对象结构的情况系,动态的给该对象增加一些职责的模式,属于对象结构型模式。
又名包装模式,装饰模式(Decorator)以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
大多数的装饰模式的是实现是半透明的,即允许装饰模式改变接口,增加新的方法,半透明的装饰模式是介于装饰模式和适配器模式之间的。可以叫半装饰模式、半适配器模式。完全透明的只适配接口不增加功能。(装饰器模式在Java中的应用是Java I/O的设计,Output/Input-Reader/Writer)
适用情况
需要动态地给一个对象添加一些额外的功能。装饰器模式下比生成子类更灵活,在不改变接口的前提下增加目标类的性能。
- 需要扩展一个类的功能,或给一个类增加附加功能。
- 需要动态给一个对象增加、撤销功能。
- 需要增加一些基本功能的列表组合(配对)而产生的非常大量的功能,从而不能使用继承。
角色
- 抽象构件角色:一个抽象接口,用于定义具体构件和装饰器的统一接口。
- 具体构件角色:实现抽象构件角色接口。定义一个将要被“贴”上附加功能的类。
- 抽象装饰角色:持有一个具体构件角色对象,实现抽象构件角色接口。虽然说它是抽象的,实际上是个实体类,不是抽象的。
- 具体装饰角色:继承装饰角色,负责给构件对象“贴”上附加责任。
特点:构件角色的接口和装饰器角色的接口完全一致(是同一个)。这个目的是实现装饰者和具体构件的方法一致。
实现
抽象构件角色
public interface IMember {
public void getF();
}
具体构件角色
public class MemberA implements IMember {
@Override
public void getF() {
System.out.println("MemberA getF");
}
}
public class MemberB implements IMember {
@Override
public void getF() {
System.out.println("MemberB getF");
}
}
抽象装饰角色
public class Decorator implements IMember {
private IMember member = null;
public Decorator(IMember member) {
this.member = member;
}
@Override
public void getF() {
member.getF();
}
}
具体装饰角色
public class DecortorA extends Decorator {
public DecortorA(IMember member) {
super(member);
// TODO Auto-generated constructor stub
}
@Override
public void getF() {
super.getF();
//这里还可以进行其他操作
System.out.println("DecortorA getF");
}
//这里也可以加功能
}
public class DecortorB extends Decorator {
public DecortorB(IMember member) {
super(member);
// TODO Auto-generated constructor stub
}
@Override
public void getF() {
//这里还可以进行其他操作
super.getF();
System.out.println("DecortorB getF");
}
//这里也可以加功能
}
使用
IMember member1 = new MemberA();
IMember decor = new DecortorA(member1);
decor.getF();
System.out.println("_____________");
IMember member2 = new MemberB();
IMember decor2 = new DecortorB(member2);
decor2.getF();
System.out.println("_____________");
IMember decor3 = new DecortorA(member2);
decor3.getF();
System.out.println("_____________");
IMember decor4 = new DecortorB(member1);
decor4.getF();
/*
DecortorA getF
MemberA getF
_____________
DecortorB getF
MemberB getF
_____________
DecortorA getF
MemberB getF
_____________
DecortorB getF
MemberA getF
*/
注意:这里在new的时候需要使用依赖倒置原则。
扩展
简化情况1:四个角色不是一定存在,当没有抽象构件的时候,抽象装饰角色可以继承具体构件,其他不变。
简化情况2:最简单的情况还可以是只有一个抽象构件、一个具体构件、一个具体装饰角色(实现抽象构件接口,并持有一个具体构件)。
优点
- 继承是静态的,装饰器可更灵活选择要对谁进行装饰。
- 可以进行功能的组合。
缺点
- 比继承产生更多的对象,理解起来困难一些。
参考文档: