Java設(shè)計模式中的簡單工廠模式解析
一、定義
定義: 提供一個創(chuàng)建對象實例的功能,而無須關(guān)心其具體實現(xiàn)。被創(chuàng)建實例的類型可以是接口、抽象類,也可以是具體的類。
PS: 我們都知道JAVA思想一直推崇“面向接口編程”。而接口的思想就是“封裝隔離”,即外部調(diào)用只能通過接口進(jìn)行調(diào)用,外部調(diào)用并不知道內(nèi)部具體實現(xiàn),也就是說外部調(diào)用和內(nèi)部實現(xiàn)是被接口隔離開的。那么只要接口不變,內(nèi)部實現(xiàn)的變化就不會影響到外部應(yīng)用,使得系統(tǒng)更加靈活,增加系統(tǒng)的擴(kuò)展性和可維護(hù)性,這也就是所謂的“接口是系統(tǒng)可拔插的保證”。
二、案例
假設(shè)有一個接口叫Api,然后有一個實現(xiàn)類Impl實現(xiàn)了它,如何在客戶端使用這個接口? So Easy !我們可以很快畫出這個案例的類圖并寫出代碼。

/**
* @ClassName Api
* @Description: 定義一個接口
* @author Jerry
* @date 2016年3月26日 下午11:27:32
*/
public interface Api {
/**
* @Description: 簡單實現(xiàn),傳入字符串打印
* @param @param str
*/
public void test(String str);
}
/**
* @ClassName Impl
* @Description: 實現(xiàn)Api接口
* @author Jerry
* @date 2016年3月27日 上午10:12:27
*/
public class Impl implements Api {
@Override
public void test(String str) {
System.out.println(str);
}
}
/**
* @ClassName Client
* @Description: 外部調(diào)用
* @author Jerry
* @date 2016年3月27日 上午10:13:35
*/
public class Client {
public static void main(String[] args) {
Api api = new Impl();
api.test("最愛你的人是我,你怎么舍得我難過");
}
}
三、使用模式的情況
如果我們仔細(xì)想想就會發(fā)現(xiàn),這樣的設(shè)計違背了接口的設(shè)計原則。因為客戶端必須知道哪些具體實例實現(xiàn)了接口,并沒有實現(xiàn)“封裝隔離”。其實這里只是用到了接口的多態(tài)功能。

/**
* @ClassName Factory
* @Description: 其余代碼和之前沒有變化,只增加這樣工廠類即可
* @author Jerry
* @date 2016年3月27日 上午10:23:30
*/
public class Factory {
/**
* @Description: 通常把Factory當(dāng)成一個工具類,不需要創(chuàng)建類實例,所以直接使用靜態(tài)方法
* @param 當(dāng)然可以添加參數(shù),使得客戶端可以選擇自己想要初始化的實例,但不推薦,后面會解釋原因
* @return Api 返回一個具體實現(xiàn)
* @throws
*/
public static Api createApi() {
return new Impl();
}
}
/**
* @ClassName Client
* @Description: 外部調(diào)用
* @author Jerry
* @date 2016年3月27日 上午10:13:35
*/
public class Client {
public static void main(String[] args) {
// Api api = new Impl();
Api api = Factory.createApi(); //無須在客戶端直接new具體實現(xiàn)
api.test("最愛你的人是我,你怎么舍得我難過");
}
}
一個簡單工廠理論上可以創(chuàng)造任何東西,所以又稱為“萬能工廠”。簡單工廠的本質(zhì)在于“選擇合適的實現(xiàn)類”,既然要選擇,那么肯定需要用戶去指定參數(shù),通常有以下3種:
- 來源于客戶端,指定參數(shù)。例如我們可以在創(chuàng)建實例的方法中加入?yún)?shù),這樣客戶端可以傳入具體參數(shù)來獲得自己想要的實例。但是這樣會帶來一個問題,客戶端必須知道每個參數(shù)的含義功能,使得向用戶暴露了一定的內(nèi)部實現(xiàn)細(xì)節(jié)。通常我們使用配置文件的寫法。
- 來源于配置文件,從配置文件獲取用于判斷的值,下文會具體介紹。
- 來源于程序運(yùn)行期的某個值,比如內(nèi)存中的某個變量值,此方法屬于動態(tài)實現(xiàn)。
- 使用配置文件進(jìn)行優(yōu)化 我們使用properties文件,放在Factory同一個包下。
- ImplClass=simpleFactory.Impl 然后修改Factory類,其余不變:
/**
* @ClassName Factory
* @Description: 其余代碼和之前沒有變化,只增加這樣工廠類即可
* @author Jerry
* @date 2016年3月27日 上午10:23:30
*/
public class Factory {
public static Api createApi() {
Properties properties = new Properties();
InputStream in = null;
try {
in = Factory.class.getResourceAsStream("factory.properties");
properties.load(in);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Api api = null;
try {
//使用反射創(chuàng)建實例
api = (Api) Class.forName(properties.getProperty("ImplClass")).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return api;
}
/**
* @Description: 通常把Factory當(dāng)成一個工具類,不需要創(chuàng)建類實例,所以直接使用靜態(tài)方法
* @param 當(dāng)然可以添加參數(shù),使得客戶端可以選擇自己想要初始化的實例,但不推薦,后面會解釋原因
* @return Api 返回一個具體實現(xiàn)
* @throws
*/
@Deprecated
public static Api createApi1() {
return new Impl();
}
}
使用配置文件的寫法好處在于,可以更加便捷的更改具體實現(xiàn)類,無須修改代碼,使得耦合性降低。
四、總結(jié)
何時選用簡單工廠
如果想要完全封裝隔離具體實現(xiàn),讓外部只能通過接口來操作封裝體。想要把對外創(chuàng)建對象的職責(zé)集中管理和控制,因為簡單工廠也稱萬能工廠,可以創(chuàng)建很多的,不相關(guān)的對象。
到此這篇關(guān)于Java設(shè)計模式中的簡單工廠模式解析的文章就介紹到這了,更多相關(guān)java簡單工廠模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實現(xiàn)ModbusCRC16校驗的示例代碼
本文介紹了使用Java實現(xiàn)ModbusCRC16校驗,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11
詳解Java實現(xiàn)設(shè)計模式之責(zé)任鏈模式
責(zé)任鏈模式是一種行為設(shè)計模式,允許你將請求沿著處理鏈發(fā)送,然后處理者都可對其進(jìn)行處理,完成后可以再將其傳遞給下一個處理者。下面將會舉例說明什么是責(zé)任鏈模式,責(zé)任鏈模式該如何使用2021-06-06
Java 如何從list中刪除符合條件的數(shù)據(jù)
這篇文章主要介紹了Java 如何從list中刪除符合條件的數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
logback-spring.xml的內(nèi)容格式詳解
這篇文章主要介紹了logback-spring.xml的內(nèi)容格式詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的的朋友參考下吧2023-11-11
SpringMVC @RequestBody出現(xiàn)400 Bad Request的解決
這篇文章主要介紹了SpringMVC @RequestBody出現(xiàn)400 Bad Request的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04

