裝飾器模式-Decorator(Java實現)

裝飾器模式-Decorator(Java實現)

裝飾器模式容許向一個現有的對象添加新的功能, 同時又不改變其結構。java

其中 "現有對象"在本文中是StringDisplay類.app

添加新的功能的對象在本文中是: SideBorder類 和 FullBorder類ide

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;
        }
    }
}

使用方式以下:this

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

 

裝飾器類

AbstractBorder抽象類

這是具體裝飾器類的抽象定義, 爲了裝飾後也能統一對外的接口, 這裏也繼承了Display接口spa

public abstract class AbstractBorder implements Display {
    Display display;

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

SideBorder類

本類是一個裝飾器3d

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.#"blog

        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();
    }
}

相關文章
相關標籤/搜索