装饰者模式

原创 2012年03月28日 20:14:52
         装饰者模式动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

特点:

①装饰者和被装饰着具有相同的超类型;所以在任何需要原始对象(被包装)的场合,都可以用装饰过的对象来代替他;

②可以有一个或者多个装饰者包装一个对象;

③装饰者可以在所委托被装饰者的行为之前或者之后加上自己的行为,以达到特定的目的;即对象可以在任何时候被装饰,所以可以在运行时动态地、不限量第用你喜欢的装饰者来装饰对象。

优缺点

      优点:1)提供比继承更多的灵活性 2)使用不同的装饰组合可以创造出不同行为的组合 3)需要的类的数目减少

      缺点:1)灵活性带来比较大的出错性 2)产生更多的对象,给查错带来困难

         下面引用这篇博客http://www.cnblogs.com/justinw/archive/2007/06/11/779356.html的理解。

Component(被装饰对象基类)

     定义对象的接口,可以给这些对象动态增加职责;

ConcreteComponent(具体被装饰对象)

     定义具体的对象,Decorator可以给它增加额外的职责;

Decorator(装饰者抽象类)

     维护一个指向Component实例的引用,并且定义了与Component一致的接口;

ConcreteDecorator(具体装饰者)

     具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责;

 

     Decorator是装饰者模式里非常特殊的一个类,它既继承于Component【IS A关系】,又维护一个指向Component实例的引用【HAS A关系】,换个角度来说,Decorator跟Component之间,既有动态组合关系又有静态继承关系, (动态和静态的问题,所谓动态是说可以在系统运行时(RunTime)动态给对象增加其它职责而不需要修改代码或重新编译;所谓静态是说必须通过调整代码(DesignTime)才能给对象增加职责,而且系统还需要重新编译;从具体技术层面来说,对象的组合和继承正好对应于前面的动态和静态,因为通过对象组合建立的交互关系不是在代码中(DesignTime)固定死的,而是在运行时(RunTime)动态组合的;而通过继承建立的关系是僵硬的难以改变的,因为它是在代码中(DesignTime)固定死了的,根本不存在运行时(RunTime)改变的可能。)    WHY? 这里为什么要这么来设计?上面我们说过,组合的好处是可以在运行时给对象增加职责,Decorator【HAS A】Component的目的是让ConcreteDecorator可以在运行时动态给ConcreteComponent增加职责,这一点相对来说还比较好理解;那么Decorator继承于Component的目的是什么?在这里,继承的目的只有一个,那就是可以统一装饰者和被装饰者的接口,换个角度来说,不管是ConcretComponent还是ConcreteDecorator,它们都是 Component,用户代码可以把它们统一看作Component来处理,这样带来的更深一层的好处就是,装饰者对象对被装饰者对象的功能职责扩展对用户代码来说是完全透明的,因为用户代码引用的都是Component,所以就不会因为被装饰者对象在被装饰后,引用它的用户代码发生错误,实际上不会有任何影响,因为装饰前后,用户代码引用的都是Component类型的对象,这真是太完美了!装饰者模式通过继承实现统一了装饰者和被装饰者的接口,通过组合获得了在运行时动态扩展被装饰者对象的能力。

抽象构件角色java 代码
package decorator;  
/** 
 * 装饰者和原组建的共同方法接口(抽象构件角色) 
 * @author mouca.he 
 * 
 */ 
public interface InterfaceComponent {  
   
    /** 
     * 组件方法 say() 
     * 
     */ 
    public void say();  
}  
具体构件角色java 代码
package decorator;  
/** 
 * 原组件(具体构件角色) 
 * @author mouca.he 
 * 
 */ 
public class Component implements InterfaceComponent{  
   
    public void say() {  
        // TODO 自动生成方法存根  
        System.out.println("Component.say():原组件的方法!");  
    }  
   
}  
抽象装饰者角色java 代码
package decorator;  
/** 
 * 抽象装饰者 
 * @author mouca.he 
 * 
 */ 
public abstract class AbstractDecorator implements InterfaceComponent{  
   
    private InterfaceComponent component;  
        
    public AbstractDecorator(InterfaceComponent component){  
        this.component = component;  
    }  
    /** 
     * 组件方法执行前预处理方法 
     * 
     */ 
    protected void preSay(){};  
        
