`

Design Pattern: Decorator 模式

阅读更多

装饰模式:Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油

漆的,那么被刷油漆的对象我们称decoratee.这两种实体在Decorator模式中是必须的.


Decorator定义:
动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功

能的扩充显得更为灵活.


为什么使用Decorator?
我们通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类

,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确

定了,是静态的.

使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机.Decorator提供了"即插即用"的

方法,在运行期间决定何时增加何种功能.

如何使用?
举Adapter中的打桩示例,在Adapter中有两种类:方形桩 圆形桩,Adapter模式展示如何综合使用这两个类,

在Decorator模式中,我们是要在打桩时增加一些额外功能,比如,挖坑 在桩上钉木板等,不关心如何使用两

个不相关的类.

我们先建立一个接口:

public interface Work
{
  public void insert();

}

 

接口Work有一个具体实现:插入方形桩或圆形桩,这两个区别对Decorator是无所谓.我们以插入方形桩为例

:

public class SquarePeg implements Work{
  public void insert(){
    System.out.println("方形桩插入");
  }
}

 

现在有一个应用:需要在桩打入前,挖坑,在打入后,在桩上钉木板,这些额外的功能是动态,可能随意增加调

整修改,比如,可能又需要在打桩之后钉架子(只是比喻).

那么我们使用Decorator模式,这里方形桩SquarePeg是decoratee(被刷油漆者),我们需要在decoratee上刷

些"油漆",这些油漆就是那些额外的功能.

public class Decorator implements Work{

  private Work work;
  //额外增加的功能被打包在这个List中
  private ArrayList others = new ArrayList();

  //在构造器中使用组合new方式,引入Work对象;
  public Decorator(Work work)
  {
    this.work=work;
  
    others.add("挖坑");

    others.add("钉木板");
  }

  public void insert(){

    newMethod();
  }

  
  //在新方法中,我们在insert之前增加其他方法,这里次序先后是用户灵活指定的   
  public void newMethod()
  {
    otherMethod();
    work.insert();


  }


  public void otherMethod()
  {
    ListIterator listIterator = others.listIterator();
    while (listIterator.hasNext())
    {
      System.out.println(((String)(listIterator.next())) + " 正在进行");
    }

  }


}

 

在上例中,我们把挖坑和钉木板都排在了打桩insert前面,这里只是举例说明额外功能次序可以任意安排.

好了,Decorator模式出来了,我们看如何调用:

Work squarePeg = new SquarePeg();
Work decorator = new Decorator(squarePeg);
decorator.insert();


Decorator模式至此完成.

如果你细心,会发现,上面调用类似我们读取文件时的调用:

FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);

实际上Java 的I/O API就是使用Decorator实现的,I/O变种很多,如果都采取继承方法,将会产生很多子类,

显然相当繁琐.

Jive中的Decorator实现
在论坛系统中,有些特别的字是不能出现在论坛中如"打X倒XXX",我们需要过滤这些"反X动"的字体.不让他们

出现或者高亮度显示.

在IBM Java专栏中专门谈Jive的文章中,有谈及Jive中ForumMessageFilter.java使用了Decorator模式,其

实,该程序并没有真正使用Decorator,而是提示说:针对特别论坛可以设计额外增加的过滤功能,那么就可

以重组ForumMessageFilter作为Decorator模式了.

所以,我们在分辨是否真正是Decorator模式,以及会真正使用Decorator模式,一定要把握好Decorator模式

的定义,以及其中参与的角色(Decoratee 和Decorator).

 

/*******************************************************************************/

 

在Java Swing中的JTextArea元件预设并没有卷轴,因为设计人员认为卷轴的功能并不是一定需要的,而决定让程式人员可以动态选择是否增加卷轴功能,卷轴的功能是由JScrollPane元件提供,如果您要加入一个具有卷轴功能的JTextArea,您可以如下进行设计:

JTextArea textArea = new JTextArea();
JScrollPane scrollPane = new JScrollPane(textArea);

 
JScrollPane对JTextArea即是个容器,而它对JFrame来说又是个元件,可以如下这般将之加入JFrame中:

getContentPane().add(scrollPane);

 
像这样动态的为JTextArea加入功能的方法,我们可以使用Decorator模式来组织结构,您可以动态的为一个物件加入一些功能(像是为 JTextArea加上卷轴),而又不用修改JTextArea的功能。对JTextArea来说,JScrollPane就好像是一个卷轴外框,直接套在JTextArea上作装饰,就好比您在照片上加上一个相框的意思。

先以上面这个例子来说明Decorator模式的一个实例:

无论是TextView或是Decorator类别,它们都是VisualComponent的一个子类,也就是说它们都是一个可视元件,而Decorator类又聚合了VisualComponent,所以又可以当作TextView容器,ScrollDecorator类别实作了 Decorator类,它可能是这样设计的:
public abstract class Decorator extends VisualComponent {
    protected VisualComponent component;

    public Decorator(VisualComponent component) {
        this.component = component;
    }

    public void draw() {
        component.draw();
    }
}

public class ScrollDecorator extends Decorator {
    public ScrollDecorator(VisualComponent component) {
        super(component);
    }

    public void draw() {
        super.draw();
        scrollTo();
    }

    public void scrollTo() {
        // ....
    }
}

 
要将新功能套用至TextView上,可以这样设计:

ScrollDecorator scrollDecorator =
                    new ScrollDecorator(new TextView());

 
super.draw()会先呼叫component也就是TextView物件的draw()方法先绘制TextView,然后再进行 ScrollPanel的scrollTo(),也就是卷动的方法。在图中也表示了一个BorderDecorator,它可能是这样设计的:

public class BorderDecorator extends Decorator {
    public BorderDecorator(VisualComponent component) {
        super(component);
    }

    public void draw() {
        super.draw();
        drawBorder();
    }

    public void drawBorder() {
        // ....
    }
}

 
要将ScrollDecorator与BorderDecorator加至TextView上,我们可以这样设计:

BorderDecorator borderDecorator =
         new BorderDecorator(
               new ScrollDecorator(new TextView()));


所以当BorderDecorator调用draw()方法时,它会先调用ScrollDecorator的draw()方法,而 ScrollDecorator的draw()方法又会先调用TextView的draw()方法,所以绘制的顺序变成:

TextDraw.draw();
ScrollDecorator.scrollTo();
BorderDecorator.drawBorder();
在Gof的书中指出另一个范例,它设计一个Stream抽象类,而有一个StreamDecorator类,Stream的子类有处理记忆体串流的 MemoryStream与FileStream,有各种方法可以处理串流,也许只是单纯的处理字元,也许会进行压缩,也许会进行字元转换,最基本的处理可能是处理字元,而字元压缩被视为额外的功能,这个时候我们可以使用装饰模式,在需要的时候为Stream物件加上必要的功能,事实上在java.io中的许多输入输出物件,就是采取这样的设计。

分享到:
评论

相关推荐

    Design Pattern - Decorator

    装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时给对象添加新的行为或职责,同时保持对象的接口不变。这种模式的核心在于,它动态地将责任附加到对象上,通过将对象包装在一个装饰类中来扩展...

    java设计模式源码-DesignPattern:设计模式(Java实现源码)

    DesignPattern项目是设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。 设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发...

    DesignPattern:设计模式小Demo

    设计模式是软件工程中的一种最佳实践,用于解决在软件设计中常见的...以上就是这个DesignPattern小Demo中可能会涵盖的设计模式,通过这些模式的实例,你可以更好地理解和应用它们到实际项目中,提升你的Java编程能力。

    DesignPattern::pencil:设计模式_java实现以及详解

    本资源“DesignPattern::pencil:设计模式_java实现以及详解”提供了一套详细的学习材料,帮助开发者理解和应用设计模式。 该资源的作者是“养码青年-Style”,他通过这个项目记录了自己的设计模式学习过程。鼓励...

    DesignPattern:设计模式

    DesignPattern-master这个压缩包可能包含了一个关于设计模式的项目或者教程资源。 设计模式分为三类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)和行为型模式(Behavioral Patterns)...

    designPattern:设计模式相关代码实现

    "designPattern:设计模式相关代码实现"这个项目,显然提供了不同设计模式在Java语言中的实际应用示例。 在Java世界里,设计模式主要分为三大类:创建型模式、结构型模式和行为型模式。每种模式都针对特定的编程问题...

    DesignPattern:设计模式.net源代码

    本资源"DesignPattern:设计模式.net源代码"提供了一套基于.NET实现的设计模式示例,旨在帮助程序员更好地理解和应用这些模式。 在"DesignPattern-master"这个压缩包中,你可能找到的文件结构和内容包括: 1. **...

    DesignPattern:设计模式演示程序

    这个名为"DesignPattern"的压缩包文件很可能包含了一个Java实现的各种设计模式的示例程序。 在这个"DesignPattern-master"目录中,我们可以期待找到一系列与设计模式相关的Java源代码文件(.java),每个文件或...

    C++设计模式(Design Pattern)范例源代码

    23种设计模式(Design Pattern)的C++实现范例,包括下面列出的各种模式,代码包含较详细注释。另外附上“设计模式迷你手册.chm”供参考。 注:项目在 VS2008 下使用。 创建型: 抽象工厂模式(Abstract Factory) 生成...

    DesignPattern:C#设计模式示例

    "DesignPattern:C#设计模式示例"这个资源很可能是包含多个C#实现的设计模式示例代码库。 设计模式通常分为三类:创建型、结构型和行为型。每种模式都解决了特定场景下的问题,并提供了良好的代码组织和扩展性。 ...

    design pattern

    在给定的压缩包文件中,包含了九种经典的设计模式示例,它们分别是:单例模式(Singleton)、策略模式(StrategyPattern)、适配器模式(AdapterPattern)、装饰者模式(DecoratorPattern)、抽象工厂模式...

    FOAD-DesignPattern:FOAD-DesignPattern

    6. 装饰模式(Decorator Pattern): 装饰模式允许动态地给一个对象添加一些额外的职责,提供了比继承更灵活的扩展对象功能的方式。在C#中,装饰模式通常通过继承并组合使用,以增加对象的功能,而不会破坏其原有的...

    设计模式源码Head_First_DesignPattern_src

    在本文中,我们将深入探讨设计模式的核心概念,并结合"Head First DesignPattern_src"中的源码,详细解析一些关键的设计模式。 1. 单例模式(Singleton): 单例模式确保一个类只有一个实例,并提供全局访问点。在...

    DesignPattern:设计模式的学习笔记和示例代码

    设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的经验总结。...在DesignPattern-master这个压缩包中,你可以找到关于这些模式的详细讲解和实例代码,为你的Java开发之旅提供宝贵的参考资料。

    DesignPattern:有关设计模式的一些演示

    这个名为"DesignPattern:有关设计模式的一些演示"的项目,可能是为了帮助开发者理解和应用各种设计模式。 设计模式分为三大类:创建型、结构型和行为型。创建型模式关注对象的创建过程,如单例(Singleton)、工厂...

    Design*Pattern*Framework*4.5

    "Design*Pattern*Framework*4.5" 可能指的是一个基于 .NET Framework 4.5 的设计模式实现或教程集合。 设计模式是经验丰富的软件开发者的智慧结晶,它们被分为三类:创建型、结构型和行为型。创建型模式涉及对象的...

    designpattern:Head First 设计模式练习

    此外,装饰器模式(Decorator)允许动态地给对象添加新的行为或职责,而不影响其其他对象。Java的IO流就是装饰器模式的一个经典应用,如BufferedInputStream和DataInputStream。 适配器模式(Adapter)将两个不兼容...

    Design-pattern:设计模式

    这个名为"Design-pattern:设计模式"的压缩包可能包含了一个关于设计模式的学习资源,比如代码示例或者教程。 创建型设计模式是设计模式中的一个类别,主要关注对象的创建过程。这类模式包括工厂方法(Factory ...

    design pattern tutorial

    10. 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责。它提供了一种灵活的扩展一个对象功能的方式,而不需要使用继承。 11. 外观模式(Facade Pattern):提供了一个统一的接口,用来访问子...

Global site tag (gtag.js) - Google Analytics