初学Java常用设计模式之——工厂模式
聲明:轉(zhuǎn)載請(qǐng)附上原文鏈接
提示:標(biāo)題序號(hào)從2開(kāi)始,是照應(yīng)不同設(shè)計(jì)模式筆記發(fā)布的順序而定的,比如,第上一篇文章 初學(xué)Java常用設(shè)計(jì)模式之——單例模式 序號(hào)從1開(kāi)始
2. 工廠(chǎng)模式(常用)
-  ??模式介紹: - 它提供了?種創(chuàng)建對(duì)象的最佳?式,我們?cè)趧?chuàng)建對(duì)象時(shí) 不會(huì)對(duì)客戶(hù)端暴露創(chuàng)建邏輯,并且是通過(guò)使??個(gè)共同 的接?來(lái)指向新創(chuàng)建的對(duì)象。
 
-  例?: - ???產(chǎn)電腦,除了A品牌、還可以?產(chǎn)B、C、D品牌 電腦;
- 業(yè)務(wù)開(kāi)發(fā)中,?付很常?,??有統(tǒng)?下單和?付接 ?,具體的?付實(shí)現(xiàn)可以微信、?付寶、銀?卡等;
 
-  ??模式有 3 種不同的實(shí)現(xiàn)?式: - 簡(jiǎn)單??模式:通過(guò)傳?相關(guān)的類(lèi)型來(lái)返回相應(yīng)的類(lèi),這 種?式?較單 ?,可擴(kuò)展性相對(duì)較差;
- ???法模式:通過(guò)實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)相應(yīng)的?法來(lái)決定相應(yīng) 的返回結(jié)果,這種?式的可擴(kuò)展性?較強(qiáng);
- 抽象??模式:基于上述兩種模式的拓展,且?持細(xì)化 產(chǎn)品;
 
-  應(yīng)?場(chǎng)景: - 解耦:分離職責(zé),把復(fù)雜對(duì)象的創(chuàng)建和使?的過(guò)程分開(kāi)
- 復(fù)?代碼 降低維護(hù)成本: - 如果對(duì)象創(chuàng)建復(fù)雜且多處需?到,如果每處都進(jìn)?編寫(xiě),則很多重復(fù)代碼,如果業(yè)務(wù)邏輯發(fā)?了改 變,需?四處修改;
- 使???模式統(tǒng)?創(chuàng)建,則只要修改??類(lèi)即可, 降低成本;
 
 
2.1 工廠(chǎng)模式——簡(jiǎn)單工廠(chǎng)模式
- 簡(jiǎn)單??模式(靜態(tài)工廠(chǎng)) - ?稱(chēng)靜態(tài)???法, 可以根據(jù)參數(shù)的不同返回不同類(lèi)的實(shí)例,專(zhuān)?定義?個(gè)類(lèi)來(lái)負(fù)責(zé)創(chuàng)建其他類(lèi)的實(shí)例,被創(chuàng)建的實(shí)例通常都具有共同的?類(lèi);
- 由于???法是靜態(tài)?法,可通過(guò)類(lèi)名直接調(diào)?,?且只需要傳?簡(jiǎn)單的參數(shù)即可;
 
- 核?組成 - Factory:??類(lèi),簡(jiǎn)單??模式的核?,它負(fù)責(zé)實(shí)現(xiàn) 創(chuàng)建所有實(shí)例的內(nèi)部邏輯
- IProduct:抽象產(chǎn)品類(lèi),簡(jiǎn)單??模式所創(chuàng)建的所有對(duì)象的?類(lèi),描述所有實(shí)例所共有的公共接?
- Product:具體產(chǎn)品類(lèi),是簡(jiǎn)單??模式的創(chuàng)建?標(biāo)
 
- 實(shí)現(xiàn)步驟 - 創(chuàng)建抽象產(chǎn)品類(lèi),??有產(chǎn)品的抽象?法,由具體的產(chǎn) 品類(lèi)去實(shí)現(xiàn)
- 創(chuàng)建具體產(chǎn)品類(lèi),繼承了他們的?類(lèi),并實(shí)現(xiàn)具體?法
- 創(chuàng)建??類(lèi),提供了?個(gè)靜態(tài)?法createXXX()?來(lái)?產(chǎn)產(chǎn)品,只需要傳?你想產(chǎn)品名稱(chēng)
 
- 優(yōu)點(diǎn): - 將對(duì)象的創(chuàng)建和對(duì)象本身業(yè)務(wù)處理分離可以降低系統(tǒng)的 耦合度,使得兩者修改起來(lái)都相對(duì)容易。
 
