现在的位置: 首页 > 研发管理 > 设计模式 > 正文

设计模式06_装饰者模式

2016年05月29日 设计模式 ⁄ 共 2350字 ⁄ 字号 暂无评论

          本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/51531519


1、定义

          动态将职责添加到对象身上。若要扩展功能,装饰者模式提供了比继承更加灵活的替代方案。(摘自Head First 中文版第91页)


2、说明

          通常情况下,在使用继承设计子类的行为,是在编译时静态决定的,所有的子类都会继承到相同的行为,这样会产生耦合较高。而利用组合来扩展对象的行为,就可以在运行时动态地进行扩展。装饰者模式是组合的一种表现,但是装饰者和被装饰者要有相同的超类。

         装饰者模式是针对抽象组件(Component)进行编程。如果要针对具体组件进行编程,需要重新思考应用架构,考虑装饰者模式是否合适。当然也可以改变Component接口,增加新的对象行为,实现“半透明”的装饰者模式,以便能够在实际项目中做出最佳选择。


3、角色

         抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任的对象。

         具体构件角色(Concrete Component):定义将要接收附加责任的类。

         装饰角色(Decorator):持有一个构件(Component)对象的引用,并定义一个与抽象构件接口一致的接口。

         具体装饰角色(Concrete Decorator):负责给构件对象“贴上”附加的责任


4、类图

这里写图片描述


5、示例

         抽象构件角色: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

6、总结

         适用性:需扩展一个类的功能,附加额外的职责。可以动态给对象添加功能,也可以动态撤销。

         优点:Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

         缺点:这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

         JDK源码中也有不少地方用到了装饰者模式。java io就是其中比较典型的范例。例如,InputStream–>FilterInputStream–>BufferedInputStream;其中FilterInputStream是装饰角色,而BufferedInputStream等是具体的装饰角色。

         本文只是简单介绍装饰者模式,并未对其进行深入探讨,略显粗糙。希望本文对你有所帮助。