`

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中的许多输入输出物件,就是采取这样的设计。

分享到:
评论

相关推荐

    36种最新设计模式整理

    Design Pattern: Decorator 模式 41 Design Pattern: Facade 模式 44 Design Pattern: Flyweight 模式 46 Design Pattern: Proxy 模式(一) 48 Design Pattern: Proxy 模式(二) 49 Design Pattern: Chain of ...

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

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

    Design Pattern - Decorator

    NULL 博文链接:https://tcg.iteye.com/blog/1283190

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

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

    java源码解读-DesignPattern:Android源码设计模式解析与实战读书笔记源代码

    DesignPattern Android源码设计模式解析与实战读书笔记源代码 说明: 包名factorypattern.normal表示的是工厂方法模式的普通用法 包名factorypattern.practices表示的是工厂方法模式的常用 包名observerpattern表示...

    单例模式源码java-DesignPattern:在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在

    DesignPattern 在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在源码中的使用,每种设计模式都举了一个简单的小例子来进行实现,并加以注释 包名解释 一、DesignPattern ...

    设计模式 design pattern

    2.4.3 Decorator 模式 32 2.5 支持多种视感标准 32 2.5.1 对象创建的抽象 32 2.5.2 工厂类和产品类 33 2.5.3 Abstract Factory模式 35 2.6 支持多种窗口系统 35 2.6.1 我们是否可以使用Abstract Factory 模式 35 ...

    java餐饮管理系统源码6-design_patterns:设计模式

    java餐饮管理系统源码6 design_patterns design_patterns 设计模式相关网站: Java设计模式书籍: 大话设计模式 Head ...装饰器模式(Decorator Pattern) 外观模式(Facade Pattern) 享元模式(Flywe

    设计模式解析习题解答,已经做好目录标签

    • Chapter 17: The Decorator Pattern • Chapter 18: The Observer Pattern • Chapter 19: The Template Method Pattern • Chapter 20: Lessons from Design Patterns: Factories • Chapter 21: The ...

    《Java Design Patterns》高清完整英文PDF版

    Learn how to implement design patterns in Java: each pattern in Java Design Patterns is a complete implementation and the output is generated using Eclipse, making the code accessible to all....

    uu-design-pattern:23种设计模式案例

    |- singleton 单例模式案例 |- structural(结构型模式) |- facade 外观模式案例 |- decorator 装饰器模式案例 |- adapter 适配器模式案例 |- flyweight 享元模式案例 |- composite 组合模式案例

    深入浅出设计模式中文

    3 Decorating Objects: the Decorator Pattern 79 4 Baking with OO goodness: the Factory Pattern 109 5 One of a Kind Objects: the Singleton Pattern 169 6 Encapsulating Invocation: the Command Pattern 191...

    design-pattern-java.pdf

    树形结构的处理——组合模式(二) 树形结构的处理——组合模式(三) 树形结构的处理——组合模式(四) 树形结构的处理——组合模式(五) 装饰模式-Decorator Pattern 扩展系统功能——装饰模式(一) 扩展系统...

    [源代码] 《易学 设计模式》 随书源代码

    第12章 真人不露相:装饰模式 (Decorator) 第13章 游刃有余:桥模式 (Bridge) 第14章 如法炮制:组合模式 (Composite) 第15章 源源不断:享元模式 (Flyweight) 第16章 按部就班:模板方法模式 (TemplateMethod) 第17...

    Programming.in.the.Large.with.Design.Patterns

    It starts with a general introduction to all types of programming patterns and goes on to describe 10 of the most popular design patterns in detail: Singleton, Iterator, Adapter, Decorator, State, ...

    C#设计模式-吕震宇

    C#设计模式(12)-Decorator Pattern C#设计模式(11)-Composite Pattern C#设计模式(10)-Adapter Pattern C#设计模式(9)-Prototype Pattern C#设计模式(8)-Builder Pattern C#设计模式(7)-Singleton...

    DesignPatterns:设计模式

    设计模式设计模式:可重用的面向对象软件的元素栏目:如何构建“运行”: Microsoft Visual Studio 2017 v15.7或更高版本Microsoft .Net Framework v4.7或更高版本Microsoft Visual C ++ 2017年

    C#3.0设计模式.pdf

    1. C# Meets Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 About Patterns 2 About UML 3 About C# 3.0 5 About the Examples 6 2. Structural ...

    Java.Design.Patterns.1537192353

    DECORATOR PATTERN FLYWEIGHT PATTERN TEMPLATE METHOD PATTERN MEDIATOR PATTERN CHAIN OF RESPONSIBILITY ... OBSERVER PATTERN STRATEGY PATTERN COMMAND PATTERN VISITOR PATTERN STATE PATTERN ITERATOR ...

Global site tag (gtag.js) - Google Analytics