- 缺點(diǎn): - ??類(lèi)的職責(zé)相對(duì)過(guò)重,增加新的產(chǎn)品需要修改??類(lèi)的判斷邏輯,這?點(diǎn)與開(kāi)閉原則是相違背
- 即開(kāi)閉原則(Open Close Principle)對(duì)擴(kuò)展開(kāi)放,對(duì) 修改關(guān)閉,程序需要進(jìn)?拓展的時(shí)候,不能去修改原有 的代碼,實(shí)現(xiàn)?個(gè)熱插拔的效果
- 將會(huì)增加系統(tǒng)中類(lèi)的個(gè)數(shù),在?定程度上增加了系統(tǒng)的復(fù)雜度和理解難度,不利于系統(tǒng)的擴(kuò)展和維護(hù),創(chuàng)建簡(jiǎn)單對(duì)象就不?模式
 
下面我們來(lái)簡(jiǎn)單使用一下簡(jiǎn)單(靜態(tài))工廠(chǎng)設(shè)計(jì)模式:
功能描述:
我們簡(jiǎn)單使用偽代碼模擬一下支付流程:
創(chuàng)建IProduct 抽象產(chǎn)品接口——IPay
/*** @Auther: csp1999* @Date: 2020/11/07/11:00* @Description: IPay抽象統(tǒng)一支付下單接口*/ public interface IPay {/*** 統(tǒng)一下單*/void unifiedOrder(); }創(chuàng)建Product具體產(chǎn)品類(lèi)——AliPay/WeChatPay
AliPay.java
/*** @Auther: csp1999* @Date: 2020/11/07/11:29* @Description: 支付寶支付具體實(shí)現(xiàn)類(lèi)*/ public class AliPay implements IPay{@Overridepublic void unifiedOrder() {System.out.println("支付寶支付統(tǒng)一下單...");} }WeChatPay.java
/*** @Auther: csp1999* @Date: 2020/11/07/11:30* @Description: 微信支付具體實(shí)現(xiàn)類(lèi)*/ public class WeChatPay implements IPay{@Overridepublic void unifiedOrder() {System.out.println("微信支付統(tǒng)一下單...");} }創(chuàng)建Factory工廠(chǎng)類(lèi)——SimplePayFactory
/*** @Auther: csp1999* @Date: 2020/11/07/11:31* @Description: 簡(jiǎn)單支付工廠(chǎng)類(lèi)(靜態(tài)工廠(chǎng)類(lèi))*/ public class SimplePayFactory {/*** 工廠(chǎng)創(chuàng)建方法:* 根據(jù)參數(shù)返回對(duì)應(yīng)的支付對(duì)象** @param payType* @return*/public static IPay createPay(String payType) {if (payType == null) {return null;} else if (payType.equalsIgnoreCase("WECHAT_PAY")) {return new WeChatPay();} else if (payType.equalsIgnoreCase("ALI_PAY")) {return new AliPay();}// 如果需要擴(kuò)展,可以編寫(xiě)更剁return null;} }測(cè)試使用簡(jiǎn)單支付工廠(chǎng):
@Test public void testSimplePayFactory(){IPay wechat_pay = SimplePayFactory.createPay("WECHAT_PAY");IPay ali_pay = SimplePayFactory.createPay("ALI_PAY");wechat_pay.unifiedOrder();ali_pay.unifiedOrder(); }// 輸出結(jié)果: // 微信支付統(tǒng)一下單... // 支付寶支付統(tǒng)一下單...上述就是工廠(chǎng)設(shè)計(jì)模式——簡(jiǎn)單工程(靜態(tài)工廠(chǎng)的一個(gè)簡(jiǎn)單使用例子),那么我們來(lái)分析下其缺點(diǎn)與不足之處:
需求:
- 如果我需要額外再添加一個(gè)A銀行的銀行卡支付,那么就需要在SimplePayFactory 類(lèi)中添加響應(yīng)的判斷邏輯,比如再加一個(gè)if判斷,添加一個(gè)A銀行支付的邏輯
- 而如果再需要一個(gè)B銀行的銀行卡支付,那么還需要再添加一個(gè)if判斷 添加一個(gè)B銀行支付的邏輯,依次加下去…
- 那么這就違背了??類(lèi)要遵循的開(kāi)閉原則(Open Close Principle)(對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉,程序需要進(jìn)?拓展的時(shí)候,不能去修改原有的代碼,實(shí)現(xiàn)?個(gè)熱插拔的效果),這樣就導(dǎo)致,每次擴(kuò)展功能的時(shí)候都需要添加新的邏輯,并且需要對(duì)工廠(chǎng)類(lèi)進(jìn)行修改,如果是真實(shí)復(fù)雜的業(yè)務(wù),這就增加了成本。
下面我們來(lái)看一下工廠(chǎng)方法模式是如何解決簡(jiǎn)單工廠(chǎng)模式的這一缺點(diǎn)
2.2 工廠(chǎng)模式——工廠(chǎng)方法模式
- ???法模式 - ?稱(chēng)??模式,是對(duì)簡(jiǎn)單??模式的進(jìn)?步抽象化,其 好處是可以使系統(tǒng)在不修改原來(lái)代碼的情況下引進(jìn)新的 產(chǎn)品,即滿(mǎn)?開(kāi)閉原則
- 通過(guò)???類(lèi)定義負(fù)責(zé)創(chuàng)建產(chǎn)品的公共接?,通過(guò)?類(lèi) 來(lái)確定所需要?jiǎng)?chuàng)建的類(lèi)型
- 相?簡(jiǎn)單????,此種?法具有更多的可擴(kuò)展性和復(fù)?性,同時(shí)也增強(qiáng)了代碼的可讀性
- 將類(lèi)的實(shí)例化(具體產(chǎn)品的創(chuàng)建)延遲到??類(lèi)的?類(lèi) (具體??)中完成,即由?類(lèi)來(lái)決定應(yīng)該實(shí)例化哪? 個(gè)類(lèi)
 
