zoukankan      html  css  js  c++  java
  • Java描述设计模式(03):工厂方法模式

    本文源码: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
    

  • 相关阅读:
    String类的substring方法
    postman绕过登录,进行接口测试的方法
    Dubbo
    那些吊炸天的互联网名词
    版本控制工具git
    Ubunto20.04 sudo apt-get update 出现目标被重置多次!
    ubuntu环境下搭建Hadoop集群中必须需要注意的问题
    Python作业---内置数据类型
    python作业完成简单的文件操作
    python3实现计算器
  • 原文地址:https://www.cnblogs.com/cicada-smile/p/11218874.html
Copyright © 2011-2022 走看看