裝飾者模式 Decorator:不改變原類寿酌,不使用繼承胰苏,創(chuàng)建一個包裝對象,動態(tài)地擴展原對象的功能醇疼。
優(yōu)點:
- 擴展性好
- 靈活性比使用繼承好
缺點:很多的裝飾類可能使程序變得復雜硕并。
類圖如下:
裝飾者模式 Decorator 包括四個角色:
抽象被裝飾者(Component):定義一個抽象的被裝飾者。
具體被裝飾者(Concrete Component):定義一個具體的被裝飾者秧荆。
抽象裝飾者(Decorator):持有一個被裝飾者(Component)對象的引用倔毙,并定義一致的接口。
-
具體裝飾者(Concrete Decorator):負責具體的實現(xiàn)辰如。
例如:
- 抽象被裝飾者(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 中的繼承方式
與上述的類圖相對應:
使用方式:
使用 BufferedInputStream
來裝飾 FileInputStream
:
public static void main(String[] args) {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream("a.txt"));
bin.read();
}