装饰者模式:像不断地在对象添加装饰的设计模式称为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抽象类,并且根据抽象类编程,因此具体的执行类,根据传入的实现类而不同。