Java中的23個設計模式 【結構型模式】 中的 【裝飾模式】
阿新 • • 發佈:2021-02-20
文章目錄
設計模式分類
- 建立型模式
- 單例模式、工廠模式、抽象工廠模式、建造者模式、原型模式
- 關注物件的建立過程
- 結構型模式
- 介面卡模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式
- 關注物件和類的組織
- 行為型模式
- 模板方法模式、
命令模式、迭代器模式、觀察者模式、中介模式、備忘錄模式、直譯器模式、狀態模式、策略模式、責任鏈模式、訪問者模式- 關注系統同對象之間的相互互動,研究系統在執行時物件之間的相互通訊和協作,進一步明確物件的職責
裝飾模式(decorator)
介紹
- 職責
- 動態的為一個物件增加新的功能
- 裝飾模式是一種用於代替繼承的技術,無需通過繼承增加子類就能擴充套件物件的新功能。使用物件的關聯關係代替繼承關係,更加靈活,同時避免型別體系的快速膨脹。
實現細節
- Component抽象構件角色
- 真實物件和裝飾物件有相同的介面。這樣,客戶端物件就能夠以與真實物件相同的方式同裝飾物件互動
- ConcreateComponent具體構件角色(真實物件)
- io流中的FileInputStream、FileOutputStream
- Decorator裝飾角色
- 持有一個抽象構件的引用。裝飾物件接受所有客戶端的請求,並把這些請求轉發給真實的物件。這樣,就能在真實物件呼叫前後增加新的功能。
- ConcreateDecorator具體裝飾角色
- 負責給構件物件增加新的責任
IO流實現細節(裝飾模式)
- Component抽象構件角色
- IO流中的InputStream、OutputStream、Reader、Writer
- ConcreteComponent具體構件角色
- IO流中的FileInputStream、FileOutputStream
- Decorator裝飾角色
- 持有一個抽象構件的引用:IO流中FilterInputStream、FilterOutputStream
- ConcreateDecorator具體裝飾角色
- 負責給構件物件增加新的責任。IO流中BufferedOutputStream、BufferedInputStream等
開發中使用的場景
- IO中輸入流和輸出流的設計
- Swing包中圖形介面構件功能
- Servlet API中提供了一個request物件的Decorator設計模式的預設實現類HttpServletRequestWrapper,HttpServletRequestWrapper類,增強了request物件的功能
- Struts2中,request,response,session物件的處理
總結
- 裝飾模式(Decorator)也叫包裝器模式(Wrapper)
- 裝飾模式降低系統的耦合度,可以動態的增加或刪除物件的職責,並使得需要裝飾的具體構建類和具體裝飾類可以獨立變化,以便增加新的具體構建類和具體裝飾類
優缺點
優點
- 擴充套件物件功能,比繼承靈活,不會導致類個數急劇增加
- 可以對一個物件進行多次裝飾,創造出不同行為的組合,得到功能更加強大的物件
- 具體構建類和具體裝飾類可以獨立變化,使用者可以根據需要自己增加新的具體構件子類和具體裝飾子類
缺點
- 產生很多小物件,大量小物件佔據記憶體,一定程度上影響效能
- 裝飾模式易於出錯,除錯排查比較麻煩
與橋接模式的區別
兩個模式都是為了解決過多子類物件問題。但他們的誘因不一樣。
橋接模式是物件自身現有機制沿著多個維度變化,是既有部分不穩定
裝飾模式是為了增加新的功能。
程式碼
以汽車為例,為汽車增加新的功能,天上飛行,水上漂行,正常行駛
- 汽車抽象類(ICar)——抽象構件
- 汽車實現類(Car)——具體構件物件
- 裝飾器類(SuperCar)——裝飾器角色
- 修飾類(FlyCar、WaterCar、AICar)——具體裝飾物件
圖解:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-K4AAyy7Y-1613681397452)(img\裝飾模式.png)]
汽車抽象類(ICar)——抽象構件
/**
* 抽象構件
* @author 橙汁兒Drk
*
*/
public interface ICar {
void move();
}
汽車實現類(Car)——具體構件物件
//具體構件物件
class Car implements ICar{
@Override
public void move() {
System.out.println("陸地上跑");
}
}
裝飾器類(SuperCar)——裝飾器角色
//裝飾器角色
class SuperCar implements ICar{
protected ICar car ;
public SuperCar(ICar car) {
super();
this.car = car;
}
@Override
public void move() {
car.move();
}
}
修飾類(FlyCar、WaterCar、AICar)——具體裝飾物件
-
FlyCar
class FlyCar extends SuperCar{ public FlyCar(ICar car) { super(car); } public void fly() { System.out.println("天上飛"); } @Override public void move() { super.move(); fly(); } }
-
WaterCar
class WaterCar extends SuperCar{ public WaterCar(ICar car) { super(car); } public void swim() { System.out.println("水上游"); } @Override public void move() { super.move(); swim(); } }
-
AICar
class AICar extends SuperCar{ public AICar(ICar car) { super(car); } public void autoMove() { System.out.println("自動駕駛"); } @Override public void move() { super.move(); autoMove(); } }
測試
package decorator;
public class Client {
public static void main(String[] args) {
Car car = new Car();
car.move();
System.out.println("增加新的功能:飛行——————————");
FlyCar flycar = new FlyCar(car);
flycar.move();
System.out.println("增加新的功能:AI——————————");
AICar aicar = new AICar(flycar);
aicar.move();
System.out.println("增加兩個功能:飛行、水上漂——————————");
WaterCar waterCar2 = new WaterCar(new FlyCar(new Car()));
waterCar2.move();
}
}
//結果————————————————————類似於IO流中的操作—————————————————————————
陸地上跑//原本汽車的move方法
增加新的功能:飛行——————————
陸地上跑
天上飛//在原有的方法上,增加了新的飛行
增加新的功能:AI——————————
陸地上跑
天上飛
自動駕駛
增加兩個功能:飛行、水上漂——————————
陸地上跑
天上飛
水上游