為了賬號安全,請及時綁定郵箱和手機立即綁定

Java設計模式----------抽象工廠模式

2018.03.10 15:53 5977瀏覽
1、介紹

意圖:提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。

主要解決:主要解決接口選擇的問題。

何時使用:系統的產品有多于一個的產品族,而系統只消費其中某一族的產品。

如何解決:在一個產品族里面,定義多個產品。每個具體的工廠負責一個產品族。抽象工廠的返回值為最高級抽象產品。

關鍵代碼:在一個工廠里聚合多個同類產品(在同一個產品族中)。

應用實例:舉一個衣服與衣柜的例子。家里邊,有男裝(產品族,其中包含休閑男裝和商務男裝)、女裝(產品族,其中包含休閑女裝和商務女裝)。商務女裝、商務男裝、時尚女裝、時尚男裝,這些都是具體產品。男裝專門放在男衣柜(具體工廠)中,女裝專門放在女衣柜(具體工廠)中。當我們需要拿衣服時候,從衣柜(抽象工廠)中獲取。

所以抽象工廠,非常適合解決兩個維度的組合產品的構造問題,取其中一個維度作為產品族,另外一個維度作為產品族中具體的多個產品。

優點:能夠從多個產品族的多個產品中,簡潔的獲取想要的具體產品。解決了工廠模式中的不符合開閉原則的問題(增加新的產品時候,不修改工廠,而是增加工廠)。

缺點:產品族擴展比較困難,要增加一個系列的某一產品,要增加具體的產品類,還要增加對應的工廠類(或者修改對應產品族的工廠類)。

注意事項:產品族難擴展,產品等級易擴展。

2、案例
2.1、背景

還是舉買車的例子。

某客戶想要購買一輛車,他要聯系4S店,首先得有4S店(抽象工廠)的電話。

客戶上網查詢(建造工廠),發現了寶馬4S店(具體工廠)的電話和奔馳4S店(具體工廠)的電話。

客戶撥通了寶馬4S店的電話(獲取具體工廠),發現目前店里可以提供(生產)多款車型(具體產品)供客戶選擇(BMW 320、BMW 530,BMW 740)。

客戶撥通了奔馳4S店的電話(獲取具體工廠),發現目前店里可以提供(生產)多款車型(具體產品)供客戶選擇(BenzC200、BenzE300)。

2.2、實現

汽車類

/**
 * 最高級抽象產品,用于抽象工廠的建造方法的返回值
 */
public abstract class Car
{
    abstract void drive();
}

寶馬產品類

/**
 * 抽象產品
 */
public abstract class BMWCar extends Car
{
}
/**
 * 具體產品BMW320
 */
public class BMW320 extends BMWCar
{
    public void drive()
    {
        System.out.println("BMW320,運動酷炫。");
    }
}
/**
 * 具體產品BMW530
 */
public class BMW530 extends BMWCar
{
    public void drive()
    {
        System.out.println("BMW530,時不我待。");
    }
}
/**
 * 具體產品BMW740
 */
public class BMW740 extends BMWCar
{
    public void drive()
    {
        System.out.println("BMW740,高端商務。");
    }
}

奔馳產品類

/**
 * 抽象產品
 */
public abstract class BenzCar extends Car
{
}
/**
 * 具體產品C200
 */
public class BenzC200 extends BenzCar
{
    public void drive()
    {
        System.out.println("BenzC200,實惠有面");
    }
}
/**
 * 具體產品E300
 */
public class BenzE300 extends BenzCar
{
    public void drive()
    {
        System.out.println("BenzE300,商務氣派");
    }
}

工廠類

/**
 * 奔馳工廠,覆蓋所有奔馳車型的構造方法
 */
public class BenzFactory extends AbstractFactory
{
    public Car getCar(String type) throws ClassNotFoundException,
            IllegalAccessException, InstantiationException
    {
        Class cl = Class.forName(type);
        return (BenzCar)cl.newInstance();
    }
}
/**
 * 寶馬工廠,覆蓋所有寶馬車型的構造方法
 */
public class BMWFactory extends AbstractFactory
{
    public Car getCar(String type) throws ClassNotFoundException,
            IllegalAccessException, InstantiationException
    {
        Class cl = Class.forName(type);
        return (BMWCar)cl.newInstance();
    }
}

抽象工廠類

public abstract class AbstractFactory
{
    public abstract Car getCar(String type) throws ClassNotFoundException,
            IllegalAccessException, InstantiationException;
}

超級工廠類

/**
 * 超級工廠類,建造工廠的工廠
 */
public class FactoryProducer
{
    public static AbstractFactory getFactory(String type)
            throws IllegalAccessException, InstantiationException, ClassNotFoundException
    {
        Class cl = Class.forName(type);
        System.out.println("創建工廠"+type);
        return (AbstractFactory)cl.newInstance();
    }
}

驗證

/**
 * 驗證
 */
public class Demo
{
    public static void main(String[] args) throws IllegalAccessException, 
        InstantiationException, ClassNotFoundException
    {
        AbstractFactory abstractFactory = FactoryProducer.getFactory("BMWFactory");
        Car bmwCar = abstractFactory.getCar("BMW320");
        bmwCar.drive();

        Car bmwCar1 = abstractFactory.getCar("BMW530");
        bmwCar1.drive();

        Car bmwCar2 = abstractFactory.getCar("BMW740");
        bmwCar2.drive();

        AbstractFactory abstractFactory1 = FactoryProducer.getFactory("BenzFactory");
        Car benzCar = abstractFactory1.getCar("BenzC200");
        benzCar.drive();

        Car benzCar1 = abstractFactory1.getCar("BenzE300");
        benzCar1.drive();
    }
}

運行結果如下如所示:
圖片描述

3、總結

抽象工廠模式非常針對2個維度描述的產品的構造問題。取其中一個維度作為產品族(也就是對應一個具體工廠),另外一個維度作為產品族下的具體產品。從這個角度說,抽象工廠模式是在工廠模式基礎上,做了一個維度的升級。

舉例,比如商務男裝,商務女裝,時尚男裝,時尚女裝的選擇問題。取男裝為一個產品族,對應一個工廠;取女裝作為一個產品族,對應一個工廠。每個工廠中會生產多種類型(商務或者時尚)的衣服。

點擊查看更多內容
8人點贊

若覺得本文不錯,就分享一下吧!

評論

相關文章推薦

正在加載中
意見反饋 幫助中心 APP下載
官方微信

舉報

0/150
提交
取消
lpl竞猜