本文源码: 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
Java 描述设计模式(03): 工厂方法模式
来源: http://www.bubuko.com/infodetail-3190572.html