- 核?組成 - IProduct:抽象產(chǎn)品接口,描述所有實(shí)例所共有的公共接?
- Product:具體產(chǎn)品類(lèi),實(shí)現(xiàn)抽象產(chǎn)品類(lèi)的接?,?? 類(lèi)創(chuàng)建對(duì)象,如果有多個(gè)需要定義多個(gè)
- IFactory:抽象??接口,描述具體??的公共接?
- Factory:具體??類(lèi),實(shí)現(xiàn)創(chuàng)建產(chǎn)品類(lèi)對(duì)象,實(shí)現(xiàn)抽 象??類(lèi)的接?,如果有多個(gè)需要定義多個(gè)
 
要實(shí)現(xiàn)工廠(chǎng)方法模式,只需要在原來(lái)的簡(jiǎn)單工廠(chǎng)模式基礎(chǔ)上,做出改進(jìn),而之前我們創(chuàng)建的IPay抽象產(chǎn)品接口和AliPay WeChatPay 兩個(gè)具體產(chǎn)品類(lèi)不需要改動(dòng)。
首先創(chuàng)建IPayFactory抽象??接口:
/*** @Auther: csp1999* @Date: 2020/11/07/15:08* @Description: 抽象??接口*/ public interface IPayFactory {IPay getPay(); }然后創(chuàng)建AliPayFactory和WeChatFactory 兩個(gè)具體??類(lèi):
/*** @Auther: csp1999* @Date: 2020/11/07/15:09* @Description: 具體工廠(chǎng)類(lèi) AliPayFactory*/ public class AliPayFactory implements IPayFactory{@Overridepublic IPay getPay() {return new AliPay();} } /*** @Auther: csp1999* @Date: 2020/11/07/15:16* @Description: 具體工廠(chǎng)類(lèi) WeChatFactory*/ public class WeChatFactory implements IPayFactory{@Overridepublic IPay getPay() {return new WeChatPay();} }進(jìn)行測(cè)試:
@Test public void testMethodPayFactory(){AliPayFactory aliPayFactory = new AliPayFactory();IPay ali_pay = aliPayFactory.getPay();ali_pay.unifiedOrder();// 輸出:支付寶支付統(tǒng)一下單...WeChatFactory weChatFactory = new WeChatFactory();IPay wechat_pay = weChatFactory.getPay();wechat_pay.unifiedOrder();// 輸出:微信支付統(tǒng)一下單... }工廠(chǎng)方法模式思路如下圖:
- 工廠(chǎng)方法模式優(yōu)點(diǎn): - 符合開(kāi)閉原則,增加?個(gè)產(chǎn)品類(lèi),只需要實(shí)現(xiàn)其他具體的產(chǎn)品類(lèi)和具體的??類(lèi);
- 符合單?職責(zé)原則,每個(gè)??只負(fù)責(zé)?產(chǎn)對(duì)應(yīng)的產(chǎn)品;
- 使?者只需要知道產(chǎn)品的抽象類(lèi),?須關(guān)?其他實(shí)現(xiàn) 類(lèi),滿(mǎn)?迪?特法則、依賴(lài)倒置原則和??替換原則; - 迪?特法則:最少知道原則,實(shí)體應(yīng)當(dāng)盡量少地與 其他實(shí)體之間發(fā)?相互作?;
- 依賴(lài)倒置原則:針對(duì)接?編程,依賴(lài)于抽象?不依 賴(lài)于具體;
- ??替換原則:俗稱(chēng)LSP, 任何基類(lèi)可以出現(xiàn)的地 ?,?類(lèi)?定可以出現(xiàn), 對(duì)實(shí)現(xiàn)抽象化的具體步驟的 規(guī)范;
 
 
- 工廠(chǎng)方法模式缺點(diǎn): - 增加?個(gè)產(chǎn)品,需要實(shí)現(xiàn)對(duì)應(yīng)的具體??類(lèi)和具體產(chǎn)品類(lèi);
- 每個(gè)產(chǎn)品需要有對(duì)應(yīng)的具體??和具體產(chǎn)品類(lèi);
 
2.3 工廠(chǎng)模式——抽象工廠(chǎng)方法模式
抽象???法模式是簡(jiǎn)單工廠(chǎng)模式 和工廠(chǎng)方法模式的整合升級(jí)版。
- ??模式有 3 種不同的實(shí)現(xiàn)?式: - 簡(jiǎn)單??模式:通過(guò)傳?相關(guān)的類(lèi)型來(lái)返回相應(yīng)的類(lèi),這 種?式?較單 ?,可擴(kuò)展性相對(duì)較差;
- ???法模式:通過(guò)實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)相應(yīng)的?法來(lái)決定相應(yīng) 的返回結(jié)果,這種?式的可擴(kuò)展性?較強(qiáng);
- 抽象??模式:基于上述兩種模式的拓展,是???法 模式的升級(jí)版,當(dāng)需要?jiǎng)?chuàng)建的產(chǎn)品有多個(gè)產(chǎn)品線(xiàn)時(shí)使? 抽象??模式是?較好的選擇
- 抽象??模式在 Spring 中應(yīng)?得最為?泛的?種設(shè)計(jì)模式
 
