Java中的裝飾器設計模式示例

裝飾者設計模式用於在運行時修改對象的功能。同時,同一類的其他實例不受此影響,因此個別對象獲得了修改後的行為。裝飾者設計模式是結構設計模式之一(如適配器模式橋接模式組合模式),並使用抽象類或介面與組合實現。

裝飾者設計模式

我們使用繼承或組合來擴展物件的行為,但這是在編譯時期完成的,並且適用於該類別的所有實例。我們無法在運行時添加任何新功能或移除任何現有行為 – 這就是裝飾者模式派上用場的時候。假設我們想要實現不同種類的汽車 – 我們可以創建介面Car來定義組裝方法,然後我們可以有一輛基本汽車,再進一步擴展為運動汽車和豪華汽車。實現層次結構如下圖所示:但是,如果我們想要在運行時獲得同時具有運動汽車和豪華汽車功能的汽車,那麼實現就變得復雜了,而且如果我們還想要指定先添加哪些功能,它就變得更加複雜。現在想象一下,如果我們有十種不同種類的汽車,使用繼承和組合的實現邏輯將無法管理。為了解決這種編程情況,我們在Java中應用裝飾者模式。我們需要以下類型來實現裝飾者設計模式。

  1. 組件介面 – 定義將被實現的方法的介面或抽象類別。在我們的案例中,Car 將是組件介面。

    package com.journaldev.design.decorator;
    
    public interface Car {
    
    	public void assemble();
    }
    
  2. 組件實現 – 組件介面的基本實現。我們可以將 BasicCar 類別作為我們的組件實現。

    package com.journaldev.design.decorator;
    
    public class BasicCar implements Car {
    
    	@Override
    	public void assemble() {
    		System.out.print("Basic Car.");
    	}
    
    }
    
  3. 裝飾者 – 裝飾者類實現組件接口,並且與組件接口存在HAS-A關係。組件變數應該對子裝飾者類可訪問,因此我們將使這個變數受保護。

    package com.journaldev.design.decorator;
    
    public class CarDecorator implements Car {
    
    	protected Car car;
    	
    	public CarDecorator(Car c){
    		this.car=c;
    	}
    	
    	@Override
    	public void assemble() {
    		this.car.assemble();
    	}
    
    }
    
  4. 具體裝飾者 – 擴展基本裝飾者功能,並根據需要修改組件行為。我們可以有具體裝飾者類,如 LuxuryCarSportsCar

    package com.journaldev.design.decorator;
    
    public class SportsCar extends CarDecorator {
    
    	public SportsCar(Car c) {
    		super(c);
    	}
    
    	@Override
    	public void assemble(){
    		super.assemble();
    		System.out.print(" 添加跑車的特色。");
    	}
    }
    
    package com.journaldev.design.decorator;
    
    public class LuxuryCar extends CarDecorator {
    
    	public LuxuryCar(Car c) {
    		super(c);
    	}
    	
    	@Override
    	public assemble(){
    		super.assemble();
    		System.out.print(" 添加豪華車的特色。");
    	}
    }
    

裝飾者設計模式 – 類別圖

裝飾者設計模式測試程式

package com.journaldev.design.test;

import com.journaldev.design.decorator.BasicCar;
import com.journaldev.design.decorator.Car;
import com.journaldev.design.decorator.LuxuryCar;
import com.journaldev.design.decorator.SportsCar;

public class DecoratorPatternTest {

	public static void main(String[] args) {
		Car sportsCar = new SportsCar(new BasicCar());
		sportsCar.assemble();
		System.out.println("\n*****");
		
		Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
		sportsLuxuryCar.assemble();
	}

}

請注意,客戶端程式可以在運行時創建不同類型的物件,並且他們也可以指定執行順序。上述測試程式的輸出為:

Basic Car. Adding features of Sports Car.
*****
Basic Car. Adding features of Luxury Car. Adding features of Sports Car.

裝飾者設計模式 – 重要要點

  • 裝飾者設計模式有助於提供運行時修改能力,因此更加靈活。當選擇數量增加時,易於維護和擴展。
  • 裝飾者設計模式的缺點是它使用了許多類似類型的物件(裝飾者)。
  • 裝飾者模式在Java IO類別中被廣泛使用,例如FileReader、BufferedReader等。

Source:
https://www.digitalocean.com/community/tutorials/decorator-design-pattern-in-java-example