• Java描述设计模式(04):抽象工厂模式


    本文源码:GitHub·点这里 || GitEE·点这里

    一、抽象工厂模式

    1、生活场景

    汽车生产根据用户选择的汽车类型,指定不同的工厂进行生产,选择红旗轿车,就要使用中国工厂,选择奥迪轿车,就要使用德国工厂。

    2、抽象工厂模式

    1. 抽象工厂模式:定义了一个interface用于创建相关对象或相互依赖的对象,而无需指明具体的类;
    2. 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合;
    3. 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
    4. 将工厂抽象成两层,AbstractFactory(抽象工厂) 和 具体实现的工厂子类,方便程序扩展。

    3、代码UML图

    4、源代码实现

    /**
     * 抽象工厂模式
     */
    public class C01_AbstractFactory {
        public static void main(String[] args) {
            CarProductFactory factory = new ChinaCarFactory() ;
            factory.getCar("hq") ;
            factory = new GermanyCarFactory () ;
            factory.getCar("ad") ;
        }
    }
    
    // 汽车生产抽象工厂
    interface CarProductFactory {
        CarProduct getCar (String type) ;
    }
    // 中国汽车工厂
    class ChinaCarFactory implements CarProductFactory {
        @Override
        public CarProduct getCar(String type) {
            CarProduct product = null ;
            if ("hq".equals(type)){
                product = new HQCar() ;
                product.name="红旗一号" ;
                product.date="1999-09-19" ;
                product.material();
                product.origin();
            } else if ("df".equals(type)){
                product = new DFCar() ;
                product.name="东风一号" ;
                product.date="2019-09-19" ;
                product.material();
                product.origin();
            }
            return product ;
        }
    }
    // 德国汽车工厂
    class GermanyCarFactory implements CarProductFactory {
        @Override
        public CarProduct getCar(String type) {
            CarProduct product = null ;
            if ("ad".equals(type)){
                product = new ADCar() ;
                product.name="奥迪A8" ;
                product.date="2017-09-19" ;
                product.material();
                product.origin();
            } else if ("bm".equals(type)){
                product = new BMCar() ;
                product.name="宝马X8" ;
                product.date="2018-09-19" ;
                product.material();
                product.origin();
            }
            return product ;
        }
    }
    // 汽车生产抽象类
    abstract class CarProduct {
        /**
         * 汽车名称
         */
        protected String name ;
        /**
         * 生产日期
         */
        protected String date ;
        /**
         * 材料
         */
        abstract void material () ;
        /**
         * 产地
         */
        abstract void origin () ;
    }
    // 红旗车
    class HQCar extends CarProduct {
        @Override
        void material() {
            System.out.println(super.name+"材料...");
        }
        @Override
        void origin() {
            System.out.println(super.date+":"+super.name+"在中国北京生产");
        }
    }
    // 东风车
    class DFCar extends CarProduct {
        @Override
        void material() {
            System.out.println(super.name+"材料...");
        }
        @Override
        void origin() {
            System.out.println(super.date+":"+super.name+"在中国南京生产");
        }
    }
    // 奥迪车
    class ADCar extends CarProduct {
        @Override
        void material() {
            System.out.println(super.name+"材料...");
        }
        @Override
        void origin() {
            System.out.println(super.date+":"+super.name+"在德国柏林生产");
        }
    }
    // 宝马车
    class BMCar extends CarProduct {
        @Override
        void material() {
            System.out.println(super.name+"材料...");
        }
        @Override
        void origin() {
            System.out.println(super.date+":"+super.name+"在德国慕尼黑生产");
        }
    }
    

    二、Spring框架应用

    1、场景描述

    Spring框架中获取配置文件中Bean的多种方式。

    2、核心配置

    <bean id="carBean" class="com.model.design.spring.node04.abstractFactory.CarBean">
        <property name="name" value="中国红旗" />
    </bean>
    <bean id="carBean1" class="com.model.design.spring.node04.abstractFactory.CarBean">
        <property name="name" value="德国奥迪" />
    </bean>
    

    3、测试文件

    这里使用了两种方式获取。

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:/spring/spring-abstract-factory.xml"})
    public class SpringTest {
    
        @Resource
        private BeanFactory beanFactory ;
    
        @Test
        public void test01 (){
            CarBean carBean = (CarBean)beanFactory.getBean("carBean") ;
            System.out.println(carBean.getName());
        }
    
        @Test
        public void test02 (){
            ApplicationContext context01 = new ClassPathXmlApplicationContext(
                    "/spring/spring-abstract-factory.xml");
            CarBean carBean = (CarBean)context01.getBean("carBean1") ;
            System.out.println(carBean.getName());
        }
    }
    

    4、结构分析


    抽象工厂封装对象的创建。在Spring中,通过实现BeanFactory。可以从Spring的各种容器获取bean。根据Bean的配置,getBean方法可以返回不同类型的对象(单例作用域)或初始化新的对象(原型作用域)。在BeanFactory的实现中,我们可以区分:ClassPathXmlApplicationContext,XmlWebApplicationContext等。

    三、工厂模式小结

    三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式),工厂模式的核心用意将实例化对象的代码封装起来,放到工厂类中统一管理和维护,完成代码依赖关系的解耦。从而提高程序的可扩展性和维护性。

    四、源代码地址

    GitHub·地址
    https://github.com/cicadasmile/model-arithmetic-parent
    GitEE·地址
    https://gitee.com/cicadasmile/model-arithmetic-parent
    

  • 相关阅读:
    js中FOR循环的陷阱
    Struts2学习第七课 result
    Struts2学习第七课 ActionSupport
    Struts2学习第六课 实现登录登出功能
    Struts2学习第五课 通过和ServletAPI耦合的方式获取WEB资源
    Struts2学习第四课 通过Aware接口获取WEB资源
    子类重写父类的方法
    字节流和字符流
    Java数据库连接库JDBC用到哪种设计模式?
    Java接口
  • 原文地址:https://www.cnblogs.com/cicada-smile/p/11223183.html
Copyright © 2020-2023  润新知