Java學習筆記之--------工廠方法模式

不使用工廠模式

我們現在有一個汽車方法,實現如下:

public interface Car {
	void run();
}
public class Audi implements Car {
	@Override
	public void run() {
		System.out.println("奧迪在跑");
	}
}
public class Byd implements Car {
	@Override
	public void run() {
		System.out.println("比亞迪在跑");
	}
}
public class Client01 {
	public static void main(String[] args) {
		Car c1 = new Audi();
		Car c2 = new Byd();
		c1.run();
		c2.run();
	}
} 

類圖如下:

可以看到,在使用過程中,調用者既要依賴接口,也要依賴具體類和方法。

工廠模式的核心思想

實現創建者和調用者的分離:實例化對象的時候用工廠方法代替new操作。將選擇實現類、創建對象統一管理和控制,從而將調用者跟我們的實現解耦。

簡單工廠模式

引入工廠模式的思想,上面的代碼可以優化一下,將實例化具體類的代碼封裝起來,新建一個CarFactory,具體實現如下:

public class CarFactory {
	public static Car createCar(String type){
		if ("奧迪".equals(type)){
			return new Audi();
		} else if ("比亞迪".equals(type)){
			return new Byd();
		} else {
			return null;
		}
	}
} 
public class Client02 {
	public static void main(String[] args) {
		Car c1 = CarFactory.createCar("奧迪");
		Car c2 = CarFactory.createCar("比亞迪");
		c1.run();
		c2.run();
	}
} 

類圖如下:

這樣我們的調用者只需要與CarFactory和Car發生依賴關係。體現了工廠模式的思想,實現了創建者和調用者的分離。

我們稱這種處理方法爲簡單工廠模式或者靜態工廠模式,就是工廠類一般是用靜態方法,通過接收的參數的不同來返回不同的對象實例。值得一提的是,簡單工廠模式不是一種設計模式,更像是一種編程習慣。

簡單工廠模式還有另外一種寫法:

public class CarFactory2 {
	public static Car createAudi(){
		return new Audi();
	}
	public static Car createByd(){
		return new Byd();
	}
} 

雖然簡單工廠模式優化了我們最初的代碼,但是還是存在一定的問題。如果增加新產品,不修改代碼的話是實現不了的。針對這一問題,我們需要用到工廠方法模式。

工廠方法模式

工廠方法模式定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。工廠方法讓類把實例化推遲到子類。

需要注意的是,工廠方法讓子類決定要實例化的類是哪一個,“決定”並不是指模式允許子類本身在運行時做決定,而是指在編寫創建者類時,不需要知道實際創建的產品是哪一個。選擇了使用哪個子類,自然就決定了實際創建的產品是什麼。

工廠方法模式提供了一組實現了相同接口的工廠類,代碼實現如下(Car、Audi和Byd的代碼和上面簡單工廠模式的代碼相同):

public interface CarFactory {
	Car createCar();
} 
public class AudiFactory implements CarFactory {
	@Override
	public Car createCar() {
		return new Audi();
	}
}
public class BydFactory implements CarFactory {
	@Override
	public Car createCar() {
		return new Byd();
	}
}
public class Client {
	public static void main(String[] args) {
		Car c1 = new AudiFactory().createCar();
		Car c2 = new BydFactory().createCar();

		c1.run();
		c2.run();
	}
} 

類圖如下:

調用者在實例化對象時,只需要依賴接口,而不是具體類。

工廠方法模式和簡單工廠模式最大的不同在於,簡單工廠模式只有一個(對於一個項目或者一個獨立模塊而言)工廠類,而工廠方法模式有一組實現了相同接口的工廠類。

開閉原則(OCP):一個軟件的實體應該對擴展開放,對修改關閉。

簡單工廠模式和工廠方法模式比較

 結構複雜度:從結構複雜度來看,很顯然簡單工廠模式佔優勢。簡單工廠模式只需要一個工廠類,而工廠方法模式的工廠類隨着產品類個數增加而增加,這無疑會使類的個數越來越多,從而增加了結構的複雜程度。

代碼複雜度:代碼複雜度和結構複雜度是一堆矛盾,既然簡單工廠模式在結構方面相對簡潔,那麼它在代碼方面肯定比工廠方法模式複雜。簡單工廠模式的工廠類隨着產品類的增加需要增加很多方法(或代碼),而工廠方法模式每個具體工廠類只完成單一任務,代碼簡潔。

客戶端編程難度:工廠方法模式雖然在工廠類的結構中引入了接口從而滿足了OCP,但是在客戶端編碼中需要對工廠類進行實例化。而簡單工廠模式的工廠類是個靜態類,在客戶端無需實例化,這無疑是一個吸引人的優點。

管理上的難度:(1)擴展度:工廠方法模式完全滿足OCP,即它有非常好的擴展性。但是簡單工廠模式也具有良好的擴展性——擴展的時候僅需修改少量代碼(修改工廠類的代碼)就可以滿足擴展性的需求了。儘管這沒有完全滿足OCP,但我們不需要太拘泥於設計理論,即使是sun提供的Java官方工具中也有相當多沒有滿足OCP的例子。(2)維護性:假如某個具體產品類需要進行一定的修改,很可能需要修改對應的工廠類。當同時需要修改多個產品類的時候,工廠類的修改會變得相當麻煩(對號入座已經是一個問題了)。反而簡單工廠模式沒有這些麻煩,當多個產品類需要修改時,簡單工廠模式仍然僅需要修改唯一的工廠類(無論怎樣都能修改到滿足要求,大不了把這個類重寫)。

根據設計理論建議:工廠方法模式。但實際上,我們一般都用簡單工廠模式。

 

以上爲工廠方法模式的學習筆記,此文章爲尚學堂視頻的學習筆記+自己總結。參考資料:Head First 設計模式。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章