常用設計模式之工廠方法模式、抽象工廠模式

設計模式有23種之多,但是我目前常用到可能就那麼幾種,之前一遍文章已經對單例模式做了詳細的解釋了,(java中單例模式的多種實現),所以今天這篇文章主要要對設計模式中常用的創造型模式中的另外兩種模式 :工廠方法模式、抽象工廠模式進行淺談一番。

1.在講到兩種模式之前,我們先來了解一下簡單工廠模式(注:簡單工廠不屬於23中設計模式),簡單工廠模式分爲三種:簡單普通工廠、多方法工廠、靜態多方法工廠。

接下來將會用一個實例來仔細講一下三種模式:該實例是使用一個設計者的接口,我們這邊有兩個他的實現(手遊設計和動漫設計):

/**
 * 創建一個設計遊戲和 設計動漫的共同接口 (普通簡單工廠方法)
 * @author leo
 *
 */
public interface Designer {
	/**
	 * 設計方法
	 */
	public void design();
}
以及他的兩個實現:

/**
 * 動漫設計實現類
 * @author leo
 *
 */
public class CartoonDesigner implements Designer{

	@Override
	public void design() {
		System.out.println("我們只設計動漫,不賣萌!");
		
	}
}
/**
 * 手機遊戲設計類
 * @author leo
 *
 */
public class GameDesigner implements Designer{

	@Override
	public void design() {
		System.out.println("我們只設計遊戲,不搞基!");
		
	}

}
①普通簡單工廠模式的,我們要創建一個普通工廠類,

/**
 * 創建設計工廠類
 * @author leo
 *
 */
public class DesignFactory {
	/**
	 *  根據闖進來的字符串的類型不同,來創建不同的對象,
	 * @param type
	 * @return
	 */
	public  Designer product(String type){
		if(type.isEmpty()){
			return null;
		}else if("game".equals(type)){
			return new GameDesigner();
		}else if("cartoon".equals(type)){
			return new CartoonDesigner();
		}
		return null;
	}
}
②.對於普通簡單工廠而言;萬一用戶在創建對象時,用戶傳遞進來的參數有錯就無法創建對象,這樣風險過於大。所以就可以第二種誕生:根據不同方法創建不同對象的工廠類。

/**
 * 多個方法簡單工廠類
 * @author leo
 *
 */
public class DesignMoreFactory {
		/**
		 * 創建卡通設計對象
		 * @return
		 */
		public Designer createCartoonDesigner(){
			return new CartoonDesigner();
		}
		/**
		 * 創建遊戲設計對象
		 * @return
		 */
		public Designer createGameDesigner(){
			return new GameDesigner();
		}
}
③.對於第一二種而言,都是需要創建對象後,才能去調用的對象的方法,這樣也很不實用。所以第三種方法就結合了第一二種工廠類的缺陷應運而生的;靜態多種方法工廠類。

/**
 * 靜態多方法工廠類
 * @author leo
 *
 */
public class DesignStaticFactory {
	/**
	 * 創建卡通設計對象
	 * @return
	 */
	public static Designer createCartoonDesigner(){
		return new CartoonDesigner();
	}
	/**
	 * 創建遊戲設計對象
	 * @return
	 */
	public static Designer createGameDesigner(){
		return new GameDesigner();
	}
}

④,三種工廠類寫完之後,測試下

<pre name="code" class="java">public class TestDesignerFactory {
	public static void main(String[] args) {
		DesignFactory factory = new DesignFactory();
		//工廠獲取 對象
		Designer designer = factory.product("cartoon");
		designer.design();
		
		DesignMoreFactory factory2 = new DesignMoreFactory();
		//多方法工廠 
		Designer designer2 =factory2.createGameDesigner();
		designer2.design();
		//靜態多方法工廠
		Designer designer3 =DesignStaticFactory.createCartoonDesigner();
		designer3.design();
	}
}

打印出來的:我們只設計動漫,不賣萌!
我們只設計遊戲,不搞基!
我們只設計動漫,不賣萌!

總體來說,工廠模式適合:凡是出現了大量的產品需要創建,並且具有共同的接口時,可以通過工廠方法模式進行創建。在以上的三種模式中,第一種如果傳入的字符串有誤,不能正確創建對象,第三種相對於第二種,不需要實例化工廠類,所以,大多數情況下,我們會選用第三種——靜態工廠方法模式。

2.工廠方法模式:簡單工廠模式有一個問題就是,類的創建依賴工廠類,也就是說,如果想要拓展程序,必須對工廠類進行修改, 這違背了閉包原則,所以,從設計角度考慮,有一定的問題,如何解決?就用到工廠方法模式(factoryMethod), 創建一個工廠接口(Provider)和創建多個工廠實現類。
①例子還是上面那個例子:然後我們創建工廠類的接口:

/**
 * 簡單工廠模式有一個問題就是,類的創建依賴工廠類,也就是說,如果想要拓展程序,必須對工廠類進行修改,
 * 這違背了閉包原則,所以,從設計角度考慮,有一定的問題,如何解決?就用到工廠方法模式(factoryMethod),
 * 創建一個工廠接口(Provider)和創建多個工廠實現類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,
 * 不需要修改之前的代碼。
 * @author leo 
 *
 */
public interface Provider {
	public Designer produceDesigner();
}
然後創建實現的兩個工廠類:

遊戲設計工廠類:

/**
 * 實現工廠接口的 遊戲設計工廠類
 * @author leo
 *
 */
public class GamesFactory implements Provider{

	@Override
	public Designer produceDesigner() {
		
		return new GameDesigner();
	}

}
動漫設計工廠類:

/**
 * 實現工廠接口的 動漫設計工廠類
 * @author leo
 *
 */
public class CartoonDesignerFactory implements Provider{
	/**
	 * 
	 */
	@Override
	public Designer produceDesigner() {
		return new CartoonDesigner();
	}

}

寫個測試類測試下:
public class TestDesignerFactory {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		GamesFactory factory = new GamesFactory() ;
		Designer designer = factory.produceDesigner();
		designer.design();
		
	}

}
3.抽象工廠模式

工廠方法模式和抽象工廠模式不好分清楚,他們的區別如下:

<span style="font-size:10px;">工廠方法模式:
一個抽象產品類,可以派生出多個具體產品類。   
一個抽象工廠類,可以派生出多個具體工廠類。   
每個具體工廠類只能創建一個具體產品類的實例。

抽象工廠模式:
多個抽象產品類,每個抽象產品類可以派生出多個具體產品類。   
一個抽象工廠類,可以派生出多個具體工廠類。   
每個具體工廠類可以創建多個具體產品類的實例,也就是創建的是一個產品線下的多個產品。   
    
區別:
工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。   
工廠方法模式的具體工廠類只能創建一個具體產品類的實例,而抽象工廠模式可以創建多個。</span>
<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px;"><span style="font-size:10px;">工廠方法創建 "一種" 產品,他的着重點在於"怎麼創建",也就是說如果你開發,你的大量代碼很可能圍繞着這種產品的構造,初始化這些細節上面。也因爲如此,類似的產品之間有很多可以複用的特徵,所以會和模版方法相隨。</span></span>



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