图解设计模式

图解设计模式--Decorator(装饰者)模式

2017-08-24  本文已影响33人  Ginger12

装饰边框与被装饰物的一致性

Decorator 模式

不断地为对象添加装饰的设计模式被称为 Decorator 模式。

示例程序

名字 说明 类型
Display 用于显示字符串的抽象类 Component
StringDisplay 用于显示单行字符串的类 ConcreteComponent
Border 用于显示装饰边框的抽象类 Decorator
SideBorder 用于只显示左右边框的类 ConcreteDecorator
FullBorder 用于显示上下左右边框的类 ConcreteDecorator
Main 测试程序行为的类

Display.java

package decorator;

public abstract class Display {
    public abstract int getColumns();
    public abstract int getRows();
    public abstract String getRowText(int row);
    public final void show() {
        for (int i = 0 ; i < getRows(); i++) {
            System.out.println(getRowText(i));
        }
    }
}

StringDisplay.java

package decorator;

public class StringDisplay extends Display {
    private String string;
    public StringDisplay(String string) {
        this.string = string;
    }
    public int getColumns() {
        return string.getBytes().length;
    }
    public int getRows() {
        return 1;
    }
    public String getRowText(int row) {
        if (row == 0) {
            return string;
        } else {
            return null;
        }
    }
}

Border.java

package decorator;

public abstract class Border extends Display {
    protected Display display;
    protected Border(Display display) {
        this.display = display;
    }
}

SideBorder.java

package decorator;

public class SideBorder extends Border {
    private char borderChar;
    public SideBorder(Display display, char ch) {
        super(display);
        this.borderChar = ch;
    }
    public int getColumns() {
        return 1 + display.getColumns() + 1;
    }
    public int getRows() {
        return display.getRows();
    }

    public String getRowText(int row) {
        return borderChar + display.getRowText(row) + borderChar;
    }
}

FullBorder.java

package decorator;

public class FullBorder extends Border {
    public FullBorder(Display display) {
        super(display);
    }

    public int getColumns() {
        return 1 + display.getColumns() + 1;
    }

    public int getRows() {
        return 1 + display.getRows() + 1;
    }

    public String getRowText(int row) {
        if (row == 0) {
            return "+" + makeLine('-', display.getColumns()) + "+";
        } else if (row == display.getRows() + 1) {
            return "+" + makeLine('-', display.getColumns()) + "+";
        } else {
            return "|" + display.getRowText(row - 1) + "|";
        }
    }

    private String makeLine(char ch, int count) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < count; i++) {
            buf.append(ch);
        }
        return buf.toString();
    }
}

Main.java

package decorator;

public class Main {
    public static void main(String[] args) {
        Display b1 = new StringDisplay("Hello, world.");
        Display b2 = new SideBorder(b1, '#');
        Display b3 = new FullBorder(b2);
        b1.show();
        b2.show();
        b3.show();
        Display b4 = new SideBorder(
                new FullBorder(
                        new FullBorder(
                                new SideBorder(
                                        new FullBorder(
                                                new StringDisplay("你好,世界。")
                                        ),
                                        '*'
                                )
                        )
                ),
                '/'
        );
        b4.show();
    }
}

Decorator 模式中的角色

  1. Component

    增加功能时的核心角色。被装饰的角色。

  2. ConcreteComponent

    该角色实现了 Component 角色所定义的接口。

  3. Decorator(装饰物)

    该角色具有与 Component 角色相同的接口。在它内部保存了被装饰对象--Component角色。

  4. ConcreteDecorator(具体的装饰物)

    该角色是具体的Decorator。

拓展思路

一、接口的透明性。装饰物是被装饰物的子类,这就体现了他们之间的一致性。这样被装饰物和装饰物就有相同的接口。

二、优点是在不改变被装饰物的前提下可以增加功能。只需要加装饰物就可以添加功能。

三、缺点是,会导致程序中增加许多功能类似的很小的类。

上一篇下一篇

猜你喜欢

热点阅读