裝飾者模式 Decorator:不改變原類,不使用繼承,創(chuàng)建一個包裝對象,動態(tài)地擴展原對象的功能。
優(yōu)點:
- 擴展性好
- 靈活性比使用繼承好
缺點:很多的裝飾類可能使程序變得復雜。
類圖如下:
裝飾者模式 Decorator 包括四個角色:
抽象被裝飾者(Component):定義一個抽象的被裝飾者。
具體被裝飾者(Concrete Component):定義一個具體的被裝飾者。
抽象裝飾者(Decorator):持有一個被裝飾者(Component)對象的引用,并定義一致的接口。
-
具體裝飾者(Concrete Decorator):負責具體的實現(xiàn)。
裝飾者模式 Decorator
例如:
- 抽象被裝飾者(Component)可以是人
Person,包括兩個方法eat()drink()
abstract class Person {
abstract void eat();
abstract void drink();
}
- 具體被裝飾者(Concrete Component)可以是年輕人
Teenager,實現(xiàn)具體的方法eat()drink()
class Teenager extends Person {
public void eat() {
System.out.println("teenager eat more");
}
public void drink() {
System.out.println("teenager drink more");
}
}
- 抽象裝飾者(Decorator)可以是穿了衣服
ClothDecorator,維護了一個Person對象的引用
abstract class ClothDecorator extends Person {
public Person p;
abstract void eat();
abstract void drink();
}
- 具體裝飾者(Concrete Decorator)可以是穿了 TShirt
class TShirtDecorator extends ClothDecorator {
public TShirtDecorator(Person p) {
this.p = p;
}
public void eat() {
// 預處理
p.eat();
// 后處理
}
public void drink() {
// 預處理
p.drink();
// 后處理
}
}
使用方式:
public static void main(String[] args) {
TShirtDecorator d = new TShirtDecorator(new Teenager());
d.eat();
d.drink();
}
使用實例:Java IO 中的繼承方式
與上述的類圖相對應:
Java IO 中使用裝飾者模式
使用方式:
使用 BufferedInputStream 來裝飾 FileInputStream:
public static void main(String[] args) {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream("a.txt"));
bin.read();
}