(11)装饰模式

(11)装饰模式

定义:动态地给一个对象添加一些额外的职责。就扩展功能而言, 它比生成子类方式更为灵活。

类型:结构型模式

类图:

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

2.    装饰模式以对客户端透明的方式动态的给一个对象附加上更多的责任。换言之客户端并不会觉的对象在装饰前和装饰后有什么区别。

3.    装饰模式可以在不创造更多的子类的模式下,将对象的功能加以扩展。

4.    装饰模式与类继承的区别:

1)    装饰模式是一种动态行为,对已经存在类进行随意组合,而类的继承是一种静态的行为,一个类定义成什么样的,该类的对象便具有什么样的功能,无法动态的改变。

2)    装饰模式扩展的是对象的功能,不需要增加类的数量,而类继承扩展是类的功能,在继承的关系中,如果我们想增加一个对象的功能,我们只能通过继承关系,在子类中增加两个方法。

3)    装饰模式是在不改变原类文件和使用继承的情况下,动态的扩展一个对象的功能,它是通过创建一个包装对象,也就是装饰来包裹真是的对象。

5.    装饰模式把对客户端的调用委派给被装饰的类,装饰模式的关键在于这种扩展完全透明的。

装饰模式的构成

1)    抽象构建角色(Component):给出一个抽象的接口,以规范准备接受附加责任的对象。相当于i/o流里面InputStream/OutputStream和Reader/Writer。

2)    具体的构建角色(ConcreteComponent):定义一个将要接受附加责任的类。相当于i/o里面的FileOutputStream和FileInputStream。

3)    装饰角色(Docorator):持有一个抽象构建(Component)角色的引用,并定义一个与抽象构件一致的接口。相当于i/o里面的FilerOutputStream和FilterInputStream。

4)    具体的装饰角色(ConcreteDecorator):负责给构建对象“贴上”附加的责任。相当于i/o流里面的BufferedOutputStream和BufferedInputStream以及DataOutputStream和DataInputSrtream。

7.    装饰模式的特点:

1)    装饰对象和真实对象具有相同的接口,这样客户端对象就可以以真实对象的相同的方式和装饰对象交互。

2)    装饰对象包含一个真实对象的引用(reference).

3)    装饰对象接受所有来自客户端的请求,它把这些请求转发给真实的对象。

4)    装饰对象可以在转发这些请求以前或者以后增加一些附加的功能。这样就能确保在运行时,不用修改给定对象结构就可以在外部增加附加的功能。在面向对象的程序设计中,通常是使用继承的关系来扩展给定类的功能。

代码实现

// 抽象的构建接口:
public interface Component {
   public void doSomething();
}
// 具体的构建角色:
public class ConcreteComponent implements Component {
   @Override
   public void doSomething() {
      System.out.println("功能A");
   }
}
// 装饰角色:
public class Decorate implements Component {
   private Component component;
   public Decorate(Component component) {
      this.component = component;
   }
   @Override
   public void doSomething() {
      component.doSomething();
   }
}
// 具体装饰角色1:
public class ConcreteDecorate1 extends Decorate {
   public ConcreteDecorate1(Component component) {
      super(component);
   }
   @Override
   public void doSomething(){
      super.doSomething();
      this.doAnotherDosomething();
   }
   private void doAnotherDosomething() {
      System.out.println("功能B");
   }
}
// 具体装饰角色2:
public class ConcreteDecorate2 extends Decorate {
   public ConcreteDecorate2(Component component) {
      super(component);
   }
   @Override
   public void doSomething() {
      super.doSomething();
      this.doAnotherDosomething();
   }
   private void doAnotherDosomething() {
      System.out.println("功能C");
   }
}
// 客户端
public class Client {
   public static void main(String[] args) {
      Component component = new ConcreteDecorate1(
        new ConcreteDecorate2(new ConcreteComponent()));
      component.doSomething();
   }
}

优缺点

