裝飾器模式是一種非常有用的結構型模式,它允許我們在不改變類的結果的情況下,為類添加新的功能。
我們來舉例說明一下。首先添加一組形狀,它們都實作了形狀接口。
public interface Shape {
String getShape();
}
class Square implements Shape{
@Override
public String getShape() {
return "正方形";
}
}
class Circle implements Shape{
@Override
public String getShape() {
return "圓";
}
}
然後再來定義裝飾器。裝飾器同樣需要實作Shape接口,而且在裝飾器中還需要對Shape進行補充(也就是裝飾)。
public abstract class ColorDecorator implements Shape {
protected Shape shape;
public ColorDecorator(Shape shape) {
this.shape = shape;
}
}
class RedDecorator extends ColorDecorator {
public RedDecorator(Shape shape) {
super(shape);
}
@Override
public String getShape() {
return "紅色的" + shape.getShape();
}
}
class BlueDecorator extends ColorDecorator {
public BlueDecorator(Shape shape) {
super(shape);
}
@Override
public String getShape() {
return "綠色的" + shape.getShape();
}
}
最後再來驗證一下。我們成功在沒有修改形狀類的前提下,為形狀增加了顔色的功能。
public void run() {
Shape square = new Square();
Shape circle = new Circle();
Shape redSquare = new RedDecorator(square);
Shape blueCircle = new BlueDecorator(circle);
System.out.println(redSquare.getShape());
System.out.println(blueCircle.getShape());
}
裝飾器模式在很多地方都有使用。在Java裡面最經典的使用場景就是Java那一大堆的IO類,例如
BufferedInputStream
或者
FileOutputStream
這樣的。Java的IO類庫通過多個不同IO類的嵌套,可以實作多種功能(例如緩存)的組合。當然其實Java的IO庫是一個反面教材,由于裝飾器模式的過度使用,導緻系統中類太多太複雜,反而不利于我們學習和使用。在實際使用中我們也要注意設計模式的合理使用,不要為了使用而使用。