深入理解Java設(shè)計(jì)模式之簡(jiǎn)單工廠模式
一、什么是簡(jiǎn)單工廠模式
簡(jiǎn)單工廠模式又稱(chēng)為靜態(tài)工廠模式,實(shí)質(zhì)是由一個(gè)工廠類(lèi)根據(jù)傳入的參數(shù),動(dòng)態(tài)決定應(yīng)該創(chuàng)建哪一個(gè)產(chǎn)品類(lèi)(這些產(chǎn)品類(lèi)繼承自一個(gè)父類(lèi)或接口)的實(shí)例。簡(jiǎn)單工廠模式的創(chuàng)建目標(biāo),所有創(chuàng)建的對(duì)象都是充當(dāng)這個(gè)角色的某個(gè)具體類(lèi)的實(shí)例。
其實(shí)就是將一個(gè)具體類(lèi)的實(shí)例化交給一個(gè)靜態(tài)工廠方法來(lái)執(zhí)行,它不屬于GOF的23種設(shè)計(jì)模式,但現(xiàn)實(shí)中卻經(jīng)常會(huì)用到,而且思想也非常簡(jiǎn)單。
二、簡(jiǎn)單工廠模式的結(jié)構(gòu)
簡(jiǎn)單工廠模式包含如下角色:
Factory:工廠角色
Product:抽象產(chǎn)品角色
ConcreteProduct:具體產(chǎn)品角色
| 工廠角色(Creator) | 是簡(jiǎn)單工廠模式的核心,它負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有具體產(chǎn)品類(lèi)的實(shí)例。工廠類(lèi)可以被外界直接調(diào)用,創(chuàng)建所需的產(chǎn)品對(duì)象。 |
| 抽象產(chǎn)品角色(Product) | 是所有具體產(chǎn)品角色的父類(lèi),它負(fù)責(zé)描述所有實(shí)例所共有的公共接口。 |
| 具體產(chǎn)品角色(Concrete Product) | 繼承自抽象產(chǎn)品角色,一般為多個(gè),是簡(jiǎn)單工廠模式的創(chuàng)建目標(biāo)。工廠類(lèi)返回的都是該角色的某一具體產(chǎn)品。 |
三、簡(jiǎn)單工廠模式的應(yīng)用場(chǎng)景
1.前幾天蘋(píng)果公司剛發(fā)布IPhone Xs和iPhone XR,那么問(wèn)題來(lái)了,蘋(píng)果公司的代工廠到底生產(chǎn)多少種尺寸的手機(jī)呢?
1.由工廠決定生產(chǎn)哪種型號(hào)的的手機(jī),蘋(píng)果公司的工廠就是一個(gè)工廠類(lèi),是簡(jiǎn)單工廠模式的核心類(lèi)。
2.iPhoneX、iPhoneXs、iphoneXr都是蘋(píng)果手機(jī),只是型號(hào)不同。蘋(píng)果手機(jī)類(lèi)滿(mǎn)足抽象的定義,各個(gè)型號(hào)的手機(jī)類(lèi)是其具體實(shí)現(xiàn)。
2.考慮一個(gè)簡(jiǎn)單的軟件應(yīng)用場(chǎng)景,一個(gè)軟件系統(tǒng)可以提供多個(gè)外觀不同的按鈕(如圓形按鈕、矩形按鈕、菱形按鈕等),這些按鈕都源自同一個(gè)基類(lèi),不過(guò)在繼承基類(lèi)后不同的子類(lèi)修改了部分屬性從而使得它們可以呈現(xiàn)不同的外觀,如果我們希望在使用這些按鈕時(shí),不需要知道這些具體按鈕類(lèi)的名字,只需要知道表示該按鈕類(lèi)的一個(gè)參數(shù),并提供一個(gè)調(diào)用方便的方法,把該參數(shù)傳入方法即可返回一個(gè)相應(yīng)的按鈕對(duì)象,此時(shí),就可以使用簡(jiǎn)單工廠模式。
在以下情況下可以使用簡(jiǎn)單工廠模式:
工廠類(lèi)負(fù)責(zé)創(chuàng)建的對(duì)象比較少:由于創(chuàng)建的對(duì)象較少,不會(huì)造成工廠方法中的業(yè)務(wù)邏輯太過(guò)復(fù)雜。
客戶(hù)端只知道傳入工廠類(lèi)的參數(shù),對(duì)于如何創(chuàng)建對(duì)象不關(guān)心:客戶(hù)端既不需要關(guān)心創(chuàng)建細(xì)節(jié),甚至連類(lèi)名都不需要記住,只需要知道類(lèi)型所對(duì)應(yīng)的參數(shù)。
四、簡(jiǎn)單工廠模式和工廠方法模式區(qū)別
簡(jiǎn)單工廠模式:
(1)工廠類(lèi)負(fù)責(zé)創(chuàng)建的對(duì)象比較少,由于創(chuàng)建的對(duì)象較少,不會(huì)造成工廠方法中的業(yè)務(wù)邏輯太過(guò)復(fù)雜。
(2)客戶(hù)端只知道傳入工廠類(lèi)的參數(shù),對(duì)于如何創(chuàng)建對(duì)象并不關(guān)心。
工廠方法模式:
(1)客戶(hù)端不知道它所需要的對(duì)象的類(lèi)。
(2)抽象工廠類(lèi)通過(guò)其子類(lèi)來(lái)指定創(chuàng)建哪個(gè)對(duì)象。
五、簡(jiǎn)單工廠模式和策略模式的異同
策略模式和簡(jiǎn)單工廠模式看起來(lái)非常相似,都是通過(guò)多態(tài)來(lái)實(shí)現(xiàn)不同子類(lèi)的選取,這種思想應(yīng)該是從程序的整體來(lái)看得出的。
如果從使用這兩種模式的角度來(lái)看的話(huà),我們會(huì)發(fā)現(xiàn)在簡(jiǎn)單工廠模式中我們只需要傳遞相應(yīng)的條件就能得到想要的一個(gè)對(duì)象,然后通過(guò)這個(gè)對(duì)象實(shí)現(xiàn)算法的操作。
而策略模式,使用時(shí)必須首先創(chuàng)建一個(gè)想使用的類(lèi)對(duì)象,然后將該對(duì)象最為參數(shù)傳遞進(jìn)去,通過(guò)該對(duì)象調(diào)用不同的算法。
在簡(jiǎn)單工廠模式中實(shí)現(xiàn)了通過(guò)條件選取一個(gè)類(lèi)去實(shí)例化對(duì)象,策略模式則將選取相應(yīng)對(duì)象的工作交給模式的使用者,它本身不去做選取工作。
結(jié)合下面的代碼和下面的釋義不難看出,其實(shí)兩個(gè)的差別很微妙,Factory是直接創(chuàng)建具體的對(duì)象并用該對(duì)象去執(zhí)行相應(yīng)的動(dòng)作,而Context將這個(gè)操作給了Context類(lèi),沒(méi)有創(chuàng)建具體的對(duì)象,實(shí)現(xiàn)的代碼的進(jìn)一步封裝,客戶(hù)端代碼并不需要知道具體的實(shí)現(xiàn)過(guò)程。
六、簡(jiǎn)單工廠模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
工廠類(lèi)是整個(gè)模式的關(guān)鍵.包含了必要的邏輯判斷,根據(jù)外界給定的信息,決定究竟應(yīng)該創(chuàng)建哪個(gè)具體類(lèi)的對(duì)象.
通過(guò)使用工廠類(lèi),外界可以從直接創(chuàng)建具體產(chǎn)品對(duì)象的尷尬局面擺脫出來(lái),僅僅需要負(fù)責(zé)“消費(fèi)”對(duì)象就可以了。
而不必管這些對(duì)象究竟如何創(chuàng)建及如何組織的.明確了各自的職責(zé)和權(quán)利,有利于整個(gè)軟件體系結(jié)構(gòu)的優(yōu)化。
缺點(diǎn):
由于工廠類(lèi)集中了所有實(shí)例的創(chuàng)建邏輯,違反了開(kāi)閉原則,將全部創(chuàng)建邏輯集中到了一個(gè)工廠類(lèi)中;
它所能創(chuàng)建的類(lèi)只能是事先考慮到的,如果需要添加新的類(lèi),則就需要改變工廠類(lèi)了。
當(dāng)系統(tǒng)中的具體產(chǎn)品類(lèi)不斷增多時(shí)候,可能會(huì)出現(xiàn)要求工廠類(lèi)根據(jù)不同條件創(chuàng)建不同實(shí)例的需求.
這種對(duì)條件的判斷和對(duì)具體產(chǎn)品類(lèi)型的判斷交錯(cuò)在一起,很難避免模塊功能的蔓延,對(duì)系統(tǒng)的維護(hù)和擴(kuò)展非常不利;
開(kāi)閉原則定義:一個(gè)軟件實(shí)體如類(lèi)、模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。
開(kāi)放-封閉原則的意思就是說(shuō),你設(shè)計(jì)的時(shí)候,時(shí)刻要考慮,盡量讓這個(gè)類(lèi)是足夠好,寫(xiě)好了就不要去修改了,如果新需求來(lái),我們?cè)黾右恍╊?lèi)就完事了,原來(lái)的代碼能不動(dòng)則不動(dòng)。這個(gè)原則有兩個(gè)特性,一個(gè)是說(shuō)“對(duì)于擴(kuò)展是開(kāi)放的”,另一個(gè)是說(shuō)“對(duì)于更改是封閉的”。面對(duì)需求,對(duì)程序的改動(dòng)是通過(guò)增加新代碼進(jìn)行的,而不是更改現(xiàn)有的代碼。這就是“開(kāi)放-封閉原則”的精神所在。
七、簡(jiǎn)單工廠模式的實(shí)現(xiàn)
首先創(chuàng)建一個(gè)"蘋(píng)果手機(jī)"類(lèi),定義一個(gè)獲取手機(jī)尺寸的方法
//蘋(píng)果手機(jī)
public abstract class ApplePhone {
//獲取尺寸
protected abstract void getSize();
}
蘋(píng)果手機(jī)不同型號(hào)的"手機(jī)類(lèi)"。
public class IphoneX:ApplePhone{
public void getSize() {
Console.WriteLine("iPhoneX屏幕:3.5英寸");
}
}
public class IphoneXs:ApplePhone{
public void getSize() {
Console.WriteLine("iPhoneX屏幕:4.5英寸");
}
}
public class IphoneXR:ApplePhone{
public void getSize() {
Console.WriteLine("iPhoneX屏幕:5.5英寸");
}
}
建立一個(gè)"工廠類(lèi)"生產(chǎn)不同型號(hào)的"手機(jī)對(duì)象"。
//蘋(píng)果工廠
public class AppleFactory {
public static ApplePhone createPhone(String model){
ApplePhone applePhone = null;
switch (model) {
case"iPhoneX":
applePhone = new IphoneX();
break;
case"iPhoneXs":
applePhone = new IphoneXs();
break;
case"iPhoneXr":
applePhone = new IphoneXR();
break;
default:
break;
}
returnapplePhone;
}
}
最后是客戶(hù)端測(cè)試類(lèi)
public class Client {
public static void main(String[] args) {
ApplePhone applePhone ;
applePhone = AppleFactory.createPhone("iPhoneX");
applePhone.getSize();
applePhone = AppleFactory.createPhone("iPhoneXs");
applePhone.getSize();
applePhone = AppleFactory.createPhone("iPhoneXr");
applePhone.getSize();
}
}
八、總結(jié)
創(chuàng)建型模式對(duì)類(lèi)的實(shí)例化過(guò)程進(jìn)行了抽象,能夠?qū)?duì)象的創(chuàng)建與對(duì)象的使用過(guò)程分離。
簡(jiǎn)單工廠模式又稱(chēng)為靜態(tài)工廠方法模式,它屬于類(lèi)創(chuàng)建型模式。在簡(jiǎn)單工廠模式中,可以根據(jù)參數(shù)的不同返回不同類(lèi)的實(shí)例。
簡(jiǎn)單工廠模式專(zhuān)門(mén)定義一個(gè)類(lèi)來(lái)負(fù)責(zé)創(chuàng)建其他類(lèi)的實(shí)例,被創(chuàng)建的實(shí)例通常都具有共同的父類(lèi)。
簡(jiǎn)單工廠模式包含三個(gè)角色:工廠角色負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有實(shí)例的內(nèi)部邏輯;抽象產(chǎn)品角色是所創(chuàng)建的所有對(duì)象的父類(lèi),負(fù)責(zé)描述所有實(shí)例所共有的公共接口;具體產(chǎn)品角色是創(chuàng)建目標(biāo),所有創(chuàng)建的對(duì)象都充當(dāng)這個(gè)角色的某個(gè)具體類(lèi)的實(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)建交給專(zhuān)門(mén)的工廠類(lèi)負(fù)責(zé),但是其最大的缺點(diǎn)在于工廠類(lèi)不夠靈活,增加新的具體產(chǎn)品需要修改工廠類(lèi)的判斷邏輯代碼,而且產(chǎn)品較多時(shí),工廠方法代碼將會(huì)非常復(fù)雜。
簡(jiǎn)單工廠模式適用情況包括:工廠類(lèi)負(fù)責(zé)創(chuàng)建的對(duì)象比較少;客戶(hù)端只知道傳入工廠類(lèi)的參數(shù),對(duì)于如何創(chuàng)建對(duì)象不關(guān)心。
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
十個(gè)最常見(jiàn)的Java字符串問(wèn)題(翻譯)
這篇文章主要介紹了十個(gè)最常見(jiàn)的Java字符串問(wèn)題(翻譯),需要的朋友可以參考下2015-03-03
Rabbitmq延遲隊(duì)列實(shí)現(xiàn)定時(shí)任務(wù)的方法
這篇文章主要介紹了Rabbitmq延遲隊(duì)列實(shí)現(xiàn)定時(shí)任務(wù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
SpringCloud Gateway自動(dòng)裝配實(shí)現(xiàn)流程詳解
Spring Cloud Gateway旨在為微服務(wù)架構(gòu)提供一種簡(jiǎn)單有效的、統(tǒng)一的 API 路由管理方式。Spring Cloud Gateway 作為 Spring Cloud 生態(tài)系中的網(wǎng)關(guān),它不僅提供統(tǒng)一的路由方式,并且基于 Filter 鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全、監(jiān)控/埋點(diǎn)和限流等2022-10-10
Java的基礎(chǔ)語(yǔ)法學(xué)習(xí)筆記
這里為大家整理了Java的基礎(chǔ)語(yǔ)法學(xué)習(xí)筆記,包括關(guān)鍵詞、運(yùn)算符與基本的流程控制語(yǔ)句寫(xiě)法等,需要的朋友可以參考下2016-05-05
SpringBoot集成WebSocket的兩種方式(JDK內(nèi)置版和Spring封裝版)
這篇文章主要介紹了SpringBoot集成WebSocket的兩種方式,這兩種方式為JDK內(nèi)置版和Spring封裝版,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
解決persistence.xml配置文件修改存放路徑的問(wèn)題
這篇文章主要介紹了解決persistence.xml配置文件修改存放路徑的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02

