二十三種設(shè)計(jì)模式 - 簡(jiǎn)單工廠模式
簡(jiǎn)單工廠模式簡(jiǎn)介
模式動(dòng)機(jī)
考慮一個(gè)簡(jiǎn)單的軟件應(yīng)用場(chǎng)景宋光,一個(gè)軟件系統(tǒng)可以提供多個(gè)外觀不同的按鈕(如圓形按鈕关斜、矩形按鈕迫淹、菱形按鈕等)秘通, 這些按鈕都源自同一個(gè)基類,不過在繼承基類后不同的子類修改了部分屬性從而使得它們可以呈現(xiàn)不同的外觀敛熬,如果我們希望在使用這些按鈕時(shí)肺稀,不需要知道這些具體按鈕類的名字,只需要知道表示該按鈕類的一個(gè)參數(shù)应民,并提供一個(gè)調(diào)用方便的方法话原,把該參數(shù)傳入方法即可返回一個(gè)相應(yīng)的按鈕對(duì)象,此時(shí)瑞妇,就可以使用簡(jiǎn)單工廠模式稿静。
模式定義
簡(jiǎn)單工廠模式:又稱為靜態(tài)工廠模式(Static Factory Pattern),<u>Factory類為靜態(tài)類或包含靜態(tài)方法</u>辕狰。它屬于類創(chuàng)建型模式改备。
簡(jiǎn)單工廠模式:定義一個(gè)Factory類,可以根據(jù)參數(shù)的不同返回不同類的實(shí)例蔓倍,被創(chuàng)建的實(shí)例通常有共同的父類悬钳。
簡(jiǎn)單工廠模式:只需要一個(gè)Factory類。
簡(jiǎn)單工廠模式:不屬于23種GOF設(shè)計(jì)模式偶翅。
簡(jiǎn)單工廠模式:實(shí)質(zhì)是由一個(gè)工廠類根據(jù)傳入的參數(shù)默勾,動(dòng)態(tài)決定應(yīng)該創(chuàng)建哪一個(gè)產(chǎn)品實(shí)例。
簡(jiǎn)單工廠模式結(jié)構(gòu)
結(jié)構(gòu)圖
時(shí)序圖
參與者
簡(jiǎn)單工廠模式參與者:
Product:抽象產(chǎn)品類聚谁,是所創(chuàng)建的所有對(duì)象的父類母剥,將具體產(chǎn)品類公共的代碼進(jìn)行抽象和提取后封裝在一個(gè)抽象產(chǎn)品類中。
ConcreteProject:具體產(chǎn)品類形导,將需要?jiǎng)?chuàng)建的各種不同產(chǎn)品對(duì)象的相關(guān)代碼封裝到具體產(chǎn)品類中环疼。
Factory:工廠類,提供一個(gè)工廠類用于創(chuàng)建各種產(chǎn)品朵耕,在工廠類中提供一個(gè)創(chuàng)建產(chǎn)品的工廠方法炫隶,該方法可以根據(jù)所傳入?yún)?shù)的不同創(chuàng)建不同的具體產(chǎn)品對(duì)象。
Client:客戶端類阎曹,只需要用工廠類的工廠方法并傳入相應(yīng)的參數(shù)即可得到一個(gè)產(chǎn)品對(duì)象伪阶。
簡(jiǎn)單工廠模式實(shí)現(xiàn)
首先創(chuàng)建一個(gè)抽象的Operation類
package com.lance.calculator.operation;
public abstract class Operation {
public double NumberA;
public double NumberB;
public double getNumberA() {
return NumberA;
}
public void setNumberA(double numberA) {
NumberA = numberA;
}
public double getNumberB() {
return NumberB;
}
public void setNumberB(double numberB) {
NumberB = numberB;
}
public abstract double getResult();
}
根據(jù)需求對(duì)Operation類進(jìn)行繼承
加法運(yùn)算方式
package com.lance.calculator.operation;
public class PlusOperation extends Operation {
@Override
public double getResult() {
return NumberA + NumberB;
}
}
減法運(yùn)算方式
package com.lance.calculator.operation;
public class MinusOperation extends Operation {
@Override
public double getResult() {
return NumberA - NumberB;
}
}
乘法運(yùn)算方式
package com.lance.calculator.operation;
public class MultiplyOperation extends Operation {
@Override
public double getResult() {
return NumberA * NumberB;
}
}
除法運(yùn)算方式
package com.lance.calculator.operation;
public class DivideOperation extends Operation {
@Override
public double getResult() {
return NumberA / NumberB;
}
}
然后創(chuàng)建工廠類煞檩,根據(jù)不同的參數(shù)創(chuàng)建不同的調(diào)用方法
package com.lance.calculator.factory;
import com.lance.calculator.operation.*;
public class OperationFactory {
public static Operation createOperation(String operate) {
Operation operation = null;
switch (operate) {
case "+":
operation = new PlusOperation();
break;
case "-":
operation = new MinusOperation();
break;
case "*":
operation = new MultiplyOperation();
break;
case "/":
operation = new DivideOperation();
break;
}
return operation;
}
}
客戶端調(diào)用具體的運(yùn)算
package com.lance.calculator;
import com.lance.calculator.factory.OperationFactory;
import com.lance.calculator.operation.Operation;
public class Program {
public static void main(String[] args) {
Operation operation = OperationFactory.createOperation("+");
operation.NumberA = 10;
operation.NumberB = 5;
System.out.println("計(jì)算結(jié)果: " + operation.getResult());
}
}
簡(jiǎn)單工廠模式應(yīng)用分析
簡(jiǎn)單工廠模式分析
- 將對(duì)象的創(chuàng)建和對(duì)象本身業(yè)務(wù)處理分離可以降低系統(tǒng)的耦合度,使得兩者修改起來都相對(duì)容易栅贴。
- 在調(diào)用工廠類的工廠方法時(shí)斟湃,由于工廠方法是靜態(tài)方法,使用起來很方便檐薯,可通過類名直接調(diào)用桐早,而且只需要傳入一個(gè)簡(jiǎn)單的參數(shù)即可,在實(shí)際開發(fā)中厨剪,還可以在調(diào)用時(shí)將所傳入的參數(shù)保存在XML等格式的配置文件中,修改參數(shù)時(shí)無(wú)須修改任何源代碼友存。
- 簡(jiǎn)單工廠模式最大的問題在于工廠類的職責(zé)相對(duì)過重祷膳,增加新的產(chǎn)品需要修改工廠類的判斷邏輯,這一點(diǎn)與開閉原則是相違背的屡立。
- 簡(jiǎn)單工廠模式的要點(diǎn)在于:當(dāng)你需要什么直晨,只需要傳入一個(gè)正確的參數(shù),就可以獲取你所需要的對(duì)象膨俐,而無(wú)須知道其創(chuàng)建細(xì)節(jié)勇皇。
簡(jiǎn)單工廠模式優(yōu)點(diǎn)
- 工廠類含有必要的判斷邏輯,可以決定在什么時(shí)候創(chuàng)建哪一個(gè)產(chǎn)品類的實(shí)例焚刺,客戶端可以免除直接創(chuàng)建產(chǎn)品對(duì)象的責(zé)任敛摘,而僅僅“消費(fèi)”產(chǎn)品;簡(jiǎn)單工廠模式通過這種做法實(shí)現(xiàn)了對(duì)責(zé)任的分割乳愉,它提供了專門的工廠類用于創(chuàng)建對(duì)象兄淫。
- 客戶端無(wú)須知道所創(chuàng)建的具體產(chǎn)品類的類名,只需要知道具體產(chǎn)品類所對(duì)應(yīng)的參數(shù)即可蔓姚,對(duì)于一些復(fù)雜的類名捕虽,通過簡(jiǎn)單工廠模式可以減少使用者的記憶量。
- 通過引入配置文件坡脐,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產(chǎn)品類泄私,在一定程度上提高了系統(tǒng)的靈活性。
簡(jiǎn)單工廠模式缺點(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í)惧盹,有可能造成工廠邏輯過于復(fù)雜乳幸,不利于系統(tǒng)的擴(kuò)展和維護(hù)。
- 簡(jiǎn)單工廠模式由于使用了靜態(tài)工廠方法钧椰,造成工廠角色無(wú)法形成基于繼承的等級(jí)結(jié)構(gòu)粹断。
簡(jiǎn)單工廠適用環(huán)境
在以下情況下可以使用簡(jiǎn)單工廠模式:
- 工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少:由于創(chuàng)建的對(duì)象較少,不會(huì)造成工廠方法中的業(yè)務(wù)邏輯太過復(fù)雜嫡霞。
- 客戶端只知道傳入工廠類的參數(shù)瓶埋,對(duì)于如何創(chuàng)建對(duì)象不關(guān)心:客戶端既不需要關(guān)心創(chuàng)建細(xì)節(jié),甚至連類名都不需要記住诊沪,只需要知道類型所對(duì)應(yīng)的參數(shù)养筒。
簡(jiǎn)單工廠模式應(yīng)用
- 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);
- Java加密技術(shù)
獲取不同加密算法的密鑰生成器:
KeyGenerator keyGen = KeyGenerator.getInstance("DESede");
創(chuàng)建密碼器:
Cipher cp = Cipher.getInstance("DESede");
總結(jié)
- 創(chuàng)建型模式對(duì)類的實(shí)例化過程進(jìn)行了抽象,能夠?qū)?duì)象的創(chuàng)建與對(duì)象的使用過程分離渐裸。
- 簡(jiǎn)單工廠模式又稱為靜態(tài)工廠方法模式巫湘,它屬于類創(chuàng)建型模式。在簡(jiǎn)單工廠模式中昏鹃,可以根據(jù)參數(shù)的不同返回不同類的實(shí)例尚氛。簡(jiǎn)單工廠模式專門定義一個(gè)類來負(fù)責(zé)創(chuàng)建其他類的實(shí)例,被創(chuàng)建的實(shí)例通常都具有共同的父類洞渤。
- 簡(jiǎn)單工廠模式包含三個(gè)角色:工廠角色負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有實(shí)例的內(nèi)部邏輯阅嘶;抽象產(chǎn)品角色是所創(chuàng)建的所有對(duì)象的父類,負(fù)責(zé)描述所有實(shí)例所共有的公共接口载迄;具體產(chǎn)品角色是創(chuàng)建目標(biāo)奈懒,所有創(chuàng)建的對(duì)象都充當(dāng)這個(gè)角色的某個(gè)具體類的實(shí)例。
- 簡(jiǎn)單工廠模式的要點(diǎn)在于:當(dāng)你需要什么宪巨,只需要傳入一個(gè)正確的參數(shù)磷杏,就可以獲取你所需要的對(duì)象,而無(wú)須知道其創(chuàng)建細(xì)節(jié)捏卓。
- 簡(jiǎn)單工廠模式最大的優(yōu)點(diǎn)在于實(shí)現(xiàn)對(duì)象的創(chuàng)建和對(duì)象的使用分離极祸,將對(duì)象的創(chuàng)建交給專門的工廠類負(fù)責(zé),但是其最大的缺點(diǎn)在于工廠類不夠靈活怠晴,增加新的具體產(chǎn)品需要修改工廠類的判斷邏輯代碼遥金,而且產(chǎn)品較多時(shí),工廠方法代碼將會(huì)非常復(fù)雜蒜田。
- 簡(jiǎn)單工廠模式適用情況包括:工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少稿械;客戶端只知道傳入工廠類的參數(shù),對(duì)于如何創(chuàng)建對(duì)象不關(guān)心冲粤。