天天看點

Java描述設計模式(04):抽象工廠模式一、抽象工廠模式二、Spring架構應用三、工廠模式小結四、源代碼位址

GitHub位址: https://github.com/cicadasmile/model-arithmetic-parent

一、抽象工廠模式

1、生活場景

汽車生産根據使用者選擇的汽車類型,指定不同的工廠進行生産,選擇紅旗轎車,就要使用中國工廠,選擇奧迪轎車,就要使用德國工廠。

2、抽象工廠模式

1) 抽象工廠模式:定義了一個interface用于建立相關對象或互相依賴的對象,而無需指明具體的類;

2) 抽象工廠模式可以将簡單工廠模式和工廠方法模式進行整合;

3) 從設計層面看,抽象工廠模式就是對簡單工廠模式的改進(或者稱為進一步的抽象)。

4) 将工廠抽象成兩層,AbstractFactory(抽象工廠) 和 具體實作的工廠子類,友善程式擴充。

3、代碼UML圖

Java描述設計模式(04):抽象工廠模式一、抽象工廠模式二、Spring架構應用三、工廠模式小結四、源代碼位址

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、結構分析

Java描述設計模式(04):抽象工廠模式一、抽象工廠模式二、Spring架構應用三、工廠模式小結四、源代碼位址
Java描述設計模式(04):抽象工廠模式一、抽象工廠模式二、Spring架構應用三、工廠模式小結四、源代碼位址
抽象工廠封裝對象的建立。在Spring中,通過實作BeanFactory。可以從Spring的各種容器擷取bean。根據Bean的配置,getBean方法可以傳回不同類型的對象(單例作用域)或初始化新的對象(原型作用域)。在BeanFactory的實作中,我們可以區分:ClassPathXmlApplicationContext,XmlWebApplicationContext等。

三、工廠模式小結

三種工廠模式 (簡單工廠模式、工廠方法模式、抽象工廠模式),工廠模式的核心用意将執行個體化對象的代碼封裝起來,放到工廠類中統一管理和維護,完成代碼依賴關系的解耦。進而提高程式的可擴充性和維護性。

四、源代碼位址

GitHub位址:知了一笑
https://github.com/cicadasmile/model-arithmetic-parent
碼雲位址:知了一笑
https://gitee.com/cicadasmile/model-arithmetic-parent