本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/51531519
动态将职责添加到对象身上。若要扩展功能,装饰者模式提供了比继承更加灵活的替代方案。(摘自Head First 中文版第91页)
通常情况下,在使用继承设计子类的行为,是在编译时静态决定的,所有的子类都会继承到相同的行为,这样会产生耦合较高。而利用组合来扩展对象的行为,就可以在运行时动态地进行扩展。装饰者模式是组合的一种表现,但是装饰者和被装饰者要有相同的超类。
装饰者模式是针对抽象组件(Component)进行编程。如果要针对具体组件进行编程,需要重新思考应用架构,考虑装饰者模式是否合适。当然也可以改变Component接口,增加新的对象行为,实现“半透明”的装饰者模式,以便能够在实际项目中做出最佳选择。
抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件角色(Concrete Component):定义将要接收附加责任的类。
装饰角色(Decorator):持有一个构件(Component)对象的引用,并定义一个与抽象构件接口一致的接口。
具体装饰角色(Concrete Decorator):负责给构件对象“贴上”附加的责任
抽象构件角色:Componet
package headfirst.design.decorator;
public interface Componet {
public void method();
}
具体构件角色(待装饰者):ConcreateComponet
public class ConcreateComponet implements Componet {
@Override
public void method() {
System.err.println("I am a method");
}
}
装饰角色:Decorator
package headfirst.design.decorator;
public class Decorator implements Componet{
private Componet componet;
public Decorator(Componet cp){
this.componet = cp;
}
@Override
public void method() {
componet.method();
}
}
具体装饰角色:ConcreateDecotator
package headfirst.design.decorator;
public class ConcreateDecotator extends Decorator{
public ConcreateDecotator(Componet cp) {
super(cp);
}
public void method(){
//可在之前添加方法
addmethodbefore();
super.method();
//可在之后添加方法
addmethodafter();
}
private void addmethodafter() {
System.err.println("add method after");
}
private void addmethodbefore() {
System.err.println("add method before");
}
}
测试:Test
package headfirst.design.decorator;
public class Test {
public static void main(String[] args) {
Componet cp = new ConcreateComponet();
Decorator decorator = new ConcreateDecotator(cp);
decorator.method();
}
}
运行结果:
add method before I am a method add method after
适用性:需扩展一个类的功能,附加额外的职责。可以动态给对象添加功能,也可以动态撤销。
优点:Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
缺点:这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
JDK源码中也有不少地方用到了装饰者模式。java io就是其中比较典型的范例。例如,InputStream–>FilterInputStream–>BufferedInputStream;其中FilterInputStream是装饰角色,而BufferedInputStream等是具体的装饰角色。
本文只是简单介绍装饰者模式,并未对其进行深入探讨,略显粗糙。希望本文对你有所帮助。