1. 程式人生 > 其它 >Java中的23個設計模式 【結構型模式】 中的 【裝飾模式】

Java中的23個設計模式 【結構型模式】 中的 【裝飾模式】

技術標籤:設計模型設計模式java大資料人工智慧區塊鏈

文章目錄

設計模式分類

  • 建立型模式
    • 單例模式、工廠模式、抽象工廠模式、建造者模式、原型模式
    • 關注物件的建立過程
  • 結構型模式
    • 介面卡模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式
    • 關注物件和類的組織
  • 行為型模式
    • 模板方法模式、命令模式、迭代器模式、觀察者模式、中介模式、備忘錄模式、直譯器模式、狀態模式、策略模式、責任鏈模式、訪問者模式
    • 關注系統同對象之間的相互互動,研究系統在執行時物件之間的相互通訊和協作,進一步明確物件的職責

裝飾模式(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——————————
陸地上跑
天上飛
自動駕駛
增加兩個功能:飛行、水上漂——————————
陸地上跑
天上飛
水上游