修饰模式(Decorator Pattern)

Posted mr-wenyan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了修饰模式(Decorator Pattern)相关的知识,希望对你有一定的参考价值。


 

是什么?

怎么用?

在什么情况下用?

实际例子!


 

修饰模式:

  在面向对象的编程中,一种动态的向类里添加新行为的设计模式。

  比如:

    window窗口系统,我们需要往里面添加竖直方向和水平方向的滚动条,如果全部code全写在同一个类(方法)里,那以后扩展或者修改某一个模块功能就很有可能影响到原有的其他功能,所以就需要用到修饰模式。

  再比如:

    coffee店的coffee配置,卡布奇洛和拿铁虽然都是咖啡,但它们的原料配比不同、售价也不同。如果全写在同一个类里,如果以后增加其他咖啡了,就得动以前的code,会有影响其他代码的风险,所以需要修饰模式。

 

原理:

  增加一个修饰类包裹原来的类,包裹的方式一般是将原来的类的作为修饰类的构造参数

  window窗口系统:

  技术分享图片

  Window 是抽象组件,所有的修饰类或修饰组件都继承这个接口类。

  SimpleWindow 是具体组件,所有其他负责的窗口(有滚动条的窗口、有按钮的窗口等)都是修饰这个最基本的窗口而来的。

  WindowDecorator 是抽象修饰者,他和SimpleWindow是一样的,但它是个抽象类。为什么会需要这个抽象类呢?因为所有的修饰者都是继承这个类的,修饰者按照多态方式分别实现了不同的行为!

  VerticalScrollBar、HorizontalScrollBar 是具体的修饰类。

 

维基百科code:

技术分享图片
public interface Window {
    public void draw(); // Draws the Window
    public String getDescription(); // Returns a description of the Window
}
Window
技术分享图片
public class SimpleWindow implements Window {
    public void draw() {
        // Draw window
    }

    public String getDescription() {
        return "simple window";
    }
}
SimpleWindow
技术分享图片
public abstract class WindowDecorator implements Window {
    protected Window decoratedWindow; // the Window being decorated

    //在构造函数中将SimpleWindow包裹起来
    public WindowDecorator (Window decoratedWindow) {
        this.decoratedWindow = decoratedWindow;
    }
    
    @Override
    public void draw() {
        decoratedWindow.draw();
    }

    @Override
    public String getDescription() {
        return decoratedWindow.getDescription();
    }
}
WindowDecorator
技术分享图片
public class VerticalScrollBar extends WindowDecorator {
    public VerticalScrollBar(Window windowToBeDecorated) {
        super(windowToBeDecorated);
    }

    @Override
    public void draw() {
        super.draw();
        drawVerticalScrollBar();
    }

    private void drawVerticalScrollBar() {
        // Draw the vertical scrollbar
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", including vertical scrollbars";
    }
}
VerticalScrollBar
技术分享图片
public class HorizontalScrollBar extends WindowDecorator1 {
    public HorizontalScrollBar (Window windowToBeDecorated) {
        super(windowToBeDecorated);
    }

    @Override
    public void draw() {
        super.draw();
        drawHorizontalScrollBar();
    }

    private void drawHorizontalScrollBar() {
        // Draw the horizontal scrollbar
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", including horizontal scrollbars";
    }
}
HorizontalScrollBar
技术分享图片
public class Main {
    // for print descriptions of the window subclasses
    static void printInfo(Window w) {
        System.out.println("description:"+w.getDescription());
    }
    public static void main(String[] args) {
        // original SimpleWindow
        SimpleWindow sw = new SimpleWindow();
        printInfo(sw);
        // HorizontalScrollBar  mixed Window
        HorizontalScrollBar hbw = new HorizontalScrollBar(sw);
        printInfo(hbw);
        // VerticalScrollBar mixed Window
        VerticalScrollBar vbw = new VerticalScrollBar(hbw);
        printInfo(vbw);
    }
}
Main

结果:

description:simple window
description:simple window, including horizontal scrollbars
description:simple window, including horizontal scrollbars, including vertical scrollbars

 

实例:

技术分享图片

  java.io类包:

技术分享图片

 

技术分享图片

 

以上是关于修饰模式(Decorator Pattern)的主要内容,如果未能解决你的问题,请参考以下文章

Head First设计模式之装饰者模式(Decorator Pattern)

装饰模式(decorator-pattern)

装饰模式(decorator-pattern)

Decorator Pattern(装饰模式)

Head First设计模式之装饰者模式(Decorator Pattern)

装饰者模式(Decorator Pattern)