摘要:本文用一个实例场景描述Gof 23设计模式中的工厂(Factory Method)模式,并用Quarkus框架代码给予实现,同时也给出实现代码的UML模型。
关键字:Gof 23 设计模式 工厂模式 Quarkus
1 基础知识
1.1 标准定义
工厂(Factory Method)模式标准定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。
1.2 分析和说明
工厂(Factory Method)模式是一个创建性的模式。它要求工厂类和产品类分开。由一个工厂类可以根据传入的参量决定创建出哪一种产品类的实例,但这些不同的实例有共同的父类。Factory Method把创建这些实例的具体过程封装起来了。当一个类无法预料将要创建哪种类的对象或是一个类需要由子类来指定创建的对象时,我们就需要用到Factory Method模式了。
图1 工厂模式结构
工厂(Factory Method)模式结构如图1所示说明。工厂模式涉及到抽象工厂角色、具体工厂角色、抽象产品角色以及具体产品角色等。
抽象工厂(Creator)角色:任何在模式中创建对象的工厂类必须实现这个接口。在实际的系统中,这个角色也常常使用抽象类或接口实现。
具体工厂(Concrete Creator)角色:担任这个角色的是实现了抽象工厂接口的具体类。具体工厂角色含有与应用密切相关的逻辑,并且受到应用程序的调用以创建产品对象。在实际的系统中这个角色使用具体类实现。
抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在实际的系统中,这个角色也常常使用抽象类或者接口来实现。
具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所声明的接口。工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。这个角色使用具体类来实现。
2 应用场景举例
比如某一类公司能提供一种产品,但是这种产品有不同的型号。当客户需要一种产品,但是没有具体是哪一种型号,只是提供了一些产品参数,公司就根据这些参数来提供产品。这就是工厂模式。用例如图2。
图2 工厂模式的用例图
在这里可以把公司(Company)理解为抽象工厂角色。CompanyA是具体工厂(Concrete Creator)角色。Product是抽象产品(Product)角色。ProductA和ProductB是具体产品(Concrete Product)角色。其实现类图如图3所示。
图3 工厂模式的类图
工厂模式实现的顺序图见图4。实现顺序描述:① 客户首先创建一个具体公司;② 客户向公司申请一个产品并传入产品参数。③ 具体公司按照客户要求新建一个产品;④ 具体公司把产品返回给客户。⑤ 客户调用产品方法。
图4 工厂模式实现顺序图
3.Quarkus的程序实现代码
Quarkus程序实现主要包括Company接口文件,Product接口文件,CompanyA类文件,ProductA和ProductB类文件等5个文件。其关系如图3所示。下面分别列出这5个文件的程序代码,最后列出测试代码并显示输出结果。
Company接口为(Creator)角色,Company接口的程序代码清单01所示。
程序代码清单01
public interface Company {
public Product bulidProduct(String Parameter);
}
Product接口为抽象产品(Product)角色,Product接口的程序代码清单02所示。
程序代码清单02
public interface Product {
public String productType = null;
public String getProductType ();
public void doUse();
}
CompanyA类为具体工厂(Concrete Creator)角色,CompanyA类文件程序代码清单03所示。
程序代码清单03
@ApplicationScoped
public class CompanyA implements Company{
public Product bulidProduct(String Parameter){
if (Parameter.equals("A")) return new ProductA();
else if (Parameter.equals("B")) return new ProductB();
else return null;
}
}
ProductA类和ProductB类为具体产品(Concrete Product)角色,ProductA和ProductB类文件程序代码清单04所示。
程序代码清单04
public class ProductA implements Product{
public String productType = "ProductA";
private String productParameter = "A";
public String getProductType(){return productType;}
public String getParameter(){ return productParameter;}
public void doUse(){System.out.println("这是ProductA实现的功能");}
}
public class ProductB implements Product{
public String productType = "ProductB";
private String productParameter = "B";
public String getProductType(){return productType;}
public String getParameter(){ return productParameter;}
public void doUse(){System.out.println("这是ProductB实现的功能");}
}
工厂模式测试程序的代码清单05所示。其实现的序列图如图4所示。
代码清单05
public class FactorymethodClient implements QuarkusApplication{
@ConfigProperty(name = "gof23.creationalpattern.factorymethod.title", defaultValue = "gof23")
String title;
@Inject
CompanyA company;
@Override
public int run(String... args){
System.out.println("——————" + title + "演示输出—————————");
// 根据传入的参数得到ProductA产品
Product product = company.bulidProduct("A");
product.doUse();
// 根据传入的参数得到ProductB产品
product = company.bulidProduct("B");
product.doUse();
return 0;
}
public static void main(String... args) {
Quarkus.run(FactorymethodClient.class, args);
}
}
工厂模式测试类输出结果如下所示:
这是ProductA实现的功能
这是ProductB实现的功能
4. 相关Quarkus程序源码下载
可以直接从github上获取代码,读者可以从github上clone预先准备好的示例代码。
git clone https://github.com/rengang66/quarkus-sample-gof23.git
这是一个Maven项目,然后Maven导入工程。该程序位于“src\main\java\com\iiit\quarkus\sample\gof23\creationalpattern\factorymethod”目录中。
同时也可以从gitee上clone预先准备好的示例代码,命令如下:
git clone https://gitee.com/rengang66/quarkus-sample-gof23.git
5 扩展和说明
工厂模式是应用最广的设计模式之一。
有些书籍中提出了简单工厂模式。简单工厂模式实际上就是把抽象工厂改为了静态工厂,具体产品由静态工厂创建出来。这其实是一种工厂模式的变种。
参考文献
[1] E.Gamma, R.Helm, R.Johnson, and Vlissides. Design Patterns Elements of Reusable Object Oriented Software. Addison-Wesley, 1995
[2] E.Gamma, R.Helm, R.Johnson, and Vlissides.著,李英军等译,设计模式:可复用面向对象软件的基础,北京:机械工业出版社.2000.9.
[3] 阎宏,Java与模式,北京:电子工业出版社. 2002.10
[4] 王俊峰 戚晓滨. 设计模式和UML. 计算机应用研究,1999.16(5), 27-29,39.
[5] 陈琴 朱正强. UML在设计模式描述中的应用. 计算机工程与设计,2003.24(4), 81-84.
[6] 周赛赛 谭汉松. Java程序开发中的设计模式. 企业技术开发,2006.25(3), 28-30.
[7] 陈东伟. 设计模式学习笔记之简单工厂模式. 程序员:CSDN开发高手,2004.(5), 102-105.
[8] 唐慕瑾 徐伯庆 孙国强. Java类的动态装载机制及其在设计模式中的应用. 上海理工大学学报,2004.26(1), 80-84.
[9] 板桥里人. Jive和设计模式. 程序员,2003.(6), 58-60.
[10] 谭炎 潘久辉. 开放源代码项目Jive的体系结构与设计模式. 科学技术与工程,2005.5(15), 1087-1090.
[11] 张良平 曾贤龙 王倩. 利用设计模式实现数据访问的泛化. 电脑编程技巧与维护,2008.(10), 33-38.
[12] 曹国民 陈根才 施文幸. 基于.NET平台的电力生产管理系统建模与实现. 计算机工程与设计,2008.29(1), 170-172,233.
[13] 齐晶晶 郭跟成 刘勇. 基于创建型模式的系统框架. 计算机应用与软件,2007.24(11), 70-72.
[14] 王莉 汤灵愈. 基于设计模式的遗传算法类库的框架模型. 科技创新导报,2008.(3), 7-8.
[15] 李长春 廖建新 王纯 朱晓民. 软件界面国际化及设计模式的应用. 北京工商大学学报:自然科学版,2007.25(5), 53-56.
[16] 杨洲 王自强 周余 都思丹. 设计模式在数据采集系统中的应用. 微电子学与计算机,2008.25(2), 107-110.
[17] 尚鲜连. 设计模式在数据持久层设计中的应用. 重庆科技学院学报:自然科学版,2008.10(6), 108-111.
[18] 刘蕴珊 刘列励. 设计模式在信息系统中的应用研究. 信息技术,2008.32(10), 121-123,126.
[19] 汪诚波 骆静峰 何钦铭. 一种新的设计模式——接口呼叫模型. 计算机系统应用,2008.(1), 49-53.
[20] 王翔. 用.Net实现领域对象适配机制及XML数据扩展. 计算机辅助工程,2008.17(2), 81-84.
[21] Quarkus官网. https://quarkus.io/