图解设计模式-Decorator模式

装饰者模式:像不断地在对象添加装饰的设计模式称为Decorator模式,Decorator指装饰物。
 
角色:
Component组件:增加功能的核心角色。本示例中,装饰前的蛋糕就是Component角色,Component角色只定义了API接口。
ConcreteComponent具体的组件:实现了Component角色所定义的接口api。在示例中有StringDisplay扮演。
Decorator装饰者:该角色具有和Component角色相同的接口api,在它内部保存了被装饰对象-Component角色。Decorator自己知道要装饰的对象。本示例中由Border类扮演。
ConcreteDecorator具体装饰者:该角色是具体Decorator角色,本示例中由SideBorder和FullBorder扮演。
 
代码:
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));
        }
    }
}
public class StringDisplay extends Display {
    private String string;

    public StringDisplay(String string) {
        this.string = string;
    }
    @Override
    public int getColumns() {
        return this.string.length();
    }

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

    @Override
    public String getRowText(int row) {
        if(row == 0) {
            return  this.string;
        }else {
            return null;
        }
    }
}
public abstract class Border extends Display{
//被装饰者
    protected Display display;
    protected Border(Display display) {//在生成实例时通过参数指定被装饰者
        this.display = display;
    }
}
public class SiderBorder extends Border {
    private char borderChar;
    protected SiderBorder(Display display,char borderChar) {
        super(display);
        this.borderChar = borderChar;
    }

    @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;
    }
}
public class FullBorder extends Border {
    protected 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) {
        StringBuilder stringBuilder = new StringBuilder();
        for(int i=0;i<count;i++) {
            stringBuilder.append(ch);
        }
        return stringBuilder.toString();
    }
}
public class Main {
    public static void main(String[] args) {
        Display stringDisplay = new StringDisplay("test");
        stringDisplay.show();
        Display siderBorder = new SiderBorder(stringDisplay,'-');
        siderBorder.show();
        Display fullBorder = new FullBorder(siderBorder);
        fullBorder.show();
        Display fullBorder1 = new FullBorder(fullBorder);
        fullBorder1.show();
    }
}
执行结果:
test
-test-
+------+
|-test-|
+------+
+--------+
|+------+|
||-test-||
|+------+|
+--------+
 
重点说明:
通过以上代码,可以了解到Display抽象类与StringDisplay(实现了Display)实现类是一对( 作为组件类),
后面的Border抽象类通过继承Display抽象类使后面继承Border类的子类都具有相同的父类Display。
SiderBorder实现类继承了Border抽象类(最上面的父类为Display),并且SiderBorder与FullBorder通过委托方式调用Display抽象类,并且根据抽象类编程,因此具体的执行类,根据传入的实现类而不同。

猜你喜欢

转载自www.cnblogs.com/use-D/p/9615745.html
今日推荐