设计模式(7)--Decorator 装饰模式

来源:互联网 发布:淘宝上充流量要验证码 编辑:程序博客网 时间:2024/05/04 04:01

装饰模式也是一种日常编码中经常会不自觉采用的设计模式。其核心理念是:一个类有自己的核心功能和职责,且这个类的代码相对已经固定,不希望改动维护。现在要为这个类加入一谢额外的功能,这些功能不是一定必须的,而且可能是动态添加的,根据实际要求加入某一种或几种。但是不管加入什么额外功能,客户眼中始终还是在操作这个核心功能类。这个时候,我们的处理方式就是,为每种动态的功能,单独的提供一个类,来完成对核心类的“装饰”。
这里写图片描述

装饰模式的要点:
1. 简单情况下,核心功能的Component类和装饰类,都可以不需要抽象成父类。但是,因为客户眼中始终还是在操作这个核心功能类(客户当然不应该在装饰后就拿到一个其它类型),所以装饰类需要继承组件类,在装饰后应依然以组件类形式返回给客户调用。
2. “继承的是类型,而不是行为”:继承组件接口,仅仅是为了让客户始终调用同一个类型。除此之外,装饰类还必须包含一个组件对象。这里也是一个用合成且不能用继承的例子。可以想想,假如有100个额外功能的排列组合,使用继承但不合成的话,那岂不是要出现100个排列组合的所有可能的子类?显然是不合适的,这也就是所说的“继承是静态的而非动态的”
3.多个装饰类的调用顺序应该按照实际的业务逻辑来进行,顺序错误是不可接受的。例如先穿衬衣再穿外套,在代码上会形成一条装饰器链。

下面是对装饰模式的一些讨论:

  1. 与Builder建造者模式的区别?
    Builder是为了提供一个对象,这个对象的创建过程复杂,但也是固定的,创建好了对象才能用。 而Decorator则是在获得对象后,去装配一些可有可无的额外功能,是动态的灵活的,这时候Builder那种固定的创建逻辑就不适用了。

  2. 与Bridge桥接模式的区别?
    桥接是因为一个产品的建立存在多个维度,每个维度有自己的一系列变化,我们必须把这些维度解耦出来,避免类的不断增加。所以桥接就是把产品拆分,然后通过合成聚合等方式组合起来。各自维护自己维度,并没有什么接口的继承关系在里头。

  3. 与Adapter适配器模式的区别?
    适配器,是为了将源对象改造成适合客户端使用的新的接口,接口已经改变了。而装饰模式,强调的是使用原接口。 其实,这两种模式很类似,也没有特别明确的界限。适配器是为了改变接口,但不在意改变功能。装饰器的目的在于改变(添加额外)功能,但不会去改变接口。实际中可能存在装饰器实现类中增加了额外的接口,而且核心组件Component的功能也被增加的情况,这时候如果客户要使用额外接口,就必须使用装饰器类了,这种情况Component并非完全对用户透明,称作半透明装饰器。

  4. 与Proxy代理模式的区别?
    代理类将被代理的类封装在其中,两者实现同一个接口。客户使用接口持有代理类,完全屏蔽了被代理类的所有细节。也就是说代理类控制了被代理对象。
    但装饰器做不到,Component组件是客户创建的,然后再由装饰器链层层包装,客户能够直接操作核心对象。

0 0
原创粉丝点击