装饰(Decorator)模式又名包装(Wrapper)模式[GOF95]。装饰者模式动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。该模式以对客户端透明的方式扩展对象的功能。利用组合在运行时动态的合成自己想要的对象,这比继承更具弹性,是继承关系的一个替代方案。
涉及角色
(1)抽象构件角色:定义一个抽象接口,来规范准备附加功能的类。
(2)具体构件角色(即被装饰者):将要被附加功能的类,实现抽象构件角色接口。
(3)抽象装饰者角色:持有对具体构件角色的引用并定义与抽象构件角色一致的接口。
(4)具体装饰角色:实现抽象装饰者角色,负责为具体构件添加额外功能。
其中,被装饰者与抽象装饰者都继承与抽象构件角色,具体装饰角色继承与抽象装饰角色,之所以让装饰者和被装饰者继承于同一组件是想让装饰者和被装饰者具有统一的类型而非为了继承行为。
装饰者模式的基本思想是用装饰者来包装组件使之成为一个同类型的新组件,所以在装饰者角色中,记录当前对象(一般是声明一个基类引用变量,构造器中传对象引用参数初始化此变量),利用多态技术,用基类对象引用最终被包裹后的对象(注意:每包裹一层就把之前的对象覆盖掉),就获得了组件和所有包裹过组件的行为。
使用装饰模式主要有以下的优点:
使用装饰模式主要有以下的缺点:
由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。
大多数情况下,装饰模式的实现都比上面定义中给出的示意性实现要简单。对模式进行简化时需要注意以下的情况:
(1)一个装饰类的接口必须与被装饰类的接口相容。
(2)尽量保持Component作为一个"轻"类,不要把太多的逻辑和状态放在Component类里。
(3)如果只有一个ConcreteComponent类而没有抽象的Component类(接口),那么Decorator类经常可以是ConcreteComponent的一个子类。如下图所示:
(4)如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。java.io.InputStream
, OutputStream
, Reader
and Writer
have
a constructor taking an instance of same type.java.util.Collections
,
the checkedXXX()
, synchronizedXXX()
and unmodifiableXXX()
methods.javax.servlet.http.HttpServletRequestWrapper
and HttpServletResponseWrapper
装饰者模式(Decorator Pattern),布布扣,bubuko.com
原文地址:http://www.cnblogs.com/hujihon/p/3730213.html