    /** 
     * 组件方法执行后处理方法 
     * 
     */ 
    protected void afterSay(){};  
        
    public void say(){  
            
        preSay();  
        component.say();  
        afterSay();  
            
    };  
}  
具体装饰者二java 代码
package decorator;  
/** 
 * 装饰者二 
 * @author mouca.he 
 * 
 */ 
public class DecoratorTwo extends AbstractDecorator{  
   
    public DecoratorTwo(InterfaceComponent component) {  
        super(component);  
        // TODO 自动生成构造函数存根  
    }  
   
    /** 
     * 根据需要重载模板类preSay()方法 
     */ 
    protected void preSay(){  
        System.out.println("DecoratorTwo.preSay():装饰者二的preSay()方法!");  
    }  
        
    /** 
     * 根据需要重载模板类afterSay()方法 
     */ 
    protected void afterSay(){  
        System.out.println("DecoratorTwo.afterSay():装饰者二的afterSay()方法!");  
    }  
   
}  
装饰者一java 代码
package decorator;  
/** 
 * 装饰者一 
 * @author mouca.he 
 * 
 */ 
public class DecoratorOne extends AbstractDecorator{  
   
    public DecoratorOne(InterfaceComponent component) {  
        super(component);  
        // TODO 自动生成构造函数存根  
    }  
    /** 
     * 根据需要重载模板类preSay()方法 
     */ 
    protected void preSay(){  
        System.out.println("DecoratorOne.preSay():装饰者一的preSay()方法!");  
    }  
        
    /** 
     * 根据需要重载模板类afterSay()方法 
     */ 
    protected void afterSay(){  
        System.out.println("DecoratorOne.afterSay():装饰者一的afterSay()方法!");  
    }  
    /** 
     * 测试方法 
     * @param args 
     */ 
    public static void main(String[] args) {  
        // TODO 自动生成方法存根  
        InterfaceComponent interfaceComponent = new DecoratorTwo(new DecoratorOne(new Component()));  
        interfaceComponent.say();  
        /* 
         * 控制台输出: 
         * DecoratorTwo.preSay():装饰者二的preSay()方法! 
         * DecoratorOne.preSay():装饰者一的preSay()方法! 
         * Component.say():原组件的方法! 
         * DecoratorOne.afterSay():装饰者一的afterSay()方法! 
         * DecoratorTwo.afterSay():装饰者二的afterSay()方法! 
         */ 
    }  
}



相关文章推荐

装饰者模式Android实例

  • 2016年07月30日 09:58
  • 6.77MB
  • 下载

装饰者模式

  • 2014年06月09日 13:01
  • 5KB
  • 下载

JS—Decorator(装饰者)模式

http://taobaofed.org/blog/2015/11/16/es7-decorator/ 转载自淘宝前端团队 装饰模式是装饰模式,是通过封装其他对象达到设计的目的。 装饰模式不一样,仅仅...

装饰者模式 - PHP版

  • 2014年05月21日 09:45
  • 2KB
  • 下载

具有装饰者的模式照片

  • 2009年06月14日 00:46
  • 1.78MB
  • 下载

Javascript中的装饰者模式以及AOP简介

装饰者顾名思义就是起到装饰作用,装饰者模式就是可以动态给某个对象增加一些额外的行为,而不会影响从这个类中派生的其他对象。模拟传统面向对象语言的装饰者模式假设我们编写一个飞机大战的游戏,飞机的等级会随经...
  • mzzzzq
  • mzzzzq
  • 2016年04月11日 23:02
  • 500

装饰者模式案例学习代码

  • 2013年03月03日 01:07
  • 2KB
  • 下载

装饰者模式源代码java

  • 2014年01月18日 21:59
  • 3KB
  • 下载

装饰者模式-有层次地组织代码

代码组织的方式可以分为横向和纵向,横向指的是抽象与具体的关系(接口或抽象类与实际类的关系),这种方式能够让代码依赖于抽象的东西,更加灵活地扩展,体现了对于增加开放,对于修改关闭的程序设计原则。对于稍微...

设计模式-装饰者

  • 2015年11月07日 10:44
  • 4.44MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:装饰者模式
举报原因:
原因补充:

(最多只允许输入30个字)