- 背景: - ???法模式引???等級(jí)結(jié)構(gòu),解決了簡(jiǎn)單??模式 中??類(lèi)職責(zé)過(guò)重的問(wèn)題
- 但???法模式中每個(gè)??只創(chuàng)建?類(lèi)具體類(lèi)的對(duì)象, 后續(xù)發(fā)展可能會(huì)導(dǎo)致??類(lèi)過(guò)多,因此將?些相關(guān)的具 體類(lèi)組成?個(gè)“具體類(lèi)族”,由同?個(gè)??來(lái)統(tǒng)??產(chǎn), 強(qiáng)調(diào)的是?系列相關(guān)的產(chǎn)品對(duì)象!!!
 
- 實(shí)現(xiàn)步驟: - 1、定義兩個(gè)接? IPay(支付)、IRefund(退款)
- 2、創(chuàng)建具體的Pay產(chǎn)品、創(chuàng)建具體的Refund產(chǎn)品
- 3、創(chuàng)建抽象?? IOrderFactory 接? ??兩個(gè)?法 createPay/createRefund
- 4、創(chuàng)建?付寶產(chǎn)品族AliOderFactory,實(shí)現(xiàn)OrderFactory 抽象??
- 5、創(chuàng)建微信?付產(chǎn)品族WechatOderFactory,實(shí)現(xiàn) OrderFactory抽象??
- 6、定義?個(gè)超級(jí)??創(chuàng)造器FactoryProducer,通過(guò)傳遞參數(shù)獲取對(duì)應(yīng)的??
 