(1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。

(2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

(3)由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

适用场景

当我们需要将责任动态的附加到对象上的时候;也就是说,我们开发设计的对象中有某一部分的功能现在还不能确定,以后需要动态的添加或者去掉。或者是在使用继承比较困难的时候,可以采用组合的实现方式(继承与复用)。

时间: 2024-10-12 05:21:33

(11)装饰模式的相关文章

设计模式-1.11装饰模式

装饰模式: Decorate,动态地给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类更为灵活.(DP)  装饰模式提供了更加灵活的向对象添加职责的方式.可以用添加和分离的方法,用装饰在运行时刻增加和删除职责.装饰模式提供了一种“即用即付”的方法来添加职责.它并不试图在一个复杂的可定制的类中支持所有可预见的特征,相反,你可以定义一个简单的类,并且用装饰类给它逐渐地添加功能.可以从简单的部件组合出复杂的功能. 实例: 比如有一个手机,允许你为手机添加特性,比如增加挂件.屏幕贴膜等.

java--反射--黑马程序员

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 反射 主要内容:<获取Class对象的三种方式.获取无参_有参构造方法.获取成员变量.获取成员方法.运行配置文件内容.越过泛型检查.代理模式.动态代理.模版设计模式.装饰模式. JDK5的新特性.JDK7的新特性 > 1.获取Class对象的三种方式 1.Object类中的:getClass():此方法不是静态的,必须对象的引用调用:2.class属性:任何的数据类型(包括基本数据类型)都有

程序员怎样迈出从5K到1W的重要一步

为什么一个相似的功能,大牛一会儿就搞定,然后悠闲地品着下午茶逛淘宝:而自己加班加点搞到天亮还做不完. 为什么用户提出需求变更后,大牛只需潇洒地敲敲键盘,改改配置:而自己将代码改了又改,删了又建,几乎晕厥,最后只能推翻重来. 为什么大牛写完的程序测试上线后,几乎完美运行,用户无懈可击:而自己的程序bug重重,改好一个却又引出另一个,按下葫芦浮起瓢,几近崩溃. 为什么同样是程序员,大牛工资1W,而自己只能拿区区的3K? 大牛显然知道一些小菜所不知道的秘密,这秘密又是什么呢? 这个秘密就是设计模式.设

初识设计模式、软件设计的六大原则

总结:本篇文字分为两个部分.第一部分:设计模式基本常识:第二部分:软件设计中的六大原则,并详细分析了单一职责原则.(本篇文章的时间轴参考:为知笔记支撑文件夹\Java设计模式(时间序列图).vsdx) 部分一:初识设计模式 什么是设计模式?James拿到这个论点时,很是迷惑! 模式?是不是一个模子?模式识别--计算机领域的经典问题? 设计模拟?软件的设计模式?不懂!!! 但是在实际编码.调试过程中,James的遇到过很是难解的问题:工程代码中有过多的冗余代码--代码复用性不高:需求一旦改变,需要

小菜技术脱变

IT职场的小菜经常有这样的疑问: 为什么一个相似的功能,大牛一会儿就搞定,然后悠闲地品着下午茶逛淘宝:而自己加班加点搞到天亮还做不完. 为什么用户提出需求变更后,大牛只需潇洒地敲敲键盘,改改配置:而自己将代码改了又改,删了又建,几乎晕厥,最后只能推翻重来. 为什么大牛写完的程序测试上线后,几乎完美运行,用户无懈可击:而自己的程序bug重重,改好一个却又引出另一个,按下葫芦浮起瓢,几近崩溃. 为什么同样是程序员,大牛工资1W,而自己只能拿区区的3K? 大牛显然知道一些小菜所不知道的秘密,这秘密又是

java23种设计模式提纲

设计模式的六大原则: 1.单一职责原则 There should never be more than one reason for a class to change. 2.接口隔离原则 Clients should not be forced to depend upon interfaces that they don't use. The dependency of one class to another one should depend on the smallest possib

迈出从3K到1W的重要一步——掌握设计模式

IT职场的小菜经常有这样的疑问: 为什么一个相似的功能,大牛一会儿就搞定,然后悠闲地品着下午茶逛淘宝:而自己加班加点搞到天亮还做不完. 为什么用户提出需求变更后,大牛只需潇洒地敲敲键盘,改改配置:而自己将代码改了又改,删了又建,几乎晕厥,最后只能推翻重来. 为什么大牛写完的程序测试上线后,几乎完美运行,用户无懈可击:而自己的程序bug重重,改好一个却又引出另一个,按下葫芦浮起瓢,几近崩溃. 为什么同样是程序员,大牛工资1W,而自己只能拿区区的3K? 大牛显然知道一些小菜所不知道的秘密,这秘密又是

Java的23种设计模式 &lt;二&gt;

1.单例模式(Singleton Pattern) 定义:Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.) 通用代码:(是线程安全的) public class Singleton { private static final Singleton singleton = new Singleton(); //限制产

C#23种设计模式

1.单例模式(Singleton Pattern) 定义:Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.) 通用代码:(是线程安全的) public class Singleton { private static final Singleton singleton = new Singleton(); //限制产

百度回复将按时缴费卡水立方

http://www.ebay.com/cln/ch.y908/-/176925541016/2015.02.11 http://www.ebay.com/cln/shaamjson/-/176833416018/2015.02.11 http://www.ebay.com/cln/x_ru421/-/176666486019/2015.02.11 http://www.ebay.com/cln/hua6592_18usz/-/176835881012/2015.02.11 http://www