1. 程式人生 > >抽象工廠模式(Java)

抽象工廠模式(Java)

工廠模式可以分為:簡單工廠模式,工廠方法模式,抽象工廠模式。

簡單工廠模式就沒什麼好說的了,無非是所有的東西都寫在一個類裡面,要什麼就呼叫什麼,如果要新增新的方法也是到這類裡面新增,程式碼很多,看起來也是很亂,就像一個大工廠,什麼都在裡面。擴充套件性很低。

而工廠方法模式,把說明的理論和生產的東西就分開一點。抽象工廠模式是工廠方法模式的升級。 說簡單點,後面兩種工廠模式都是java三大特徵的繼承和多型的具體表現,你從後面的類圖中就可以很簡單看到繼承(介面為實現)的關係,而你在程式碼中就很容易看到多型的使用。 關於工廠方法模式,上次已經有詳細的介紹了,本文主要是介紹抽象工廠模式。

抽象工廠模式的概念

抽象工廠模式的定義:為建立一組相關或相互依賴的物件提供一個介面,而且無需指定它們的具體類。 同時你也可以對比一下工廠方法模式的定義:為某個物件提供一個介面,而且無需指定它們的具體類。 都是子類實現介面的方法,並在子類寫具體的程式碼。這裡抽象工廠的介面類是能建立多個相關的物件,而工廠方法的介面類是隻建立一個物件。

抽象工廠模式的類圖:

1 對比工廠方法模式,你要知道它們之間的類圖區別,就能理解這兩種模式的區別。 工廠方法模式中也是可以有多個具體工廠,也是可以有多個抽象產品,和多個具體工廠、具體產品類。區別是在抽象工廠介面類中,能建立幾個產品物件。 抽象工廠模式的工廠能建立多個相關的產品物件,而工廠方法模式的工廠只建立一個產品物件。

抽象工廠模式的優點/缺點:

1.優點

針對同一組產品建立新的生產線,只需實現那組產品的抽象工廠介面即可建立新的工廠類。

2.缺點

抽象方法模式的最大缺點就是產品族本身的擴充套件非常困難。如果在產品族中增加一個新的產品型別,則需要修改多個介面,並影響現已有的工廠類。 上面這句話,有些人不怎麼理解,我給大家解釋一下,打個比方說,你要在這個工廠建立三個物件,原本只是建立兩個物件的,那麼你就要在抽象方法中新增一個建立物件的方法,那麼所有實現了這個介面的類都是要重新新增這個建立物件的方法,這就是對之前的工廠有影響的原因。

抽象工廠模式的應用場景

當一個物件都有相同的約束時,可以使用抽象工廠模式。 打個比方說,這個工廠的幾個產品都需要經過某些共同的步驟和打上相同的商標,這一組產品可以在一個工廠裡面生產,減少很多重複的程式碼在不同的地方都出現多次。

抽象工廠模式的例項

這裡設計一個工廠生產賓士汽車和它對應的導航儀兩種產品。

例項類圖

2 這個類圖和上面的抽象工廠的類圖是一樣的,只是把東西具體化,程式碼化。

各個介面/類的程式碼

(1)生產賓士的介面Benz

package P3_abstractFactory;

/**
 * 賓士產品的抽象介面
 */
public interface Benz {
    void carColor();//設定顏色
    void carSpeed();//設定速度
    void carPrice();//設定價格

}


(2)生產車輛導航儀的介面類

package P3_abstractFactory;

/**
 * 車輛導航儀的抽象產品介面類
 */
public interface CarNavigator {

    void navigatorColor();//導航儀的顏色

    void navigatorPrice();//導航儀的價格


}

(3)賓士工廠的抽象介面類BanzFactory

package P3_abstractFactory;

/**
 * 賓士工廠的抽象介面
 */
public interface BanzFactory {
    /**
     * 建立賓士的方法
     */
      Benz createCar();

    /**
     * 建立導航儀的方法
     */
    CarNavigator createNacigator();

}

(4)生產賓士車輛C180和相關導航儀的具體工廠類

package P3_abstractFactory;

/**
 * 生產某一個型號賓士車輛的實際工廠
 */
public class C180Factory implements BanzFactory {
    @Override
    public Benz createCar() {
        return new BenzC180();
    }

    @Override
    public CarNavigator createNacigator() {
        return new C180Navigator();
    }
}

(5)生產賓士車輛Z260和相關導航儀的具體工廠類

package P3_abstractFactory;

/**
 * 生產某一個型號賓士車E260輛的實際工廠
 */
public class E260Factory implements BanzFactory {
    @Override
    public Benz createCar() {
        return new BenzE260();
    }

