装饰边框与被装饰物的一致性
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 模式中的角色
-
Component
增加功能时的核心角色。被装饰的角色。
-
ConcreteComponent
该角色实现了 Component 角色所定义的接口。
-
Decorator(装饰物)
该角色具有与 Component 角色相同的接口。在它内部保存了被装饰对象--Component角色。
-
ConcreteDecorator(具体的装饰物)
该角色是具体的Decorator。
拓展思路
一、接口的透明性。装饰物是被装饰物的子类,这就体现了他们之间的一致性。这样被装饰物和装饰物就有相同的接口。
二、优点是在不改变被装饰物的前提下可以增加功能。只需要加装饰物就可以添加功能。
三、缺点是,会导致程序中增加许多功能类似的很小的类。
网友评论