博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Decorator——结构型模式
阅读量:2381 次
发布时间:2019-05-10

本文共 3340 字,大约阅读时间需要 11 分钟。

意图

动态地给一个对象添加一些额外的职责或者行为。就增加功能来说, Decorator模式相比生成子类更为灵活。

别名

包装器(Wrapper)

适用性

1)• 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

2)• 处理那些可以撤消的职责。

3)• 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。


结构

这里写图片描述

角色职能

抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这些对象动态地添加职责。

具体组件角色(ConcreteComponent) :被装饰者,定义一个将要被装饰增加功能的类。可以给这个类的对象添加一些职责

抽象装饰器(Decorator):维持一个指向构件Component对象的实例,并定义一个与抽象组件角色Component接口一致的接口

具体装饰器角色(ConcreteDecorator):向组件添加职责。

协作

Decorator讲请求转发给他的Component对象,并可能在转发前后执行一些附加动作。

效果

1) 比静态继承更灵活 与对象的静态继承(多重继承)相比, Decorator模式提供了更加灵活的向对象添加职责的方式。可以用添加和分离的方法,用装饰在运行时刻增加和删除职责。相比之下,继承机制要求为每个添加的职责创建一个新的子类。这会产生许多新的类,并且会增加系统的复杂度。此外,为一个特定的Component类提供多个不同的 Decorator类,这就使得你可以对一些职责进行混合和匹配。使用Decorator模式可以很容易地重复添加一个特性。

2) 避免在层次结构高层的类有太多的特征 Decorator模式提供了一种“即用即付”的方法来添加职责。它并不试图在一个复杂的可定制的类中支持所有可预见的特征,相反,你可以定义一个简单的类,并且用 Decorator类给它逐渐地添加功能。可以从简单的部件组合出复杂的功能。这样,应用程序不必为不需要的特征付出代价。同时更易于不依赖于 Decorator所扩展(甚至是不可预知的扩展)的类而独立地定义新类型的 Decorator。扩展一个复杂类的时候,很可能会暴露与添加的职责无关的细节。

3) Decorator与它的Component不一样 Decorator是一个透明的包装。如果我们从对象标识的观点出发,一个被装饰了的组件与这个组件是有差别的,因此,使用装饰不应该依赖对象标识。

4) 有许多小对象 采用Decorator模式进行系统设计往往会产生许多看上去类似的小对象,这些对象仅仅在他们相互连接的方式上有所不同,而不是它们的类或是它们的属性值有所不同。尽管对于那些了解这些系统的人来说,很容易对它们进行定制,但是很难学习这些系统,排错也很困难。


实现

public abstract class Component {
/** * 示例方法 */ public abstract void operation(); } public class ConcreteComponent extends Component {
public void operation() { //相应的功能处理 } } public abstract class Decorator extends Component {
/** * 持有组件对象 */ protected Component component; /** * 构造方法,传入组件对象 * @param component 组件对象 */ public Decorator(Component component) { this.component = component; } public void operation() { //转发请求给组件对象,可以在转发前后执行一些附加动作 component.operation(); } } public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) { super(component); } private void operationFirst(){ } //在调用父类的operation方法之前需要执行的操作 private void operationLast(){ } //在调用父类的operation方法之后需要执行的操作 public void operation() { //调用父类的方法,可以在调用前后执行一些附加动作 operationFirst(); //添加的功能 super.operation(); //这里可以选择性的调用父类的方法,如果不调用则相当于完全改写了方法,实现了新的功能 operationLast(); //添加的功能 } } public class Client{
public static void main(String[] args){ Component c1 = new ConcreteComponent (); //首先创建需要被装饰的原始对象(即要被装饰的对象) Decorator decoratorA = new ConcreteDecoratorA(c1); //给对象透明的增加功能A并调用 decoratorA .operation(); Decorator decoratorB = new ConcreteDecoratorB(c1); //给对象透明的增加功能B并调用 decoratorB .operation(); Decorator decoratorBandA = new ConcreteDecoratorB(decoratorA);//装饰器也可以装饰具体的装饰对象,此时相当于给对象在增加A的功能基础上在添加功能B decoratorBandA.operation(); } }

装饰器模式与其他相关模式

1)Adapter 模式:Decorator模式不同于Adapter模式,因为装饰仅改变对象的职责而不改变它的接口;而适配器将给对象一个全新的接口。

2)Composite模式:可以将装饰视为一个退化的、仅有一个组件的组合。然而,装饰仅给对象添加一些额外的职责—它的目的不在于对象聚集。

3)Strategy模式:用一个装饰你可以改变对象的外表;而Strategy模式使得你可以改变对象的内核。这是改变对象的两种途径。

总结

1)使用装饰器设计模式设计类的目标是: 不必重写任何已有的功能性代码,而是对某个基于对象应用增量变化。

2) 装饰器设计模式采用这样的构建方式: 在主代码流中应该能够直接插入一个或多个更改或“装饰”目标对象的装饰器,同时不影响其他代码流。

3) Decorator模式采用对象组合而非继承的手法,实现了在运行时动态的扩展对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。同时它很好地符合面向对象设计原则中“优先使用对象组合而非继承”和“开放-封闭”原则。

你可能感兴趣的文章
以大数据视角 看住房信息普查
查看>>
宁家骏:大数据比云计算更为落地
查看>>
IBM PureData:破解大数据的利器
查看>>
实施大数据项目时所需要做的三件事
查看>>
北京开放政府信息资源 “大数据”供社会化利用
查看>>
互联网大会:大数据驱动的智能创新
查看>>
评论:大数据是否仅仅只是炒作?
查看>>
让大数据成为政务信息化的战略资源
查看>>
大数据时代企业须把握三个变化
查看>>
华为发布敏捷交换机备战大数据
查看>>
大数据挖掘变革 美赛达软硬云引领车联网商业蓝海
查看>>
大数据市场火爆 互联网思维激发运营商潜能
查看>>
赵先德:不提倡每个人都分析大数据
查看>>
大数据潮起 三领域争抢蛋糕
查看>>
百度助力中小企搜赢大数据
查看>>
大数据风云再起 二线龙头接棒大涨
查看>>
大数据核心就是要预测未来趋势
查看>>
风投掘金可穿戴设备:大数据才是背后真金
查看>>
搞互联网金融的,少点大数据忽悠吧!
查看>>
检测食品质量,看大数据分析
查看>>