Decorator 模式
不断地为对象添加装饰的设计模式被称为Decorator 模式。
示例程序类图
示例程序
Display
public abstract class Display {
public abstract int getColumns();
public abstract int getRows();
public abstract String
getRowText(int row
);
public void show() {
for (int i
= 0; i
< getRows(); i
++) {
System
.out
.println(getRowText(i
));
}
}
}
StringDisplay
public class StringDisplay extends Display {
private String string
;
public StringDisplay(String string
) {
this.string
= string
;
}
@Override
public int getColumns() {
return string
.getBytes().length
;
}
@Override
public int getRows() {
return 1;
}
@Override
public String
getRowText(int row
) {
if (row
== 0) {
return string
;
} else {
return null
;
}
}
}
Border
public abstract class Border extends Display {
protected Display display
;
protected Border(Display display
) {
this.display
= display
;
}
}
SideBorder
public class SideBorder extends Border {
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
;
}
}
FullBorder
public class FullBorder extends Border {
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
) {
StringBuffer buf
= new StringBuffer();
for (int i
= 0; i
< count
; i
++) {
buf
.append(ch
);
}
return buf
.toString();
}
}
Main
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 模式中的登场角色
1.Component
增加功能时的核心角色。在示例程序中,由Display类扮演此角色。
2.ConcreteComponent
该角色是实现了Component角色所定义的接口(API)的具体蛋糕。在示例程序中,由StringDisplay类扮演此角色。
3.Decorator(装饰物)
该角色具有与Component角色相同的接口(API)。在它内部保存了被装饰对象——Component角色。Decorator角色知道自己要装饰的对象。在示例程序中,由Border类扮演此角色。
4.ConcreteDecorator(具体的装饰物)
该角色是具体的Decorator角色。在示例程序中,由SideBorder和FullBorder类扮演此角色。
通用类图
Decorator 模式的主要目的是通过添加装饰物来增加对象的功能。
继承和委托中的一致性
public class Parent {
void parentMethod(){
System
.out
.println("Parent");
}
}
public class Child extends Parent {
private String namec
= "child";
void childMethod() {
System
.out
.println("Child");
}
public static void main(String
[] args
) {
Parent obj
= new Child();
obj
.parentMethod();
System
.out
.println(obj
.name
);
Parent obj1
= new Child();
((Child
) obj1
).childMethod();
}
}
从上面的代码中,我们可以看到Child类的实例可以被保存在Parent类型的变量中,也可以调用从Parent类中继承的方法。 我们可以像操作Parent类的实例一样操作Child类的实例。这是将子类当作父类看待的一个例子。 但是反过来,如果想将父类当作子类一样操作,则需要先进行类型转换。