參考:https://www.cnblogs.com/WindSun/p/10252425.html
模式動(dòng)機(jī)
只需要知道水果的名字則可得到相應(yīng)的水果。
考慮一個(gè)簡(jiǎn)單的軟件應(yīng)用場(chǎng)景,一個(gè)軟件系統(tǒng)可以提供多個(gè)外觀不同的按鈕(如圓形按鈕、矩形按鈕、菱形按鈕等),這些按鈕都源自同一個(gè)基類,不過(guò)在繼承基類后不同的子類修改了部分屬性從而使得它們可以呈現(xiàn)不同的外觀,如果我們希望在使用這些按鈕時(shí),不需要知道這些具體按鈕類的名字,只需要知道表示該按鈕類的一個(gè)參數(shù),并提供一個(gè)調(diào)用方便的方法,把該參數(shù)傳入方法即可返回一個(gè)相應(yīng)的按鈕對(duì)象,此時(shí),就可以使用簡(jiǎn)單工廠模式。
模式定義
簡(jiǎn)單工廠模式(Simple Factory Pattern):又稱為靜態(tài)工廠方法(Static Factory Method)模式,它屬于類創(chuàng)建型模式。在簡(jiǎn)單工廠模式中,可以根據(jù)參數(shù)的不同返回不同類的實(shí)例。簡(jiǎn)單工廠模式專門定義一個(gè)類來(lái)負(fù)責(zé)創(chuàng)建其他類的實(shí)例,被創(chuàng)建的實(shí)例通常都具有共同的父類。
模式結(jié)構(gòu)

簡(jiǎn)單工廠模式包含如下角色:
? Factory:工廠角色
? Product:抽象產(chǎn)品角色
? ConcreteProduct:具體產(chǎn)品角色
模式分析
將對(duì)象的創(chuàng)建和對(duì)象本身業(yè)務(wù)處理分離可以降低系統(tǒng)的耦合度,使得兩者修改起來(lái)都相對(duì)容易。
在調(diào)用工廠類的工廠方法時(shí),由于工廠方法是靜態(tài)方法,使用起來(lái)很方便,可通過(guò)類名直接調(diào)用,而且只需要傳入一個(gè)簡(jiǎn)單的參數(shù)即可,在實(shí)際開(kāi)發(fā)中,還可以在調(diào)用時(shí)將所傳入的參數(shù)保存在XML等格式的配置文件中,修改參數(shù)時(shí)無(wú)須修改任何Java源代碼。
簡(jiǎn)單工廠模式最大的問(wèn)題在于工廠類的職責(zé)相對(duì)過(guò)重,增加新的產(chǎn)品需要修改工廠類的判斷邏輯,這一點(diǎn)與開(kāi)閉原則是相違背的。
簡(jiǎn)單工廠模式的要點(diǎn)在于:當(dāng)你需要什么,只需要傳入一個(gè)正確的參數(shù),就可以獲取你所需要的對(duì)象,而無(wú)須知道其創(chuàng)建細(xì)節(jié)。
模式實(shí)例與解析
實(shí)例一:簡(jiǎn)單電視工廠
某電視機(jī)廠專為各知名電視機(jī)品牌代工生產(chǎn)各類電視機(jī),當(dāng)需要海爾牌電視機(jī)時(shí)只需要在調(diào)用該工廠的工廠方法時(shí)傳入?yún)?shù)“Haier”,需要海信電視機(jī)時(shí)只需要傳入?yún)?shù)“Hisense”,工廠可以根據(jù)傳入的不同參數(shù)返回不同品牌的電視機(jī)?,F(xiàn)使用簡(jiǎn)單工廠模式來(lái)模擬該電視機(jī)工廠的生產(chǎn)過(guò)程。

