1. 程式人生 > >Java設計模式:裝飾者模式

Java設計模式:裝飾者模式

原文連結 譯者:秦建平

裝飾者模式可以給已經存在的物件動態的新增能力。下面,我將會用一個簡單的例子來演示一下如何在程式當中使用裝飾者模式。

1.裝飾者模式
讓我們來假設一下,你正在尋找一個女朋友。有很多來自不同國家的女孩,比如:美國,中國,日本,法國等等,他們每個人都有不一樣的個性和興趣愛好,如果需要在程式當中模擬這麼一種情況的話,假設每一個女孩就是一個Java類的話,那麼就會有成千上萬的類,這樣子就會造成類的膨脹,而且這樣的設計的可擴充套件性會比較差。因為如果我們需要一個新的女孩,就需要建立一個新的Java類,這實際上也違背了在程式開發當中需要遵循的OCP(對擴充套件開放,對修改關閉)原則。
讓我們來重新做另外一種設計,讓每一種個性或者興趣愛好成為一種裝飾從而可以動態地新增到每一個女孩的身上。

2.類圖結構

3.裝飾者模式示例程式碼
Girl.java

public abstract class Girl {
	String description = "no particular";

	public String getDescription(){
		return description;
	}
}

AmericanGirl.java

public class AmericanGirl extends Girl {

	public AmericanGirl() {
		description = "+American";
	}

}

EuropeanGirl.java

public class EuropeanGirl extends Girl {

	public EuropeanGirl(){
		description = "+European";
	}

}

GirlDecorator.java

public abstract class GirlDecorator extends Girl {

	public abstract String getDescription();

}

Science.java

public class Science extends GirlDecorator {

	private Girl girl;

	public Science(Girl girl){
		this.girl = girl;
	}

	@Override
	public String getDescription() {
		return this.girl.getDescription() + "+Like Science";
	}

	public void caltulateStuff() {
		System.out.println("scientific calculation!");
	}
}

Art.java

public class Art extends GirlDecorator {

	private Girl girl;

	public Art(Girl girl){
		this.girl = girl;
	}

	@Override
	public String getDescription() {
		return this.girl.getDescription() + "+Like Art";
	}

	public void draw() {
		System.out.println("draw pictures!");
	}
}

Main.java

public class Main {

	public static void main(String[] args) {
		//普通美國女孩
		Girl g1 = new AmericanGirl();
		System.out.println(g1.getDescription());

		//喜歡科學的
		Science g2 = new Science(g1);
		System.out.println(g2.getDescription());

		//喜歡藝術的
		Art g3 = new Art(g2);
		System.out.println(g3.getDescription());
	}

}

4.裝飾者模式在JDK中的運用
Java當中的IO是運用了裝飾者模式的最典型的例子。
下面是一個簡單的例子,通過BufferedReader物件來裝飾InputStreamReader物件:

BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
//System.in is an InputStream object


秦建平

專注於Android、Java、效能優化,《Android程式設計寶典》作者,嚮往自由,為目標前行