装饰器模式-Decorator(Java实现)

装饰器模式-Decorator(Java实现)

装饰器模式允许向一个现有的对象添加新的功能, 同时又不改变其结构。

其中 "现有对象"在本文中是StringDisplay类.

添加新的功能的对象在本文中是: SideBorder类 和 FullBorder类

Display接口

public interface Display {
    int getColumns();

    int getRows();

    String getRowText(int row);

    default void show() {
        for (int i = 0; i < getRows(); i++) {
            System.out.println(getRowText(i));
        }
    }
}

StringDisplay类

基础功能类, 用于打印字符串.

public class StringDisplay implements Display {
    private String string;

    public StringDisplay(String s) {
        string = s;
    }

    @Override
    public int getColumns() {
        return string.length();
    }

    @Override
    public int getRows() {
        return 1;
    }

    @Override
    public String getRowText(int row) {
        if (row == 0) {
            return string;
        } else {
            return null;
        }
    }
}

使用方式如下:

Display b1 = new StringDisplay("Hello, world.");
b1.show();

 

装饰器类

AbstractBorder抽象类

这是具体装饰器类的抽象定义, 为了装饰后也能统一对外的接口, 这里也继承了Display接口

public abstract class AbstractBorder implements Display {
    Display display;

    public AbstractBorder(Display display) {
        this.display = display;
    }
}

SideBorder类

本类是一个装饰器

public class SideBorder extends AbstractBorder {
    private char borderchar;

    public SideBorder(Display display, char ch) {
        super(display);
        this.borderchar = ch;
    }

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

    @Override
    public int getRows() {
        return display.getRows();
    }

    @Override
    public String getRowText(int row) {
        return borderchar + display.getRowText(row) + borderchar;
    }
}

使用方式如下:

把一个SideBorder装饰器添加到StringDisplay上, 于是乎"Hello, world." 就变成了 "#Hello, world.#"

        Display b1 = new StringDisplay("Hello, world.");
        Display b2 = new SideBorder(b1, '#');
        b2.show();

FullBorder类

本类是一个装饰器

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

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

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

    @Override
    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) {         // 生成一个重复count次字符ch的字符串
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < count; i++) {
            buf.append(ch);
        }
        return buf.toString();
    }
}

使用方式如下:

把一个FullBorder装饰器添加到StringDisplay上, 于是乎"Hello, world." 就变成了->

+------ --+

|Hello, world.|

+---------+

        Display b1 = new StringDisplay("Hello, world.");
        Display b3 = new FullBorder(b1);
        b3.show();

Main

运行测试

public class Main {
    public static void main(String[] args) {
        Display b4 =
                new SideBorder(
                        new FullBorder(
                                new FullBorder(
                                        new SideBorder(
                                                new FullBorder(
                                                        new StringDisplay("1234567")
                                                ), '*'
                                        )
                                )
                        ), '/'
                );
        b4.show();
    }
}

 

posted @ 2018-05-13 11:42  GoldArowana  阅读(915)  评论(0编辑  收藏  举报