TypechoJoeTheme

IT技术分享

统计

装饰者模式——23种设计模式之结构型模式

2015-06-22
/
0 评论
/
570 阅读
/
正在检测是否收录...
06/22

如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?

一、知识补充

一般有两种方式可以实现给一个类或对象增加行为

  • ①、继承机制:使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。
  • ②、关联机制:即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展 自己的行为,我们称这个嵌入的对象为装饰器 (Decorator)。

动态的将新功能附加到对象上。在对象功能扩张方面,比继承更有弹性。要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。

二、类图表示

装饰者模式涉及Component,ConcreteComponent,Decorator,ConcreteDecorator四个角色

  • ①、Component:定义一个对象接口,可以给这些对象动态地添加职责。
  • ②、ConcreteComponent:定义一个对象,可以给这个对象添加一些职责。
  • ③、Decorator:维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。
  • ④、ConcreteDecorator:向组件添加职责。

java-decorate-model-1

三、代码示例

public abstract Class Model{

    public String name;

    public String getName(){

        return name;

    }

    public void setName(String name){

        this.name = name;

    }

    public abstrace String method();
//实体中间层,实现超类的抽象方法

public Class Source extends Model{

    @override

    public String method(){

        return super.getName;

    }

}
//实体类

public Class Source_A extends Source{

    public Source_A (){

        super.setName("I am Source_A");

    }

}
//装饰者中间层

public Class Decorate extends Model{

    private Model obj;

    public Decorate (Model obj){

        this.obj= obj;

    }

    @override

    public String method(){

        return super.getName + obj.method();

    }

}
//装饰者实体

public Class Decorate_A extends Decorate{

    public Decorate_A(Model obj){

        super(obj);

        super.setName("I am Decorate_A");

    }

}
public Class Test{

    public static void main(String[] args){

        Model obj = new Source_A();

        obj = new Decorate_A(obj);

        obj.method();

    }

}

四、优缺点分析

1、优点

  • ①、动态地给一个对象增加一些额外的职责。就增加功能来说,比生成子类更为灵活。
  • ②、装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
  • ③、通过动态的方式扩展一个对象的功能,通过配置文件在运行时选择不同的装饰器,从而实现不同的行为。
  • ④、通过使用不同的具体装饰类以及这些装饰类的排列组合, 可以创造出很多不同行为的组合。
  • ⑤、可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
  • ⑥、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类。
  • ⑦、在使用时对其进行组合,原有代码无须改变,符合“开闭原则”
  • ⑧、装饰模式将更多的功能动态地附加到一个对象上。装饰模式提供了一个灵活的、可以替代继承的选择。

2、缺点

  • ①、装饰模式进行系统设计时将产生很多小对象,这 些对象的区别在于它们之间相互连接的方式有所不同,,而不是它们的类或者属性值有所不同,同时还将产生很多具体装饰类。这些装饰类和小对象的产生将增加 统的复杂度,加大学习与理解的难度。
  • ②、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次 装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐

    五、与其它模式的比较

1、与适配器模式的比较

  • ①、Decorator模式中装饰仅改变对象的职责而不改变它的接口。
  • ②、Adapter模式中适配器将给对象一个全新的接口

2、与组合模式的比较

  • ①、可以将装饰视为一个退化的仅有一 个组件的组合,Decorator的目的不在于对象聚集

3、与策略模式的比较

  • ①、用一个装饰可以改变对象的外表,而 Strategy模式可以改变对象的内核

六、应用场景

  • ①、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  • ②、需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。
  • ③、当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
  • ③、当不能采用生成子类的方法进行扩充时,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,类定义被隐藏或者类定义不能用于生成子类
  • ④、有一个基本功能,还有些可选功能, 每一个具体的对象,在基本功能的基础上通过 选用不同的可选功能来定制

七、总结

装饰者模式

  • ①、装饰者模式通过继承统一了装饰者和被装饰者的接口。
  • ②、通过采用组合/聚合、而非继承,获得了在运行时动态扩展被装饰者对象的能力。
  • ③、Decorator将请求转发给它的Component对象, 并有可能在转发请求前后执行一些附加的动作。
  • ④、基本功能作为ConcreteComponent,可选功能作为ConcreteDecortator
  • ⑤、虽然装饰对象可以在被装饰对象之前或之后添加功能,但是对象链总是终于ConcreteComponent对象
  • ⑥、可以根据需要扩展多个功能,避免了单独使用 继承带来的“灵活性差”和“多子类衍生”问 题。
  • ⑦、Component类在Decorator模式中充当抽象接口 的角色,不应该去实现具体的行为。
  • ⑧、 Decorator类对于Component类应该透明,Decorator 类是从外部来扩展Component类的功能。
  • ⑨、Decorator模式并非为解决“多子类衍生的多继 承”问题,。
  • ⑩、Decorator模式应用的要点在于解决 “主体类在多个方向上的扩展功能”------此为 “装饰 ”的真正含义。
朗读
赞 · 0
版权属于:

IT技术分享

本文链接:

https://idunso.com/archives/378/(转载时请注明本文出处及文章链接)