抽象工廠模式

抽象工廠模式

抽象工廠模式是所有形態的工廠模式中最爲抽象和最具一般性的一種形態。

爲了方便引進抽象工廠模式,引進一個新概念:產品族(Product Family)。所謂產品族,是指位於不同產品等級結構,功能相關聯的產品組成的家族。如圖:



圖中一共有四個產品族,分佈於三個不同的產品等級結構中。只要指明一個產品所處的產品族以及它所屬的等級結構,就可以唯一的確定這個產品。

引進抽象工廠模式

所謂的抽象工廠是指一個工廠等級結構可以創建出分屬於不同產品等級結構的一個產品族中的所有對象。如果用圖來描述的話,如下圖:


抽象工廠模式的通用類圖如圖

圖中描述的東西用產品族描述如下:

抽象工廠(Abstract Factory)角色:擔任這個角色的是工廠方法模式的核心,它是與應用系統商業邏輯無關的。

具體工廠(Concrete Factory)角色:這個角色直接在客戶端的調用下創建產品的實例。這個角色含有選擇合適的產品對象的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的。

抽象產品(Abstract Product)角色:擔任這個角色的類是工廠方法模式所創建的對象的父類,或它們共同擁有的接口。

具體產品(Concrete Product)角色:抽象工廠模式所創建的任何產品對象都是某一個具體產品類的實例。這是客戶端最終需要的東西,其內部一定充滿了應用系統的商業邏輯。
抽象工廠模式模擬代碼
抽象產品類A
public abstract class AbstractProductA {
	 
	//每個產品共有的方法
	 
	public void shareMethod(){
		System.out.println("抽象工廠A共有方法");
	}
	 
	//每個產品相同方法,不同實現
	 
	public abstract void doSomething();
	 
}
產品A1的實現
public class ProductA1 extends AbstractProductA {

	@Override
	public void doSomething() {
		// TODO Auto-generated method stub
		System.out.println("產品A1的實現方法");
	}

}
產品A2的實現
public class ProductA2 extends AbstractProductA {

	@Override
	public void doSomething() {
		// TODO Auto-generated method stub
		System.out.println("產品A2的實現方法");
	}

}
類似抽象產品類B、產品B1、產品B2
public abstract class AbstractProductB {
	 
	//每個產品共有的方法
	 
	public void shareMethod(){
		System.out.println("抽象工廠B共有方法");
	}
	 
	//每個產品相同方法,不同實現
	 
	public abstract void doSomething();
	 
}
public class ProductB1 extends AbstractProductB {

	@Override
	public void doSomething() {
		// TODO Auto-generated method stub
		System.out.println("產品B1的實現方法");
	}

}
public class ProductB2 extends AbstractProductB {

	@Override
	public void doSomething() {
		// TODO Auto-generated method stub
		System.out.println("產品B2的實現方法");
	}

}
抽象工廠類
public abstract class AbstractCreator {

	//創建A產品家族
	 
	public abstract AbstractProductA createProductA();
	 
	//創建B產品家族
	 
	public abstract AbstractProductB createProductB();
	
}
注意 有N個產品族,在抽象工廠類中就應該有N個創建方法。
產品等級1實現類
public class Creator1 extends AbstractCreator {

	@Override
	public AbstractProductA createProductA() {
		// TODO Auto-generated method stub
		return new ProductA1();
	}

	@Override
	public AbstractProductB createProductB() {
		// TODO Auto-generated method stub
		return new ProductB1();
	}

}
產品等級2實現類
public class Creator2 extends AbstractCreator {

	@Override
	public AbstractProductA createProductA() {
		// TODO Auto-generated method stub
		return new ProductA2();
	}

	@Override
	public AbstractProductB createProductB() {
		// TODO Auto-generated method stub
		return new ProductB2();
	}

}
注意 有M個產品等級就應該有M個實現工廠類,在每個實現工廠中,實現不同產品族的生產任務。
測試代碼如下
public class testdemo {
	
	public static void main(String[] args) {
		 
		//定義出兩個工廠
		 
		AbstractCreator creator1 = new Creator1();
		 
		AbstractCreator creator2 = new Creator2();
		 
		//產生A1對象
		 
		AbstractProductA a1 = creator1.createProductA();
		 
		//產生A2對象
		 
		AbstractProductA a2 = creator2.createProductA();
		 
		//產生B1對象
		 
		AbstractProductB b1 = creator1.createProductB();
		 
		//產生B2對象
		 
		AbstractProductB b2 = creator2.createProductB();
		 
		a1.shareMethod();
		a1.doSomething();
		
		a2.shareMethod();
		a2.doSomething();
		
		b1.shareMethod();
		b1.doSomething();
		
		b2.shareMethod();
		b2.doSomething();
		
	}

}
結果
抽象工廠A共有方法
產品A1的實現方法
抽象工廠A共有方法
產品A2的實現方法
抽象工廠B共有方法
產品B1的實現方法
抽象工廠B共有方法
產品B2的實現方法
抽象工廠模式的優點
         封裝性,每個產品的實現類不是高層模塊要關係的,要關心的是什麼?是接口,是抽象,它不關心對象是如何創建出來,這由誰負責呢?工廠類,只要知道工廠類是誰,我就能創建出一個需要的對象,省時省力,優秀設計就應該如此。
         產品族內的約束爲非公開狀態。例如生產男女比例的問題上,猜想女媧娘娘肯定有自己的打算,不能讓女盛男衰,否則女性的優點不就體現不出來了嗎?那在抽象工廠模式,就應該有這樣的一個約束:每生產1個女性,就同時生產出1.2個男性,這樣的生產過程對調用工廠類的高層模塊來說是透明的,它不需要知道這個約束,我就是要一個黃色女性產品就可以了,具體的產品族內的約束是在工廠內實現的。

抽象工廠模式的缺點
         抽象工廠模式的最大缺點就是產品族擴展非常困難,爲什麼這麼說呢?我們以通用代碼爲例,如果要增加一個產品C,也就是說有產品家族由原來的2個,增加到3個,看看我們的程序有多大改動吧!抽象類AbstractCreator要增加一個方法createProductC(),然後,兩個實現類都要修改,想想看,這在項目中的話,還這麼讓人活!嚴重違反了開閉原則,而且我們一直說明抽象類和接口是一個契約,改變契約,所有與契約有關係的代碼都要修改,這段代碼叫什麼?叫“有毒代碼”,——只要這段代碼有關係,就可能產生侵害的危險!

發佈了73 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章