接下來(lái)我們就按照步驟使用一下抽象工廠(chǎng)方法模式:
1、定義兩個(gè)接? IPay(支付)、IRefund(退款):
/*** @Auther: csp1999* @Date: 2020/11/07/16:06* @Description: 支付抽象接口*/ public interface IPay {/*** 統(tǒng)一下單*/void unifiedOrder(); } /*** @Auther: csp1999* @Date: 2020/11/07/16:07* @Description: 退款抽象接口*/ public interface IReFund {/*** 退款*/void refund(); }2、創(chuàng)建具體的Pay產(chǎn)品、創(chuàng)建具體的Refund產(chǎn)品:
AliPay/WeChatPay:支付寶支付和微信支付
/*** @Auther: csp1999* @Date: 2020/11/07/11:29* @Description: 支付寶支付具體實(shí)現(xiàn)類(lèi)*/ public class AliPay implements IPay {@Overridepublic void unifiedOrder() {System.out.println("支付寶支付 統(tǒng)一下單接口...");} } /*** @Auther: csp1999* @Date: 2020/11/07/11:30* @Description: 微信支付具體實(shí)現(xiàn)類(lèi)*/ public class WeChatPay implements IPay {@Overridepublic void unifiedOrder() {System.out.println("微信支付統(tǒng)一下單...");} }AliRefund/WeChatFund:支付寶退款和微信退款
/*** @Auther: csp1999* @Date: 2020/11/07/16:35* @Description:*/ public class AliRefund implements IReFund {@Overridepublic void refund() {System.out.println("支付寶退款...");} } /*** @Auther: csp1999* @Date: 2020/11/07/16:40* @Description:*/ public class WeChatRefund implements IReFund {@Overridepublic void refund() {System.out.println("微信支付退款...");} }3、創(chuàng)建抽象?? IOrderFactory 接? ??兩個(gè)?法 createPay/createRefund:
/*** @Auther: csp1999* @Date: 2020/11/07/16:04* @Description: 訂單抽象工廠(chǎng),一個(gè)超級(jí)工廠(chǎng)可以創(chuàng)建其他工廠(chǎng)(又被稱(chēng)為其他工廠(chǎng)的工廠(chǎng))*/ public interface IOrderFactory {IPay createPay();IReFund createRefund(); }4、創(chuàng)建?付寶產(chǎn)品族AliOderFactory,實(shí)現(xiàn)OrderFactory 抽象??:
/*** @Auther: csp1999* @Date: 2020/11/07/16:18* @Description:*/ public class AliOrderFactory implements IOrderFactory {@Overridepublic IPay createPay() {return new AliPay();}@Overridepublic IReFund createRefund() {return new AliRefund();} }5、創(chuàng)建微信?付產(chǎn)品族WechatOderFactory,實(shí)現(xiàn) OrderFactory抽象??
/*** @Auther: csp1999* @Date: 2020/11/07/16:39* @Description:*/ public class WeChatOrderFactory implements IOrderFactory {@Overridepublic IPay createPay() {return new WeChatPay();}@Overridepublic IReFund createRefund() {return new WeChatRefund();} }6、定義?個(gè)超級(jí)??創(chuàng)造器FactoryProducer,通過(guò)傳遞參數(shù)獲取對(duì)應(yīng)的??
/*** @Auther: csp1999* @Date: 2020/11/07/16:46* @Description: 工廠(chǎng)創(chuàng)造器*/ public class FactoryProducer {public static IOrderFactory getFactory(String type){if (type.equalsIgnoreCase("WECHAT")){return new WeChatOrderFactory();}else if (type.equalsIgnoreCase("ALI")){return new AliOrderFactory();}return null;} }最后我們來(lái)進(jìn)行測(cè)試:
@Test public void testAbstractMethodPayFactory(){IOrderFactory wechatPayFactory = FactoryProducer.getFactory("WECHAT");wechatPayFactory.createPay().unifiedOrder();wechatPayFactory.createRefund().refund();IOrderFactory aliPayFactory = FactoryProducer.getFactory("ALI");aliPayFactory.createPay().unifiedOrder();aliPayFactory.createRefund().refund(); }結(jié)果如下:
微信支付統(tǒng)一下單... 微信支付退款... 支付寶支付 統(tǒng)一下單接口... 支付寶退款...- ???法模式和抽象???法模式 - 當(dāng)抽象??模式中每?個(gè)具體??類(lèi)只創(chuàng)建?個(gè)產(chǎn)品對(duì) 象,抽象??模式退化成???法模式
 
- 優(yōu)點(diǎn) - 當(dāng)?個(gè)產(chǎn)品族中的多個(gè)對(duì)象被設(shè)計(jì)成?起?作時(shí),它能 保證使??始終只使?同?個(gè)產(chǎn)品族中的對(duì)象
- 產(chǎn)品等級(jí)結(jié)構(gòu)擴(kuò)展容易,如果需要增加多?個(gè)產(chǎn)品等 級(jí),只需要增加新的??類(lèi)和產(chǎn)品類(lèi)即可, ?如增加銀 ??付、退款
 
- 缺點(diǎn) - 產(chǎn)品族擴(kuò)展困難,要增加?個(gè)系列的某?產(chǎn)品,既要在 抽象的??和抽象產(chǎn)品?修改代碼,不是很符合開(kāi)閉原 則
- 增加了系統(tǒng)的抽象性和理解難度
 
之后我會(huì)陸續(xù)更新其他設(shè)計(jì)模式博文,如果文章對(duì)您有幫助,希望點(diǎn)個(gè)贊/收藏/關(guān)注! O(∩_∩)O~
總結(jié)
以上是生活随笔為你收集整理的初学Java常用设计模式之——工厂模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: Codeforces Round #54
- 下一篇: 江苏省计算机二级c语言题型分值,计算机二
