首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

装饰器(Decorator)方式

2013-11-08 
装饰器(Decorator)模式????? 装饰器模式又名包装器(Wrapper)模式。装饰器模式以对客户端透明的方式扩展对象

装饰器(Decorator)模式

????? 装饰器模式又名包装器(Wrapper)模式。装饰器模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。


模式类图


装饰器模式的类图如附件图1所示.
?
?? ?在装饰器模式中的各个角色有: 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

??? 具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。??? 装饰器(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。??? 具体装饰(Decorator)角色:负责给构件对象贴上附加的责任。

?


对象图


?? ?装饰器模式的对象图呈链状结构,其共有三个具体装饰器类,分别称为Decorator1、Decorator2和Decorator3,具体构架类是ConcreteComponent。一个典型的创建过程如代码所示:

new Decorator1(    new Decorator2(        new Decorator3(            new ConcreterComponent()        )    ));
?


?
?? ?这意味着Decorator1的对象持有一个Decorator2对象的引用,后者则持有一个对Decorator3对象的引用,再后者持有一个对具体构件ConcreteComponent对象的引用。
?? ?装饰器模式常常被称作包裹模式,就是因为每一个具体装饰器类都将下一个具体装饰器类或者具体构件类包裹起来。仍然以上面的情况为例,Decorator1对象包裹了Decorator2对象,后者包裹了Decorator3对象,再后者又包裹了ConcreteComponent对象。每一层包裹都提供了一些新的功能,如下附件图2所示.
?
装饰器模式应当在什么情况下使用


在以下情况下应当使用装饰器模式:
(1)?? ?需要扩展一个类的功能,或给一个类增加附加责任。
(2)?? ?需要动态地给一个对象增加功能,这些功能可以再动态的撤销。
(3)?? ?需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

?


使用装饰器模式的优点和缺点


?? ?使用装饰器模式主要有以下的优点:
(1)?? ?装饰器模式与继承关系的目的都是要扩展对象的功能,但是装饰器模式可以提供比继承更多的灵活性。
装饰器模式允许系统动态的决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。
(2)?? ?通过使用不同的具体装饰器类以及这些装饰器类的排列组合,设计师可以创造出很多不同行为的组合。
(3)?? ?这种比继承更加灵活机动的特性,也同时意味着装饰器模式比继承更加易于出错。
使用装饰器模式主要有以下的缺点:
由于使用装饰器模式,可以比使用继承关系需要较少数据的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰器模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很像。

?


模式的简化

?


?? ?大多数情况下,装饰器模式的实现都比上面的示意性实现要简单。对模式进行简化时需要注意以下的情况:
(1)?? ?一个装饰器类的接口必须与被装饰器类的接口相容。
ConcreteDecorator类必须继承自一个共同的父类Component。但是在实际使用时,如果在模式上所有所简化,就必须特别注意这一点。
(2)?? ?尽量保持Component作为一个“轻”类。
这个类的责任是为各个ConcreteDecorator类提供共同的接口,因此它应当着重在提供接口而不是存储数据。在实际工作中,它可以是一个抽象类或者一个具体类。此时,就应当主要不要把太多的逻辑和状态放在Component类里。
(3)?? ?如果只有一个ConcreteComponent类而没有抽象的Component类(接口),那么Decorator类经常可以是ConcreteComponent的一个子类,如附件图3所示.
?
(4)?? ?如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。甚至在只有两个ConcreteDecorator类的情况下,都可以这样做。但是如果ConcreteDecorator类的数目大于三的话,使用一个单独的Decorator类来区分抽象和具体的责任就是必要的了,如附件图4所示.

热点排行