本文源碼:GitHub·點這裡 || GitEE·點這裡
一、工廠方法模式
1、生活場景
系統常見的資料導出功能:資料導出PDF、WORD等常見格式。
2、工廠方法模式
是類的建立模式,又叫做虛拟構造子(Virtual Constructor)模式或者多态性工廠(Polymorphic Factory)模式。工廠方法模式的用意是定義一個建立産品對象的工廠接口,将實際建立工作推遲到子類中。
3、核心角色
1)、抽象工廠角色
這個角色的是工廠方法模式的核心,任何在模式中建立對象的工廠類必須實作這個接口。在實際的系統中,這個角色也常常使用抽象類實作。
2)、具體工廠角色
擔任這個角色的是實作了抽象工廠接口的具體JAVA類。具體工廠角色含有與業務密切相關的邏輯,并且受到使用者的調用以建立導出類。
3)、抽象導出角色
工廠方法模式所建立的對象的超類,也就是所有導出類的共同父類或共同擁有的接口。在實際的系統中,這個角色也常常使用抽象類實作。
4)、具體導出角色
這個角色實作了抽象導出角色所聲明的接口,工廠方法模式所建立的每一個對象都是某個具體導出角色的執行個體。
4、代碼UML關系圖

5、源代碼實作
// 用戶端角色
public class C01_FactoryMethod {
public static void main(String[] args) {
String data = "" ;
ExportFactory factory = new ExportWordFactory () ;
ExportFile exportWord = factory.factory("user-word") ;
exportWord.export(data) ;
factory = new ExportPdfFactory() ;
ExportFile exportPdf =factory.factory("log-pdf") ;
exportPdf.export(data) ;
}
}
// 抽象工廠角色
interface ExportFactory {
ExportFile factory (String type) ;
}
// 具體工廠角色
class ExportWordFactory implements ExportFactory {
@Override
public ExportFile factory(String type) {
if ("user-word".equals(type)){
return new ExportUserWordFile() ;
} else if ("log-word".equals(type)){
return new ExportLogWordFile() ;
} else {
throw new RuntimeException("沒有找到對象") ;
}
}
}
class ExportPdfFactory implements ExportFactory {
@Override
public ExportFile factory(String type) {
if ("user-pdf".equals(type)){
return new ExportUserPdfFile() ;
} else if ("log-pdf".equals(type)){
return new ExportLogPdfFile() ;
} else {
throw new RuntimeException("沒有找到對象") ;
}
}
}
// 抽象導出角色
interface ExportFile {
boolean export (String data) ;
}
// 具體導出角色
class ExportUserWordFile implements ExportFile {
@Override
public boolean export(String data) {
System.out.println("導出使用者Word檔案");
return true;
}
}
class ExportLogWordFile implements ExportFile {
@Override
public boolean export(String data) {
System.out.println("導出日志Word檔案");
return true;
}
}
class ExportUserPdfFile implements ExportFile {
@Override
public boolean export(String data) {
System.out.println("導出使用者Pdf檔案");
return true;
}
}
class ExportLogPdfFile implements ExportFile {
@Override
public boolean export(String data) {
System.out.println("導出日志Pdf檔案");
return true;
}
}
二、Spring架構中應用
1、場景描述
基于spring架構的配置實作如下流程:汽車工廠根據不同的國家,生産不同類型的汽車。
2、核心工廠類
public class ProductCar implements CarFactory {
private Map<String, CarEntity> carMap = null;
public ProductCar() {
carMap = new HashMap<>();
carMap.put("china", new CarEntity("中國", "黑色","紅旗"));
carMap.put("america", new CarEntity("美國", "白色","雪佛蘭"));
}
@Override
public CarEntity getCar(String type) {
return carMap.get(type);
}
}
3、核心Xml配置檔案
<bean id="productCarFactory" class="com.model.design.spring.node03.factoryMethod.ProductCar" />
<bean id="car1" factory-bean="productCarFactory" factory-method="getCar">
<constructor-arg name="type" value="china" />
</bean>
<bean id="car2" factory-bean="productCarFactory" factory-method="getCar">
<constructor-arg name="type" value="america" />
</bean>
4、測試類
1)、代碼塊
public class SpringTest {
@Test
public void test01 (){
ApplicationContext context01 = new ClassPathXmlApplicationContext("/spring/spring-factorymethod.xml");
CarEntity car1 = (CarEntity)context01.getBean("car1") ;
CarEntity car2 = (CarEntity)context01.getBean("car2") ;
System.out.println(car1);
System.out.println(car2);
}
}
2)、輸出結果
CarEntity{country='中國', color='黑色', name='紅旗'}
CarEntity{country='美國', color='白色', name='雪佛蘭'}
三、工廠方法小結
工廠方法中,把建立類的動作延遲,就是通過對應的工廠來生成類的對象,這種設計方式符合“開閉”原則。缺點就是當産品的種類過多的時候,需要定義很多産品對應的工廠類。
四、源代碼位址
GitHub·位址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·位址
https://gitee.com/cicadasmile/model-arithmetic-parent