Java工廠模式之簡單工廠,工廠方法,抽象工廠模式詳解
1、簡單工廠模式
1.定義
簡單工廠模式(Simple Factory Pattern)是指由一個工廠對象決定創(chuàng)建出哪一種產品類的實例。
屬于創(chuàng)建型模式,但它不屬于GOF23種設計模式。
2.代碼案例
假設以罐頭產品的制造為案例
第一步:定義罐頭的頂層接口類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();
}
}
運行結果:
名稱:水果罐頭
----------------------------------------
名稱:牛肉罐頭
簡單工廠模式類圖:

3.適用場景
工廠類負責創(chuàng)建的對象較少,不需要關心創(chuàng)建對象的邏輯
4.優(yōu)缺點
優(yōu)點:
簡化了客戶端創(chuàng)建對象的過程
缺點:
1.工廠類職責相對較重,在一定程度上可能違背開閉原則(增加新的產品可能需要修改工廠類邏輯)
2.不易于擴展過于復雜的產品結構
2、工廠方法模式
1.定義
工廠方法模式(Factory Method Pattern)是指定義一個創(chuàng)建對象的接口,但讓實現(xiàn)這個接口的類來決定實例化哪個類,工廠方法讓類的實例化推遲到子類中進行。
屬于創(chuàng)建型設計模式。
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();
}
}
運行結果:
名稱:水果罐頭
----------------------------------------
名稱:牛肉罐頭
工廠方法模式類圖:

3.適用場景
創(chuàng)建對象需要大量重復的代碼。
客戶端(應用層)不依賴于產品類實例如何被創(chuàng)建、實現(xiàn)等細節(jié)。
一個類通過其子類來指定創(chuàng)建哪個對象。
4.優(yōu)缺點
優(yōu)點:
1.用戶只需關心所需產品對應的工廠,無須關心創(chuàng)建細節(jié)。
2.加入新產品符合開閉原則,提高了系統(tǒng)的可擴展性。
缺點:
1.類的個數(shù)容易過多,增加了代碼結構的復雜度。
2.增加了系統(tǒng)的抽象性和理解難度。
3、抽象工廠模式
1.定義
抽象工廠模式(Abstract Factory Pattern)是指提供一個創(chuàng)建一系列相關或相互依賴對象的接口,無須指定他們具體的類。
屬于創(chuàng)建型設計模式。
抽象工廠模式有產品族和產品等級的概念,可以通俗的理解為
產品族相當于不同品牌的產品合集,產品等級相當于不同品牌的同一種產品
例如:水果罐頭的材料信息、標簽信息組成了一個產品族,牛肉罐頭的材料信息、標簽信息組成了一個產品族
水果罐頭的材料信息、牛肉罐頭的材料信息組成一個產品等級,水果罐頭的標簽信息、牛肉罐頭的標簽信息組成一個產品等級
2.代碼案例
假設制造一個罐頭包含兩個部分(材料信息+標簽信息)
第一步:分別定義罐頭材料信息接口IMaterialInfo和罐頭標簽信息接口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: 罐頭標簽信息接口
* @Author: HuangZhiGao
* @CreateDate: 2022-02-18 10:48
*/
public interface ITagInfo {
/**
* 打印標簽信息
* <p/>
*
* @return void
* @author HuangZhiGao
* @date 2022/2/18/018 10:57
*/
void printTagInfo();
}
第二步:定義罐頭的頂層工廠接口類ICannedFactory
/**
* @Package: com.hzg.study.design.pattern.factory.abstractfactory
* @Description: 頂層工廠接口:一個罐頭包含兩個部分(材料信息+標簽信息)
* @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("標簽: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("標簽: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("標簽: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();
}
}
運行結果:
材料:牛肉
標簽:2022升級版牛肉罐頭
----------------------------------------
材料:水果
標簽:2022升級版水果罐頭
抽象工廠模式類圖:

3.適用場景
客戶端(應用層)不依賴于產品類實例如何被創(chuàng)建、實現(xiàn)等細節(jié)。
強調一系列相關的產品對象(屬于同一產品族)一起使用創(chuàng)建對象需要大量重復的代碼。
提供一個產品類的庫,所有的產品以同樣的接口出現(xiàn),從而使客戶端不依賴于具體實現(xiàn)。
4.優(yōu)缺點
優(yōu)點:
1.具體產品在應用層代碼隔離,無須關心創(chuàng)建細節(jié)。
2.將一個系列的產品族統(tǒng)一到一起創(chuàng)建。
缺點:
1.規(guī)定了所有可能被創(chuàng)建的產品集合,產品族中擴展新的產品困難,需要修改抽象工廠的接口。
2.增加了系統(tǒng)的抽象性和理解難度。
4、總結
簡單工廠、工廠方法和抽象工廠的區(qū)別:
工廠方法和抽象工廠是GOF23種設計模式中的兩種,簡單工廠不是一種設計模式,可以理解為是一種約定俗成的編碼習慣。
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!
相關文章
Java實現(xiàn)字符串轉換成可執(zhí)行代碼的方法
今天小編就為大家分享一篇Java實現(xiàn)字符串轉換成可執(zhí)行代碼的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07
詳解SpringMVC組件之HandlerMapping(二)
這篇文章主要介紹了詳解SpringMVC組件之HandlerMapping(二),HandlerMapping組件是Spring?MVC核心組件,用來根據(jù)請求的request查找對應的Handler,在Spring?MVC中,有各式各樣的Web請求,每個請求都需要一個對應的Handler來處理,需要的朋友可以參考下2023-08-08
SpringBoot+Redis實現(xiàn)分布式緩存的方法步驟
在高并發(fā)的分布式的系統(tǒng)中,緩存是提升系統(tǒng)性能的重要手段,本文主要介紹了SpringBoot+Redis實現(xiàn)分布式緩存的方法步驟,具有一定的參考價值,感興趣的可以了解一下2024-07-07
基于SpringBoot服務端表單數(shù)據(jù)校驗的實現(xiàn)方式
這篇文章主要介紹了基于SpringBoot服務端表單數(shù)據(jù)校驗的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
Spring實戰(zhàn)之類級別緩存實現(xiàn)與使用方法
這篇文章主要介紹了Spring實戰(zhàn)之類級別緩存實現(xiàn)與使用方法,結合實例形式分析了Spring類級別緩存配置、屬性、領域模型等相關操作技巧,需要的朋友可以參考下2020-01-01

