1、裝飾模式介紹html
裝飾模式(decorator):表示動態的給一個對象添加一些新的功能(利用子類繼承父類也能夠實現),可是比生成子類方式更靈活。java
也叫裝飾者模式或者裝飾器模式設計模式
例如:咱們每一個人身上穿的衣服,鞋子,領帶,披風均可以理解爲是對人的裝飾。session
裝飾器模式類圖:app
Component:定義一個對象接口,能夠給這些對象動態添加職責。真實對象和裝飾者對象有相同的接口,這樣客戶端不用知道內部有裝飾者對象(Decorator)ide
存在的,仍是以以前處理真實對象的相同方式來和裝飾者對象交互。性能
ConcreteComponent:是定義了一個具體的對象(例如:人),也能夠給這個對象添加一些其餘職責。學習
Decorator:裝飾抽象類,繼承了Component,從外類來擴展Component類的功能,但對Component來講,是無需知道Decorator存在的。測試
ConcreteDecorator:就是具體的裝飾對象了(衣服,鞋子..),它起到了給Component添加職責的功能。this
2、裝飾模式代碼實現
定義一個Component對象接口(ICar),汽車移動
1
2
3
4
5
6
|
/**
* ICar表示Component:
*/
public
interface
ICar {
void
move();
//汽車移動
}
|
定義一個具體真實的對象ConcreteComponent:這裏是Car,就是具體的汽車,未裝飾的汽車
1
2
3
4
5
6
7
|
//ConcreteComponent:具體的對象
class
Car
implements
ICar{
@Override
public
void
move() {
System.out.println(
"汽車移動"
);
}
}
|
裝飾抽象類Decorator:SuperCar這裏須要持有一個真實對象的引用,也就是Car對象
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//Decorator:裝飾抽象類
class
SuperCar
implements
ICar{
protected
ICar car;
//持有一個真實對象的引用
@Override
public
void
move() {
car.move();
//這裏調用真實對象的移動方法
}
//構造的時候傳參
public
SuperCar(ICar car) {
super
();
this
.car = car;
}
}
|
開始實現具體的裝飾對象ConcreteDecorator:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
//ConcreteDecorator:就是具體的裝飾對象
class
FlayCar
extends
SuperCar {
public
FlayCar(ICar car) {
super
(car);
}
//這裏就是新增的功能
public
void
flay(){
System.out.println(
"---天上飛"
);
}
@Override
public
void
move() {
super
.move();
flay();
//在原有移動的基礎上,裝飾了一個fly的功能
}
}
//ConcreteDecorator:就是具體的裝飾對象
class
WaterCar
extends
SuperCar {
public
WaterCar(ICar car) {
super
(car);
}
//這裏就是新增的功能
public
void
swim(){
System.out.println(
"---水裏遊"
);
}
@Override
public
void
move() {
super
.move();
swim();
//在原有移動的基礎上,裝飾了一個swim的功能
}
}
|
測試代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
static
void
main(String[] args) {
Car car =
new
Car();
car.move();
//這裏打印未增長新功能的時候:汽車移動
System.out.println(
"--------增長飛行功能-------"
);
FlayCar flyCar =
new
FlayCar(car);
//將真實對象傳入裝飾對象中
flyCar.move();
//這裏就是增長了飛行後的裝飾
System.out.println(
"--------增長潛水功能-------"
);
WaterCar waterCar =
new
WaterCar(car);
//將真實對象傳入裝飾對象中
waterCar.move();
//這裏就是增長了潛水功能後的裝飾
}
|
控制檯結果就是:
汽車移動
--------增長飛行功能-------
汽車移動
---天上飛
--------增長潛水功能-------
汽車移動
---水裏遊
整個例子的類圖結構以下:
3、總結
裝飾模式(Decorator)也叫包裝器模式(Wrapper)
裝飾模式下降系統的耦合度,能夠動態的增長或刪除對象的職責,並使得須要裝飾的具體構建類和具體裝飾類能夠獨立變化
以便增長新的具體構建類和具體裝飾類。
優勢:
擴展功能強,相比繼承來講更靈活。繼承的話會致使子類個數增長。而裝飾者模式不會出現這種狀況。
能夠對一個對象進行屢次裝飾,創造出不一樣行爲的組合,獲得功能更增強大的對象。
具體構建類和具體裝飾類能夠獨立變化,用戶能夠根據須要本身增長新的構件子類和具體裝飾類。
缺點:
產生不少小對象,大量小對象會佔據內存。必定程度上影響了性能。
裝飾模式易於出錯,調試排查比較麻煩。
開發中應用的場景:
IO中輸入流和輸出流
Swing包中圖形界面構件功能
Servlet API中提供了一個request對象的Decorator設計模式的默認實現類HttpServletRequestWrapper,加強了request對象的功能。
Struts2中,request,response,session對象的處理。
裝飾模式和橋接模式的區別:
兩個模式都是爲了解決過多子類對象的問題,橋接模式是對象自身有過多的維度,形成過多的子類。而讓維度分類後在搭建一個橋樑來聯繫起來。
而裝飾模式是解決在增長新功能的時候產生多個類的問題。
參考資料:
大話設計模式(帶目錄完整版).pdf
HEAD_FIRST設計模式(中文版).pdf
尚學堂_高淇_java300集最全視頻教程_【GOF23設計模式】