Java設計模式及應用場景之《簡單工廠模式》

一、簡單工廠模式定義

簡單工廠提供了一個創建對象實例的功能,而無需關心其具體實現。被創建對象實例的類型可以是抽象類、接口,也可以是具體的類。

二、簡單工廠模式的結構和說明

在這裏插入圖片描述

  • Api: 定義所需要的功能接口。
  • ApiImplA、ApiImplB: Api接口的實現類,可能會有更多個。
  • Factory: 工廠類,根據條件選擇合適的實現類來創建Api的對象。

三、簡單工廠模式示例

  假設有一個訂單支付功能,我們有兩種支付方式,一種支付寶支付,一種微信支付。用戶在客戶端進行支付的時候,需要從這兩種支付方式中選取一種,來進行支付操作。

首先我們有一個支付接口:

/**
 * 支付接口
 */
public interface Pay {

	/**
	 * 支付操作方法
	 */
	public void pay();
}

然後我們有兩個具體支付業務類:

/**
 * 支付寶支付
 */
public class ZhiFuBaoPay implements Pay {

	@Override
	public void pay() {
		System.out.println("通過支付寶進行支付...");
	}

}
/**
 * 微信支付
 */
public class WeiXinPay implements Pay {

	@Override
	public void pay() {
		System.out.println("通過微信進行支付...");
	}

}

定義工廠類:

/**
 * 工廠類,用來創造具體支付業務對象
 */
public class PayFactory {
	
	private PayFactory() {} // 防止客戶端無謂的創建工廠實例,將構造方法私有化

	/**
	 * 具體的創造支付業務對象實例的方法
	 * @param type 從外部傳入的選擇條件
	 * @return
	 */
	public static Pay createPay(String type){
		//應該根據某些條件去選擇究竟創建哪一個具體的實現對象
		//這些條件可以從外部傳入,也可以從其它途徑獲取
		//如果只有一個實現,可以省略條件,因爲沒有選擇的必要
		
		Pay pay = null;
		if("ZFB".equals(type)){
			pay = new ZhiFuBaoPay();
		}else if("WX".equals(type)){
			pay = new WeiXinPay();
		}else{
			System.out.println("支付方式不正確");
		}
		
		return pay;
	}
	
}

那麼我們在客戶端用的時候,就可以這樣用:

public static void main(String[] args) {
		
	Pay pay = PayFactory.createPay("ZFB");
	pay.pay();// 輸出:通過支付寶進行支付...
		
}

四、可配置的簡單工廠模式示例

  如果我們新增一種支付方式的話,通過上邊說的模式,我們就需要修改工廠類:

/**
 * 具體的創造支付業務對象實例的方法
 * @param type 從外部傳入的選擇條件
 * @return
 */
public static Pay createPay(String type){
	//應該根據某些條件去選擇究竟創建哪一個具體的實現對象
	//這些條件可以從外部傳入,也可以從其它途徑獲取
	//如果只有一個實現,可以省略條件,因爲沒有選擇的必要
	
	Pay pay = null;
	if("ZFB".equals(type)){
		pay = new ZhiFuBaoPay();
	}else if("WX".equals(type)){
		pay = new WeiXinPay();
	}
	// 新增銀聯支付方式
	else if("YL".equals(type)){
		pay = new YinLianPay();
	}
	else{
		System.out.println("支付方式不正確");
	}
	
	return pay;
}

這樣肯定不是一個好的實現方式。一個解決的方法就是,將具體的實現類配置到配置文件中,在簡單工廠的方法裏面通過反射來獲取實現類。

配置文件中:
ZFB=com.pay.ZhiFuBaoPay WX=com.pay.WeiXinPay YL=com.pay.YinLianPay

我們的工廠類方法可以這樣實現:

/**
 1. 具體的創造支付業務對象實例的方法
 2. @param type 從外部傳入的選擇條件
 3. @return
 */
public static Pay createPay(String type){
	//應該根據某些條件去選擇究竟創建哪一個具體的實現對象
	//這些條件可以從外部傳入,也可以從其它途徑獲取
	//如果只有一個實現,可以省略條件,因爲沒有選擇的必要
	
	// 讀取配置文件的內容,這裏不介紹怎麼讀取配置文件了
	String payClazzName = getProperty(type);
	
	Pay pay = null;
	//用反射去創建具體對象實例
	try {
		pay = (Pay)Class.forName(payClazzName).newInstance();
	} catch (InstantiationException e) {
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}
	
	return pay;
}

五、簡單工廠模式的優缺點

優點:

  • 幫助封裝。 簡單工廠雖然很簡單,但是非常友好的幫助我們實現了組件的封裝,讓組件外部真正能實現面向接口編程。
  • 解耦。 通過簡單工廠,實現了調用類和具體實現類的解耦。

缺點:

  • 可能增加客戶端的複雜度。 如果通過客戶端傳過來的參數來選擇具體的實現類,就必須要求客戶端理解各個參數代表的含義,這樣會增加客戶端的複雜度。

六、簡單工廠模式的應用場景

  • 如果想要完全封裝隔離具體實現,讓外部只能通過接口來操作封裝類,那麼可以選擇簡單工廠模式。
  • 如果想要把對外創建對象的職責集中管理和控制,可以選擇簡單工廠模式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章