實(shí)例代碼(Java)
// tv接口
public interface TV {
void play();
}
// 海爾電視實(shí)現(xiàn)類
public class HairTV implements TV {
@Override
public void play() {
System.out.println("海爾電視播放中!");
}
}
// 海信電視實(shí)現(xiàn)類
public class HisenseTV implements TV {
@Override
public void play() {
System.out.println("海信電視播放中");
}
}
// 創(chuàng)建電視的簡(jiǎn)單工廠
public class TVFactory {
public static TV createTV(String name) {
if ("海爾".equals(name)) return new HairTV();
else if ("海信".equals(name)) return new HisenseTV();
else return null;
}
}
模式優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 工廠類含有必要的判斷邏輯,可以決定在什么時(shí)候創(chuàng)建哪一個(gè)產(chǎn)品類的實(shí)例,客戶端可以免除直接創(chuàng)建產(chǎn)品對(duì)象的責(zé)任,而僅僅“消費(fèi)”產(chǎn)品;簡(jiǎn)單工廠模式通過(guò)這種做法實(shí)現(xiàn)了對(duì)責(zé)任的分割,它提供了專門的工廠類用于創(chuàng)建對(duì)象。
- 客戶端無(wú)須知道所創(chuàng)建的具體產(chǎn)品類的類名,只需要知道具體產(chǎn)品類所對(duì)應(yīng)的參數(shù)即可,對(duì)于一些復(fù)雜的類名,通過(guò)簡(jiǎn)單工廠模式可以減少使用者的記憶量。
- 通過(guò)引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產(chǎn)品類,在一定程度上提高了系統(tǒng)的靈活性。
缺點(diǎn)
由于工廠類集中了所有產(chǎn)品創(chuàng)建邏輯,一旦不能正常工作,整個(gè)系統(tǒng)都要受到影響。
使用簡(jiǎn)單工廠模式將會(huì)增加系統(tǒng)中類的個(gè)數(shù),在一定程序上增加了系統(tǒng)的復(fù)雜度和理解難度。
系統(tǒng)擴(kuò)展困難,一旦添加新產(chǎn)品就不得不修改工廠邏輯,在產(chǎn)品類型較多時(shí),有可能造成工廠邏輯過(guò)于復(fù)雜,不利于系統(tǒng)的擴(kuò)展和維護(hù)。
簡(jiǎn)單工廠模式由于使用了靜態(tài)工廠方法,造成工廠角色無(wú)法形成基于繼承的等級(jí)結(jié)構(gòu)。
模式適用環(huán)境
在以下情況下可以使用簡(jiǎn)單工廠模式:
- 工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少:由于創(chuàng)建的對(duì)象較少,不會(huì)造成工廠方法中的業(yè)務(wù)邏輯太過(guò)復(fù)雜。
- 客戶端只知道傳入工廠類的參數(shù),對(duì)于如何創(chuàng)建對(duì)象不關(guān)心:客戶端既不需要關(guān)心創(chuàng)建細(xì)節(jié),甚至連類名都不需要記住,只需要知道類型所對(duì)應(yīng)的參數(shù)。
模式應(yīng)用
(1) 在JDK類庫(kù)中廣泛使用了簡(jiǎn)單工廠模式,如工具類java.text.DateFormat,它用于格式化一個(gè)本地日期或者時(shí)間。
public final static DateFormat getDateInstance();
public final static DateFormat getDateInstance(int style);
public final static DateFormat getDateInstance(int style,Locale locale);
(2) Java加密技術(shù)
//獲取不同加密算法的密鑰生成器
KeyGenerator keyGen=KeyGenerator.getInstance("DESede");
//創(chuàng)建密碼器
Cipher cp=Cipher.getInstance("DESede");
模式擴(kuò)展
簡(jiǎn)單工廠模式的簡(jiǎn)化:
-
在有些情況下工廠類可以由抽象產(chǎn)品角色扮演,一個(gè)抽象產(chǎn)品類同時(shí)也是子類的工廠,也就是說(shuō)把靜態(tài)工廠方法寫到抽象產(chǎn)品類中。
