装饰器模式
- 何时使用:保持接口,增强性能。为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀,在不想增加很多子类的情况下扩展类,动态地给一个对象添加一些额外的职责,可以使用装饰器模式。特点:不改变原类文件、不使用继承、动态扩展。
- 如何解决:将具体功能职责划分,同时地继承装饰者模式。 1、Component 类充当抽象角色(被修饰类的抽象父类,为了易于扩展,不应该具体实现)。 2、修饰类继承Component抽象类和引用Component抽象类的实现类,具体扩展类重写父类(Component类)方法。引用:从引用的Component实现类对象中获得Component实现类(被修饰类)的方法;继承:在父类(Component抽象类)的接口下重写扩展新的修饰功能。总结:修饰类继承被修饰对象的抽象父类,依赖被修饰对象的实例(被修饰对象依赖注入),以实现接口扩展。
- 优点:1、装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。2、就增加功能来说,装饰器模式相比生成子类更为灵活。允许向一个现有的对象添加新的功能,同时又不改变其结构
- 缺点:多层装饰比较复杂。
- 使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。3、可代替继承。
典型框架
这个类图只是装饰器模式的完整结构,但其实里面有很多可以变化的地方,如:
1,Component接口可以是接口也可以是抽象类,甚至是一个普通的父类(这个强烈不推荐,普通的类作为继承体系的超级父类不易于维护)。
2,装饰器的抽象父类Decorator并不是必须的。
待装饰的接口Component:
public interface Component{
void method();
}
待装饰类:
publicclassConcreteComponent implements Component{
publicvoid method(){
System.out.println("原来的方法");
}
}
抽象装饰器父类,它主要是为装饰器定义我们需要装饰的目标是什么,并对Component进行了基础的装饰:
public abstract classDecorator implements Component{
protectedComponent component;
publicDecorator(Component component){
super();
this.component = component;
}
publicvoid method(){
component.method();
}
}
具体的装饰器A和装饰器B:
publicclassConcreteDecoratorA extends Decorator{
publicConcreteDecoratorA(Component component){
super(component);
}
publicvoid methodA(){
System.out.println("被装饰器A扩展的功能");
}
publicvoid method(){
System.out.println("针对该方法加一层A包装");
super.method();
System.out.println("A包装结束");
}
}
publicclassConcreteDecoratorB extends Decorator{
publicConcreteDecoratorB(Component component){
super(component);
}
publicvoid methodB(){
System.out.println("被装饰器B扩展的功能");
}
publicvoid method(){
System.out.println("针对该方法加一层B包装");
super.method();
System.out.println("B包装结束");
}
}
publicclassMain{
publicstaticvoid main(String[] args){
Component component =newConcreteComponent(); //原来的对象
component.method(); //原来的方法
ConcreteDecoratorA concreteDecoratorA =newConcreteDecoratorA(component); //装饰成A
concreteDecoratorA.method(); //原来的方法
concreteDecoratorA.methodA(); //装饰成A以后新增的方法
ConcreteDecoratorB concreteDecoratorB =newConcreteDecoratorB(concreteDecoratorA);//装饰成A以后再装饰成B
concreteDecoratorB.method(); //原来的方法
concreteDecoratorB.methodB(); //装饰成B以后新增的方法
}
}
JAVA IO中的装饰器模式
参考文章:
http://chenhua-1984.iteye.com/blog/565629 (层层修饰的装饰器模式)