装饰模式:
装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
装饰模式以对客户端透明的方式拓展对象的功能,是继承关系的一个替代方案。装饰模式以透明的方式动态的给一个对象附加上更多的责任。
简易类图:
结构:
装饰模式实用原来的被装饰的类的一个子类实例,把客户端的调用委派给被装饰类。
类图:
抽象构件角色(Component):给出一个对象的接口,以规范接收附加责任的对象。
具体构件角色(Concreate Component):定义将要接收附加责任的类。
装饰角色(Decorator):持有构件对象(Component)的实例,并定义一个与抽象构件接口一致的接口。
具体装饰角色(Concreate Decorator):负责给构件对象“贴上”附加责任。
代码:
interface Component{
void operation();
}
class Decorator implements Component{
private Component component;
public Decorator() {
}
public Decorator(Component component) {
this.component = component;
}
public void operation() {
System.out.println("方法增强...");
component.operation();
}
}
class ConcreateComponent implements Component{
public ConcreateComponent() {
}
public void operation() {
System.out.println("do operation...");
}
}
class ConcreateDecorator extends Decorator{
public void operation() {
super.operation();
}
}
装饰角色(Decorator)每一个实现方法都委派给组合的Component完成,但并不是简单的委派,而是功能的增强。Decorator可是为抽象类。
什么时候用装饰模式?
1)需要拓展一个类的功能或给类增加附加责任。
2)需要动态的给一个对象增加功能,这些功能可以动态撤销。
3)需要增加一些基本功能的排列组合而产生大量的功能(多个装饰类组合),从而使得继承关系变得不现实。
装饰模式的优缺点:
优点:
1)装饰模式和继承关系的目的都是拓展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态的决定“贴上”一个需要的“装饰”,或者出掉一个不需要的“装饰”,继承关系不同,继承是静态的,它在系统运行前就决定了。
2)通过使用不同具体的装饰类以及这些装饰类的组合,可以创造出很多不同行为的组合。
3)比继承更多的灵活性,每一种不同的组合均需要事先通过子类的继承方式设计好。
缺点:
会产生比继承关系更多的对象。使得查错变得困难,特别是这些对象看上去都很相像。
参考:
《Java与模式》