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