Java工廠模式之簡單工廠,工廠方法,抽象工廠模式詳解
1、簡單工廠模式
1.定義
簡單工廠模式(Simple Factory Pattern)是指由一個工廠對象決定創(chuàng)建出哪一種產(chǎn)品類的實例。
屬于創(chuàng)建型模式,但它不屬于GOF23種設(shè)計模式。
2.代碼案例
假設(shè)以罐頭產(chǎn)品的制造為案例
第一步:定義罐頭的頂層接口類ICanned
/** * @Package: com.hzg.study.design.pattern.factory.simplefactory * @Description: 罐頭頂層接口 * @Author: HuangZhiGao * @CreateDate: 2022-02-17 17:52 */ public interface ICanned { /** * 展示罐頭名稱 * <p/> * * @return void * @author HuangZhiGao * @date 2022/2/17/017 17:54 */ void showCannedName(); }
第二步:分別編寫兩個具體的實現(xiàn)類FruitCanned和BeefCanned
/** * @Package: com.hzg.study.design.pattern.factory.simplefactory * @Description: 水果罐頭 * @Author: HuangZhiGao * @CreateDate: 2022-02-17 17:56 */ public class FruitCanned implements ICanned { @Override public void showCannedName() { System.out.println("名稱:水果罐頭"); } }
/** * @Package: com.hzg.study.design.pattern.factory.simplefactory * @Description: 牛肉罐頭 * @Author: HuangZhiGao * @CreateDate: 2022-02-17 17:57 */ public class BeefCanned implements ICanned { @Override public void showCannedName() { System.out.println("名稱:牛肉罐頭"); } }
第三步:編寫工廠類
import com.hzg.study.design.pattern.factory.common.ICanned; /** * @Package: com.hzg.study.design.pattern.factory.simplefactory * @Description: 罐頭工廠類 * @Author: HuangZhiGao * @CreateDate: 2022-02-17 18:16 */ public class CannedFactory { /** * 創(chuàng)建罐頭的方法 * <p/> * * @param clazz * @return com.hzg.study.design.pattern.factory.common.ICanned * @author HuangZhiGao * @date 2022/2/17/017 18:18 */ public ICanned createCanned(Class<? extends ICanned> clazz) { if (null != clazz) { try { return clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); } } return null; } }
第四步:main方法測試、查看類圖
import com.hzg.study.design.pattern.factory.common.BeefCanned; import com.hzg.study.design.pattern.factory.common.FruitCanned; import com.hzg.study.design.pattern.factory.common.ICanned; /** * @Package: com.hzg.study.design.pattern.factory.simplefactory * @Description: 測試類 * @Author: HuangZhiGao * @CreateDate: 2022-02-17 18:22 */ public class SimpleFactoryTest { public static void main(String[] args) { CannedFactory cannedFactory = new CannedFactory(); ICanned fruitCanned = cannedFactory.createCanned(FruitCanned.class); fruitCanned.showCannedName(); System.out.println("----------------------------------------"); ICanned beefCanned = cannedFactory.createCanned(BeefCanned.class); beefCanned.showCannedName(); } }
運行結(jié)果:
名稱:水果罐頭
----------------------------------------
名稱:牛肉罐頭
簡單工廠模式類圖:
3.適用場景
工廠類負責(zé)創(chuàng)建的對象較少,不需要關(guān)心創(chuàng)建對象的邏輯
4.優(yōu)缺點
優(yōu)點:
簡化了客戶端創(chuàng)建對象的過程
缺點:
1.工廠類職責(zé)相對較重,在一定程度上可能違背開閉原則(增加新的產(chǎn)品可能需要修改工廠類邏輯)
2.不易于擴展過于復(fù)雜的產(chǎn)品結(jié)構(gòu)
2、工廠方法模式
1.定義
工廠方法模式(Factory Method Pattern)是指定義一個創(chuàng)建對象的接口,但讓實現(xiàn)這個接口的類來決定實例化哪個類,工廠方法讓類的實例化推遲到子類中進行。
屬于創(chuàng)建型設(shè)計模式。
2.代碼案例
需要使用到簡單工廠模式的ICanned、FruitCanned、BeefCanned
第一步:定義罐頭工廠頂層接口類ICannedFactory
import com.hzg.study.design.pattern.factory.common.ICanned; /** * @Package: com.hzg.study.design.pattern.factory.factorymethod * @Description: 罐頭工廠頂層接口 * @Author: HuangZhiGao * @CreateDate: 2022-02-18 10:03 */ public interface ICannedFactory { /** * 創(chuàng)建罐頭方法 * <p/> * * @return void * @author HuangZhiGao * @date 2022/2/18/018 10:04 */ ICanned doCreateCanned(); }
第二步:分別編寫兩個具體的工廠實現(xiàn)類FruitCannedFactory和BeefCannedFactory
import com.hzg.study.design.pattern.factory.common.FruitCanned; import com.hzg.study.design.pattern.factory.common.ICanned; /** * @Package: com.hzg.study.design.pattern.factory.factorymethod * @Description: 水果罐頭工廠類 * @Author: HuangZhiGao * @CreateDate: 2022-02-18 10:05 */ public class FruitCannedFactory implements ICannedFactory { @Override public ICanned doCreateCanned() { return new FruitCanned(); } }
import com.hzg.study.design.pattern.factory.common.BeefCanned; import com.hzg.study.design.pattern.factory.common.ICanned; /** * @Package: com.hzg.study.design.pattern.factory.factorymethod * @Description: 牛肉罐頭工廠類 * @Author: HuangZhiGao * @CreateDate: 2022-02-18 10:08 */ public class BeefCannedFactory implements ICannedFactory { @Override public ICanned doCreateCanned() { return new BeefCanned(); } }
第三步:main方法測試、查看類圖
import com.hzg.study.design.pattern.factory.common.BeefCanned; import com.hzg.study.design.pattern.factory.common.FruitCanned; import com.hzg.study.design.pattern.factory.common.ICanned; /** * @Package: com.hzg.study.design.pattern.factory.simplefactory * @Description: 測試類 * @Author: HuangZhiGao * @CreateDate: 2022-02-17 18:22 */ public class SimpleFactoryTest { public static void main(String[] args) { CannedFactory cannedFactory = new CannedFactory(); ICanned fruitCanned = cannedFactory.createCanned(FruitCanned.class); fruitCanned.showCannedName(); System.out.println("----------------------------------------"); ICanned beefCanned = cannedFactory.createCanned(BeefCanned.class); beefCanned.showCannedName(); } }
運行結(jié)果:
名稱:水果罐頭
----------------------------------------
名稱:牛肉罐頭
工廠方法模式類圖:
3.適用場景
創(chuàng)建對象需要大量重復(fù)的代碼。
客戶端(應(yīng)用層)不依賴于產(chǎn)品類實例如何被創(chuàng)建、實現(xiàn)等細節(jié)。
一個類通過其子類來指定創(chuàng)建哪個對象。
4.優(yōu)缺點
優(yōu)點:
1.用戶只需關(guān)心所需產(chǎn)品對應(yīng)的工廠,無須關(guān)心創(chuàng)建細節(jié)。
2.加入新產(chǎn)品符合開閉原則,提高了系統(tǒng)的可擴展性。
缺點:
1.類的個數(shù)容易過多,增加了代碼結(jié)構(gòu)的復(fù)雜度。
2.增加了系統(tǒng)的抽象性和理解難度。
3、抽象工廠模式
1.定義
抽象工廠模式(Abstract Factory Pattern)是指提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,無須指定他們具體的類。
屬于創(chuàng)建型設(shè)計模式。
抽象工廠模式有產(chǎn)品族和產(chǎn)品等級的概念,可以通俗的理解為
產(chǎn)品族相當(dāng)于不同品牌的產(chǎn)品合集,產(chǎn)品等級相當(dāng)于不同品牌的同一種產(chǎn)品
例如:水果罐頭的材料信息、標(biāo)簽信息組成了一個產(chǎn)品族,牛肉罐頭的材料信息、標(biāo)簽信息組成了一個產(chǎn)品族
水果罐頭的材料信息、牛肉罐頭的材料信息組成一個產(chǎn)品等級,水果罐頭的標(biāo)簽信息、牛肉罐頭的標(biāo)簽信息組成一個產(chǎn)品等級
2.代碼案例
假設(shè)制造一個罐頭包含兩個部分(材料信息+標(biāo)簽信息)
第一步:分別定義罐頭材料信息接口IMaterialInfo和罐頭標(biāo)簽信息接口ITagInfo
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: 罐頭材料信息接口 * @Author: HuangZhiGao * @CreateDate: 2022-02-18 10:51 */ public interface IMaterialInfo { /** * 打印材料信息 * <p/> * * @return void * @author HuangZhiGao * @date 2022/2/18/018 10:57 */ void printMaterialInfo(); }
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: 罐頭標(biāo)簽信息接口 * @Author: HuangZhiGao * @CreateDate: 2022-02-18 10:48 */ public interface ITagInfo { /** * 打印標(biāo)簽信息 * <p/> * * @return void * @author HuangZhiGao * @date 2022/2/18/018 10:57 */ void printTagInfo(); }
第二步:定義罐頭的頂層工廠接口類ICannedFactory
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: 頂層工廠接口:一個罐頭包含兩個部分(材料信息+標(biāo)簽信息) * @Author: HuangZhiGao * @CreateDate: 2022-02-18 10:47 */ public interface ICannedFactory { IMaterialInfo createMaterialInfo(); ITagInfo createTagInfo(); }
第三步:分別編寫具體實現(xiàn)類FruitMaterialInfo、FruitTagInfo和BeefMaterialInfo、BeefTagInfo
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: * @Author: HuangZhiGao * @CreateDate: 2022-02-18 11:05 */ public class FruitMaterialInfo implements IMaterialInfo { @Override public void printMaterialInfo() { System.out.println("材料:水果"); } }
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: * @Author: HuangZhiGao * @CreateDate: 2022-02-18 11:05 */ public class FruitTagInfo implements ITagInfo { @Override public void printTagInfo() { System.out.println("標(biāo)簽:2022升級版水果罐頭"); } }
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: * @Author: HuangZhiGao * @CreateDate: 2022-02-18 11:05 */ public class BeefMaterialInfo implements IMaterialInfo { @Override public void printMaterialInfo() { System.out.println("材料:牛肉"); } }
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: * @Author: HuangZhiGao * @CreateDate: 2022-02-18 11:06 */public class BeefTagInfo implements ITagInfo { @Override public void printTagInfo() { System.out.println("標(biāo)簽:2022升級版牛肉罐頭"); }}/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: * @Author: HuangZhiGao * @CreateDate: 2022-02-18 11:06 */ public class BeefTagInfo implements ITagInfo { @Override public void printTagInfo() { System.out.println("標(biāo)簽:2022升級版牛肉罐頭"); } }
第四步:分別編寫工廠具體實現(xiàn)類FruitCannedFactory、BeefCannedFactory
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: * @Author: HuangZhiGao * @CreateDate: 2022-02-18 11:04 */ public class FruitCannedFactory implements ICannedFactory { @Override public IMaterialInfo createMaterialInfo() { return new FruitMaterialInfo(); } @Override public ITagInfo createTagInfo() { return new FruitTagInfo(); } }
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: * @Author: HuangZhiGao * @CreateDate: 2022-02-18 11:04 */ public class BeefCannedFactory implements ICannedFactory { @Override public IMaterialInfo createMaterialInfo() { return new BeefMaterialInfo(); } @Override public ITagInfo createTagInfo() { return new BeefTagInfo(); } }
第五步:main方法測試、查看類圖
/** * @Package: com.hzg.study.design.pattern.factory.abstractfactory * @Description: * @Author: HuangZhiGao * @CreateDate: 2022-02-18 11:12 */ public class AbstractFactoryTest { public static void main(String[] args) { ICannedFactory beefCannedFactory = new BeefCannedFactory(); beefCannedFactory.createMaterialInfo().printMaterialInfo(); beefCannedFactory.createTagInfo().printTagInfo(); System.out.println("----------------------------------------"); ICannedFactory fruitCannedFactory = new FruitCannedFactory(); fruitCannedFactory.createMaterialInfo().printMaterialInfo(); fruitCannedFactory.createTagInfo().printTagInfo(); } }
運行結(jié)果:
材料:牛肉
標(biāo)簽:2022升級版牛肉罐頭
----------------------------------------
材料:水果
標(biāo)簽:2022升級版水果罐頭
抽象工廠模式類圖:
3.適用場景
客戶端(應(yīng)用層)不依賴于產(chǎn)品類實例如何被創(chuàng)建、實現(xiàn)等細節(jié)。
強調(diào)一系列相關(guān)的產(chǎn)品對象(屬于同一產(chǎn)品族)一起使用創(chuàng)建對象需要大量重復(fù)的代碼。
提供一個產(chǎn)品類的庫,所有的產(chǎn)品以同樣的接口出現(xiàn),從而使客戶端不依賴于具體實現(xiàn)。
4.優(yōu)缺點
優(yōu)點:
1.具體產(chǎn)品在應(yīng)用層代碼隔離,無須關(guān)心創(chuàng)建細節(jié)。
2.將一個系列的產(chǎn)品族統(tǒng)一到一起創(chuàng)建。
缺點:
1.規(guī)定了所有可能被創(chuàng)建的產(chǎn)品集合,產(chǎn)品族中擴展新的產(chǎn)品困難,需要修改抽象工廠的接口。
2.增加了系統(tǒng)的抽象性和理解難度。
4、總結(jié)
簡單工廠、工廠方法和抽象工廠的區(qū)別:
工廠方法和抽象工廠是GOF23種設(shè)計模式中的兩種,簡單工廠不是一種設(shè)計模式,可以理解為是一種約定俗成的編碼習(xí)慣。
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java?empty、null、blank的區(qū)別小結(jié)
本文主要介紹了Java?empty、null、blank的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06跟我學(xué)Java Swing之游戲設(shè)計(2)
跟我學(xué)Java Swing之游戲設(shè)計(2)...2006-12-12java之向linux文件夾下寫文件無權(quán)限的問題
這篇文章主要介紹了java之向linux文件夾下寫文件無權(quán)限的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09spring boot mybatis多數(shù)據(jù)源解決方案過程解析
這篇文章主要介紹了spring boot mybatis多數(shù)據(jù)源解決方案過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11Mybatis入門指南之實現(xiàn)對數(shù)據(jù)庫增刪改查
數(shù)據(jù)持久層主要負責(zé)數(shù)據(jù)的增、刪、改、查等功能,MyBatis 則是一款優(yōu)秀的持久層框架,下面這篇文章主要給大家介紹了關(guān)于Mybatis入門指南之實現(xiàn)對數(shù)據(jù)庫增刪改查的相關(guān)資料,需要的朋友可以參考下2022-10-10Mybatis配置之<properties>屬性配置元素解析
這篇文章主要介紹了Mybatis配置之<properties>屬性配置元素解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07SpringBoot實現(xiàn)過濾器、攔截器與切片的實現(xiàn)和區(qū)別
本文詳細介紹了使用過濾器、攔截器與切片實現(xiàn)每個請求耗時的統(tǒng)計,并比較三者的區(qū)別與聯(lián)系,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-02-02