Abstract Factory Pattern in Java

引言

抽象工廠模式是基于工廠模式之上的另一種創(chuàng)造性的設(shè)計(jì)模式,是工廠模式的一種抽象;基于工廠模式的案例抽象出抽象工廠模式。

抽象工廠模式設(shè)計(jì)全球化汽車(chē)工廠

在工廠模式中我們將不同類(lèi)型的汽車(chē)使用工廠流水線來(lái)生產(chǎn),隱藏其復(fù)雜的生產(chǎn)邏輯(構(gòu)建過(guò)程);假如我們生產(chǎn)的汽車(chē)是面向全球地區(qū)的,那么應(yīng)該如何讓我們的生產(chǎn)面向全球化。

為了支持全球化運(yùn)營(yíng),我們需要增強(qiáng)我們應(yīng)用程序,以便生產(chǎn)出支持不同國(guó)家地區(qū)風(fēng)格的汽車(chē),比如我們國(guó)家汽車(chē)的駕駛室在前排左側(cè),而美國(guó)等歐洲國(guó)家駕駛室在前排的右側(cè),我們必須支持這種差異化生產(chǎn)。

為了描述抽象工廠模式,我們將考慮3種產(chǎn)品 - 美國(guó),亞洲和默認(rèn)(所有其他國(guó)家),支持多個(gè)位置需要進(jìn)行關(guān)鍵的設(shè)計(jì)更改。

為了支持這種多樣化的生產(chǎn)細(xì)節(jié),我們需要增加工廠流水線,即USACarFactory,AsiaCarFactory和DefaultCarFactory。在新增3條流水線之后,我們的工廠便足以能夠面向多樣化生產(chǎn),而使用者只需要通過(guò)抽象工廠類(lèi)來(lái)制造自己想要的汽車(chē),不要關(guān)注其中的細(xì)節(jié)。

抽象工廠是基于工廠類(lèi)的基礎(chǔ)上的再一層抽象,我們需要將工廠類(lèi)根據(jù)不同類(lèi)型進(jìn)行改造,然后在抽象工廠中對(duì)新流水線進(jìn)行再次抽象。

抽象工廠的解決方案

抽象工廠封裝類(lèi)圖:

image.png

使用CarFactory隱藏位置工廠的生產(chǎn)細(xì)節(jié)。

抽象工廠實(shí)現(xiàn)

為汽車(chē)新增Location屬性:

package com.iblog.pattern.factory;

public enum Location {
    DEFAULT, USA, ASIA
}

抽象工廠類(lèi)實(shí)現(xiàn):

package com.iblog.pattern.factory;

public abstract class Car {
    private CarType model;
    private Location location;

    public Car(CarType model, Location location) {
        this.model = model;
        this.location = location;
    }

    private void arrangeParts() {
        // Do one time processing here
    }

    // Do subclass level processing in this method
    protected abstract void construct();

    public CarType getModel() {
        return model;
    }

    public void setModel(CarType model) {
        this.model = model;
    }
}

將Location屬性增加至各種汽車(chē)模型中(LuxuryCar):

package com.iblog.pattern.factory;

public class LuxuryCar extends Car {

    LuxuryCar(Location location) {
        super(CarType.LUXURY, location);
        construct();
    }

    @Override
    protected void construct() {
        System.out.println("Building luxury car");
        // add accessories
    }
}

將之前的工廠實(shí)現(xiàn)根據(jù)Location屬性進(jìn)行抽象:

package com.iblog.pattern.factory;

public class USACarFactory {
    public static Car buildCar(CarType model) {
        Car car = null;
        switch (model) {
            case SMALL:
                car = new SmallCar(Location.USA);
                break;

            case SEDAN:
                car = new SedanCar(Location.USA);
                break;

            case LUXURY:
                car = new LuxuryCar(Location.USA);
                break;

            default:
                //throw some exception
                break;
        }
        return car;
    }
}
package com.iblog.pattern.factory;

public class AsiaCarFactory {
    public static Car buildCar(CarType model) {
        Car car = null;
        switch (model) {
            case SMALL:
                car = new SmallCar(Location.ASIA);
                break;

            case SEDAN:
                car = new SedanCar(Location.ASIA);
                break;

            case LUXURY:
                car = new LuxuryCar(Location.ASIA);
                break;

            default:
                //throw some exception
                break;
        }
        return car;
    }
}
package com.iblog.pattern.factory;

public class DefaultCarFactory {
    public static Car buildCar(CarType model) {
        Car car = null;
        switch (model) {
            case SMALL:
                car = new SmallCar(Location.DEFAULT);
                break;

            case SEDAN:
                car = new SedanCar(Location.DEFAULT);
                break;

            case LUXURY:
                car = new LuxuryCar(Location.DEFAULT);
                break;

            default:
                //throw some exception
                break;
        }
        return car;
    }
}

然后我們?cè)?個(gè)Location工廠之上抽象出來(lái)一個(gè)新的抽象工廠類(lèi),我們通過(guò)不同Location工廠類(lèi)來(lái)生產(chǎn)汽車(chē):

package com.iblog.pattern.factory;

public class CarFactory {
    private CarFactory() {
        //Prevent instantiation
    }

    public static Car buildCar(CarType model) {
        Car car = null;
        //Read location property somewhere from configuration, also as a param.
        Location location = Location.USA;

        //Use location specific car factory
        switch (location) {
            case USA:
                car = USACarFactory.buildCar(model);
                break;
            case ASIA:
                car = AsiaCarFactory.buildCar(model);
                break;
            case DEFAULT:
                car = DefaultCarFactory.buildCar(model);
                break;
            default:
                // throw some exception
                break;
        }
        return car;
    }
}

測(cè)試:

package com.iblog.pattern.factory;

import org.junit.Test;

import static org.junit.Assert.*;

public class CarFactoryTest {

    @Test
    public void buildCar() {
        System.out.println(CarFactory.buildCar(CarType.SMALL));
        System.out.println(CarFactory.buildCar(CarType.SEDAN));
        System.out.println(CarFactory.buildCar(CarType.LUXURY));
    }
}

結(jié)果:

Building small car
com.iblog.pattern.factory.SmallCar@5b80350b
Building sedan car
com.iblog.pattern.factory.SedanCar@5d6f64b1
Building luxury car
com.iblog.pattern.factory.LuxuryCar@32a1bec0

Summary

當(dāng)我們?cè)诠S模式實(shí)現(xiàn)中需要對(duì)工廠進(jìn)行抽象編程時(shí),應(yīng)用抽象工廠實(shí)現(xiàn),與工廠模式之間多了一層抽象邏輯,在Jdk中抽象工廠模式也是常見(jiàn)的:

案例地址:https://github.com/major2015/pattern-example

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容