從簡單工廠模式到抽象工廠模式的思考

又一次看到了工廠模式,經過思考之後對工廠模式又有了新的認識。首先舉例說下使用工廠模式的好處:現在有一個繪畫的類(Print)裏面有一個方法print()需要調用RedPen裏面的write()方法,初學的時候是這樣寫的:

RedPen類:

public class RedPen {
	public void write(){
		System.out.println("use red color writing....");
	}
}
Print類:

public class Print {
	private RedPen pen;
	
	public Print() {
		super();
	}
	public Print(RedPen pen){
		this.pen=pen;
	}
	public void print(){
		pen.write();
		
	}
	public static void main(String[] args) {
		
		RedPen redPen=new RedPen();
		Print print=new Print(redPen);
		print.print();
	}

}
這樣寫似乎沒有什麼問題,A類需要調用B類的方法,直接New一個B類實例然後調用實例的方法;但是當考慮到程序的變更和問題的擴展時,問題也就出現了,比如現在我使用藍色的筆(BluePen)來寫,對於上面的代碼,由於Print類裏面構造的時候直接使用了RedPen是的程序的耦合度最高(硬編碼耦合),所以當需要修改的時候,要重新修改Print的構造方法改成:

public Print(BluePen pen),但是如果Print依賴的類跟多的話(例如還有畫刷,形狀等)都採用上述方式的話,當程序需要對功能有所調整的時候需要修改的地方會更多,因此我們需要使用接口:

還是以上述例子,我們如果增加一個Pen的接口,Print類依賴於Pen,有一個用來生產Pen的工廠(PenFactory)擴展之後如下圖:

因此Print的代碼改爲:

public class Print {
	private Pen pen;
	
	public Print() {
		super();
	}
	public Print(Pen pen){
		this.pen=pen;
	}
	public void print(){
		pen.write();
		
	}
	public static void main(String[] args) {
		PenFactory factory=new PenFactory();
		Print print=new Print(factory.getPen("blue"));
		print.print();
	}

}
工廠類:

public class PenFactory {
	public Pen getPen(String color){
		if("red".equals(color))
			return new RedPen();
		else
			return new BluePen();
	}
}
顯然經過重新設計之後,如果需要改成使用BluePen則只需要修改getPen()的參數即可,也就避免了對Print類作大量修改,這就就簡單工廠模式,在簡單工廠模式創建產品的方法中,根據傳入的參數來判斷到底創建哪個產品,如果不需要做判斷的話則可以改成工廠模式:

修改之後Print類的代碼改成:

public class Print {
	private Pen pen;
	
	public Print() {
		super();
	}
	public Print(Pen pen){
		this.pen=pen;
	}
	public void print(){
		pen.write();
		
	}
	public static void main(String[] args) {
		PenFactory factory=new RedPenFactory();
		Print print=new Print(factory.getPen());
		print.print();
	}

}
到此爲止我們已經實現了客戶端代碼(Print)與需要調用類的代碼分離,但是Print卻與具體的工廠類耦合起來,因此爲了進一步達到解耦效果,則可以使用抽象工廠方法:

只需要在上面的基礎上增加一個生產工廠的類:

自此就完成了Print與工廠類的完全解耦,在PenFactoryFactory的getPenFactory裏面需要根據不同的參數返回不同的工廠實例。其實不管是簡單工程模式還是抽象工廠模式都是工廠模式,不過是在不同的類裏面判斷而已,如果是直接返回被調用的對象,只是簡單工廠;如果是返回的工廠對象,則是抽象工廠。




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