    @Override
    public CarNavigator createNacigator() {
        return new E260Navigator();
    }
}

(6)生產賓士車輛C180的具體產品類

package P3_abstractFactory;

/**
 * 賓士C180的生產的具體類
 */
public class BenzC180 implements Benz {
    /**
     * 構造方法,建立的時候就設定基本屬性
     */
    public BenzC180() {
        carColor();
        carPrice();
        carSpeed();
    }

    @Override
    public void carColor() {
        System.out.println("賓士C180的顏色是銀白色");

    }

    @Override
    public void carSpeed() {
        System.out.println("賓士C180的速度是200公里每小時");
    }

    @Override
    public void carPrice() {
        System.out.println("賓士C180的價格是100萬");
    }
}

(7)生產賓士車輛C180對應導航儀的具體產品類

package P3_abstractFactory;

/**
 * 車型C180的導航儀
 */
public class C180Navigator implements CarNavigator {

    C180Navigator(){
        navigatorColor();
        navigatorPrice();
    }

    @Override
    public void navigatorColor() {
        System.out.println("汽車C180的導航儀顏色:黑色");
    }

    @Override
    public void navigatorPrice() {
        System.out.println("汽車C180的導航儀價格:480元");
    }
}

賓士車輛E260的具體產品類

package P3_abstractFactory;

/**
 * 賓士E260的生產的具體類
 */
public class BenzE260 implements Benz {
    /**
     * 構造方法,建立的時候就設定基本屬性
     */
    public BenzE260() {
        carColor();
        carPrice();
        carSpeed();
    }

    @Override
    public void carColor() {
        System.out.println("賓士E260的顏色是銀白色");

    }

    @Override
    public void carSpeed() {
        System.out.println("賓士E260的速度是200公里每小時");
    }

    @Override
    public void carPrice() {
        System.out.println("賓士E260的價格是100萬");
    }
}

(7)生產賓士車輛E260對應導航儀的具體產品類

package P3_abstractFactory;

/**
 * 車型E260的導航儀
 */
public class E260Navigator implements CarNavigator {

    E260Navigator(){
        navigatorColor();
        navigatorPrice();
    }

    @Override
    public void navigatorColor() {
        System.out.println("汽車E260的導航儀顏色:白色");
    }

    @Override
    public void navigatorPrice() {
        System.out.println("汽車E260的導航儀價格:880元");
    }
}

生產賓士車輛和相關產品的呼叫者類AbstractFactoryDemo

package P3_abstractFactory;

/**
 * 抽象工廠模式呼叫
 * 生產兩個賓士車C180、E260和它們對應的導航儀的演示
 * 這裡使用多型的方法類建立各個類別的車型產品
 */
public class AbstractFactoryDemo {
    public static void main(String[] a) {
        System.out.println("生產賓士車C180");
        //父類但物件子類的例項
        BanzFactory banzFactory = new C180Factory();//建立一個C180工廠
        //呼叫父類的方法,這就是java多型的一種體現
        banzFactory.createCar();//C180工廠生產車輛C180
        banzFactory.createNacigator();//生產車輛C180對應的導航儀

        System.out.println("=========================================");
        System.out.println("生產賓士車Z260");
        BanzFactory banzFactory2 = new E260Factory();
        banzFactory2.createCar();//E260工廠生產車輛E260
        banzFactory2.createNacigator();//生產車輛E260對應的導航儀

    }

}

程式執行的結果:

3

從例項中分析,工廠方法模式的優點/缺點

1.優點

如果需要生產新的汽車產品和對應的導航儀裝置,你只需要建立一個該產品對應的具體工廠和該產品的具體實現類,不需要改變抽象的工廠類和抽象的產品類,具體工廠類和具體產品類需要什麼操作已經在抽象介面類定義好了。

2.缺點

之前有說工廠方法的擴充套件性算是比較好的,而抽象工廠模式的擴充套件性就沒那麼好了。 比如說某個工廠需要多建立幾個產品物件,那麼就需要增加抽象工廠的方法,增加抽象介面的方法後,其他實現了抽象工廠介面方法的所有類都需要改變,才能正常編譯。

比如:我們在程式碼中有定義生產導航儀的介面方法和具體實現,那如果我們新增一個新的產品,比如內建空調,這時候要在抽象介面中新增定義生產空調的介面,並且之前所有的產品類都實現的這個介面,所以之前型號的汽車也要實現內建空調的方法,這裡方法可以是沒有具體操作的,但是方法肯定是要實現的。

https://blog.csdn.net/wenzhi20102321/article/details/78153437?utm_source=copy