设计模式学习之装饰者模式

来源:互联网 发布:淘宝店铺优惠券名称 编辑:程序博客网 时间:2024/05/29 08:06

设计模式学习之——装饰者模式

  • 装饰者模式定义
    装饰者模式动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
    通常,装饰者和被装饰者对象有相同的超类型对象,可以用一个或者多个装饰者包装对象,装饰者可以在所委托被装饰者的行为之前/或之后,加上自己的行为,以达到特定目的,对象可以在任何时候被装饰,所以可以在运行时动态的、不限量的用你喜欢的装饰者模式来装饰对象。
    相同的超类型对象为组件(Componet),每个组件都可以单独使用,或者被装饰者包起来使用。ConcreteComponet是我们将要动态加上新行为的对象,它扩展自Component。
    Decotator是装饰者共同实现的接口或者基类,同样扩展自Component,但只是为了保持和被装饰者相同的超类类型,每个装饰者都有一个组件,即装饰者有一个实例变量保存某个Component的引用。
    ConcreteDecorator是一个具体的装饰者类,包含一个Component实例,装饰者可以扩展Component的状态,一般新的行为通过在旧行为的前面或者后面添加一些操作。

  • 模式实例
    Componenet{
    methodA();
    methodB();
    }
    ConcreteComponent extends Component{
    methodA(){…};
    methodB(){…};
    }
    Decorator extends Component{
    methodA();
    methodB();
    }
    ConcreteDecorator{
    Component wrapObj;
    methodA(){
    方法前操作………..
    wrapObj.methodA();
    方法后操作………..
    }
    methodB(){
    方法前操作………..
    wrapObj.methodB();
    方法后操作………..
    }
    }

  • 装饰者模式特点
    装饰者可以在不改变原始代码的情况下扩展我们的行为。
    装饰者模式意味着一群装饰者类,这些类用来包装具体组件,装饰者类反应出被装饰的组件类型(事实上,他们具有相同的类型,都经过接口或继承实现)。
    装饰者可以在被装饰着行为前后加上自己的行为,甚至将装饰者的行为整个取代掉,而达到特定的目的。
    可以用多个装饰者包装一个组件,装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。
    当然装饰者也有一个明显的缺点,会导致设计中出现许多小对象,而且对于API程序员会造成一些使用困惑(正如初识java的众多io类时),所以过度的使用装饰者会使程序变得复杂。

-装饰者在java内置API的使用
典型的例子就是io包下的众多流对象,初始的抽象组件类为InputStream(在此仅以输出流举例),FileInputStream、StringBufferInputStream、ByteArrayInputStream等为组件的具体实现类(即被装饰者)。FilterInputStream是一个抽象的装饰者,它们都实现了对InputStream组件的扩展,以保持相同的超类类型,PushBackInputStream、BufferedInputStream、DataInputStream、LineNumberInputStream为实现了FilterInputStream的具体装饰者。
但是,java I/O也引出了装饰者模式的一个缺点:利用装饰者模式,常常造成设计中有大量的小类,这着实会对使用此API的程序员造成困扰,只有当你了解了装饰者的工作原理时,你才能很容易的辨别出他们的转世者类是如何组织的。

  • 编程原则
    对扩展开放,对修改关闭,在开放-关闭的原则下,如理设计系统,让关闭的部分和新扩展的部分隔离。