Java設(shè)計(jì)模式編程中的工廠方法模式和抽象工廠模式
工廠方法模式
動(dòng)機(jī)
創(chuàng)建一個(gè)對(duì)象往往需要復(fù)雜的過程,所以不適合包含在一個(gè)復(fù)合工廠中,當(dāng)有新的產(chǎn)品時(shí),需要修改這個(gè)復(fù)合的工廠,不利于擴(kuò)展。
而且,有些對(duì)象的創(chuàng)建可以需要用到復(fù)合工廠訪問不到的信息,所以,定義一個(gè)工廠接口,通過實(shí)現(xiàn)這個(gè)接口來決定實(shí)例化那個(gè)產(chǎn)品,這就是工廠方法模式,讓類的實(shí)例化推遲到子類中進(jìn)行。
目的
1. 定義一個(gè)接口,讓子類決定實(shí)例化哪個(gè)產(chǎn)品。
2. 通過通用接口創(chuàng)建對(duì)象。
實(shí)現(xiàn)
1. 產(chǎn)品接口和具體產(chǎn)品很好理解。
2. 工廠類提供一個(gè)工廠方法,返回一個(gè)產(chǎn)品對(duì)象。但是這個(gè)工廠方法是抽象的。
3. 具體工廠類實(shí)現(xiàn)工廠方法,完成具體產(chǎn)品的創(chuàng)建。
//幾個(gè)Button類 class Button{/* ...*/} class WinButton extends Button{/* ...*/} class MacButton extends Button{/* ...*/} //它們的工廠類 interface ButtonFactory{ abstract Button createButton(); } class WinButtonFactory implements ButtonFactory{ Button createButton(){ return new WinButton(); } } class MacButtonFactory implements ButtonFactory{ Button createButton(){ return new MacButton(); } }
適用場(chǎng)景
1. 創(chuàng)建對(duì)象時(shí)有比較多重復(fù)的代碼時(shí),可以考慮使用工廠方法模式執(zhí)行這些重復(fù)的部分。
2. 創(chuàng)建對(duì)象需要訪問某些信息,而這些信息不應(yīng)該包含在工廠類,那么可以讓子類來實(shí)現(xiàn)對(duì)象的創(chuàng)建。
3. 需要集中管理對(duì)象的創(chuàng)建,保持程序的一致性時(shí)。
抽象工廠模式
定義
抽象工廠模式提供了一種方式,可以將一組具有同一主題的單獨(dú)的工廠封裝起來。在正常使用中,客戶端程序需要?jiǎng)?chuàng)建抽象工廠的具體實(shí)現(xiàn),然后使用抽象工廠作為接口來創(chuàng)建這一主題的具體對(duì)象??蛻舳顺绦虿恍枰溃ɑ蜿P(guān)心)它從這些內(nèi)部的工廠方法中獲得對(duì)象的具體類型,因?yàn)榭蛻舳顺绦騼H使用這些對(duì)象的通用接口。抽象工廠模式將一組對(duì)象的實(shí)現(xiàn)細(xì)節(jié)與他們的一般使用分離開來。
“工廠”是創(chuàng)建產(chǎn)品(對(duì)象)的地方,其目的是將產(chǎn)品的創(chuàng)建與產(chǎn)品的使用分離。抽象工廠模式的目的,是將若干抽象產(chǎn)品的接口與不同主題產(chǎn)品的具體實(shí)現(xiàn)分離開。這樣就能在增加新的具體工廠的時(shí)候,不用修改引用抽象工廠的客戶端代碼。
使用抽象工廠模式,能夠在具體工廠變化的時(shí)候,不用修改使用工廠的客戶端代碼,甚至是在運(yùn)行時(shí)。然而,使用這種模式或者相似的設(shè)計(jì)模式,可能給編寫代碼帶來不必要的復(fù)雜性和額外的工作。正確使用設(shè)計(jì)模式能夠抵消這樣的“額外工作”。
實(shí)現(xiàn)
1. AbstractFactory - 定義創(chuàng)建抽象產(chǎn)品的接口方法。
2. ConcreteFactory - 實(shí)現(xiàn)方法創(chuàng)建具體的產(chǎn)品。
3. AbstractProduct - 聲明不同類型的產(chǎn)品的接口。
4. Product - 定義ConcreteFactory對(duì)應(yīng)的具體產(chǎn)品,實(shí)現(xiàn)AbstractProduct接口。
5. Client - 使用AbstractFactory和AbstractProduct類。
abstract class AbstractProductA{ public abstract void operationA1(); public abstract void operationA2(); } class ProductA1 extends AbstractProductA{ ProductA1(String arg){ System.out.println("Hello "+arg); } // Implement the code here public void operationA1() { }; public void operationA2() { }; } class ProductA2 extends AbstractProductA{ ProductA2(String arg){ System.out.println("Hello "+arg); } // Implement the code here public void operationA1() { }; public void operationA2() { }; } abstract class AbstractProductB{ //public abstract void operationB1(); //public abstract void operationB2(); } class ProductB1 extends AbstractProductB{ ProductB1(String arg){ System.out.println("Hello "+arg); } // Implement the code here } class ProductB2 extends AbstractProductB{ ProductB2(String arg){ System.out.println("Hello "+arg); } // Implement the code here } abstract class AbstractFactory{ abstract AbstractProductA createProductA(); abstract AbstractProductB createProductB(); } class ConcreteFactory1 extends AbstractFactory{ AbstractProductA createProductA(){ return new ProductA1("ProductA1"); } AbstractProductB createProductB(){ return new ProductB1("ProductB1"); } } class ConcreteFactory2 extends AbstractFactory{ AbstractProductA createProductA(){ return new ProductA2("ProductA2"); } AbstractProductB createProductB(){ return new ProductB2("ProductB2"); } } //Factory creator - an indirect way of instantiating the factories class FactoryMaker{ private static AbstractFactory pf=null; static AbstractFactory getFactory(String choice){ if(choice.equals("a")){ pf=new ConcreteFactory1(); }else if(choice.equals("b")){ pf=new ConcreteFactory2(); } return pf; } } // Client public class Client{ public static void main(String args[]){ AbstractFactory pf=FactoryMaker.getFactory("a"); AbstractProductA product=pf.createProductA(); //more function calls on product } }
FactoryMaker類使用的是簡(jiǎn)單工廠模式,而具體工廠的實(shí)現(xiàn)用的是工廠方法模式。
適用場(chǎng)景
1. 一個(gè)系統(tǒng)要獨(dú)立于它的產(chǎn)品的創(chuàng)建、組合和表示時(shí)。
2. 一個(gè)系統(tǒng)要由多個(gè)產(chǎn)品系列中的一個(gè)來配置時(shí)。
3. 需要強(qiáng)調(diào)一系列相關(guān)的產(chǎn)品對(duì)象的設(shè)計(jì)以便進(jìn)行聯(lián)合使用時(shí)。
4. 提供一個(gè)產(chǎn)品類庫,而只想顯示它們的接口而不是實(shí)現(xiàn)時(shí)。
優(yōu)點(diǎn)
1. 具體產(chǎn)品從客戶代碼中被分離出來
2. 容易改變產(chǎn)品的系列
3. 將一個(gè)系列的產(chǎn)品族統(tǒng)一到一起創(chuàng)建
缺點(diǎn)
1. 在產(chǎn)品族中擴(kuò)展新的產(chǎn)品是很困難的,它需要修改抽象工廠的接口和具體工廠。
- Java創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory)
- Java設(shè)計(jì)模式之抽象工廠模式淺析講解
- Java設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory)
- Java?深入理解創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式
- 深入理解Java設(shè)計(jì)模式之抽象工廠模式
- Java設(shè)計(jì)模式之簡(jiǎn)單工廠 工廠方法 抽象工廠深度總結(jié)
- Java設(shè)計(jì)模式之抽象工廠模式詳解
- Java設(shè)計(jì)模式之工廠模式分析【簡(jiǎn)單工廠、工廠方法、抽象工廠】
- Java設(shè)計(jì)模式之抽象工廠模式
- Java設(shè)計(jì)模式筆記之抽象工廠代碼示例
- Java設(shè)計(jì)模式之抽象工廠模式實(shí)例詳解
- Java設(shè)計(jì)模式編程中簡(jiǎn)單工廠與抽象工廠模式的使用實(shí)例
- Java設(shè)計(jì)模式之工廠方法和抽象工廠
相關(guān)文章
spring啟動(dòng)后保證創(chuàng)建的對(duì)象不被垃圾回收器回收
最近看到一個(gè)問題是,spring在啟動(dòng)后如何保證創(chuàng)建的對(duì)象不被垃圾回收器回收?。所以本文結(jié)合jvm的垃圾回收機(jī)制和spring中的源代碼做出自己的一點(diǎn)猜測(cè)。有需要的朋友們可以參考借鑒。2016-09-09servlet之web路徑問題_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了servlet之web路徑問題的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07Java Web項(xiàng)目中實(shí)現(xiàn)文件下載功能的實(shí)例教程
這篇文章主要介紹了Java Web項(xiàng)目中實(shí)現(xiàn)文件下載功能的實(shí)例教程,分別講解了通過超鏈接實(shí)現(xiàn)下載以及通過Servlet程序?qū)崿F(xiàn)下載的方式,需要的朋友可以參考下2016-05-05Java Socket實(shí)現(xiàn)單線程通信的方法示例
這篇文章主要介紹了Java Socket實(shí)現(xiàn)單線程通信的方法,結(jié)合具體實(shí)例形式分析了java socket單線程通信的原理與客戶端、服務(wù)器端相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-06-06SiteMesh如何結(jié)合Freemarker及velocity使用
這篇文章主要介紹了SiteMesh如何結(jié)合Freemarker及velocity使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10tk.mybatis實(shí)現(xiàn)uuid主鍵生成的示例代碼
本文主要介紹了tk.mybatis實(shí)現(xiàn)uuid主鍵生成的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12基于spring boot排除掃描類的三種方式小結(jié)
這篇文章主要介紹了spring boot排除掃描類的三種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08舉例講解Java的RTTI運(yùn)行時(shí)類型識(shí)別機(jī)制
這篇文章主要介紹了Java的RTTI運(yùn)行時(shí)類型識(shí)別機(jī)制,包括泛化的Class引用以及類型檢查instanceof等知識(shí)點(diǎn),需要的朋友可以參考下2016-05-05Java Arrays.sort()如何實(shí)現(xiàn)對(duì)int類型數(shù)組倒序排序
這篇文章主要介紹了Java Arrays.sort()如何實(shí)現(xiàn)對(duì)int類型數(shù)組倒序排序問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08