溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

創(chuàng)建型模式:工廠方法

發(fā)布時(shí)間:2020-07-24 14:29:07 來(lái)源:網(wǎng)絡(luò) 閱讀:214 作者:LieBrother 欄目:軟件技術(shù)

文章首發(fā)
創(chuàng)建型模式:工廠方法

創(chuàng)建型模式:工廠方法

簡(jiǎn)介

姓名:工廠方法

英文名:Factory method Pattern

價(jià)值觀:擴(kuò)展是我的專(zhuān)屬

個(gè)人介紹

Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses. (定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類(lèi)決定實(shí)例化哪一個(gè)類(lèi)。工廠方法使一個(gè)類(lèi)的實(shí)例化延遲到其子類(lèi)。)
(來(lái)自《設(shè)計(jì)模式之禪》)

你要的故事

還記得上一篇 單例模式 中的故事么?小明開(kāi)著汽車(chē)去旅游、去學(xué)校、去聚會(huì)。這一次還是延續(xù)小明的故事,一個(gè)故事能講 2 個(gè)設(shè)計(jì)模式,不容易呀。。。(每次想故事都想破腦袋,每一篇文章至少有 3 個(gè)故事從腦子里閃過(guò),但最終留下的只有一個(gè)適合,為了就是能比較清晰簡(jiǎn)單的說(shuō)明設(shè)計(jì)模式中的關(guān)鍵要點(diǎn)。)

簡(jiǎn)單工廠

小明家里以前不算很富裕,但是還是有一個(gè)不錯(cuò)的車(chē)庫(kù),什么汽車(chē)、摩托車(chē)、自行車(chē)啥的都放在這個(gè)車(chē)庫(kù)里。小明每次要出去,都會(huì)到車(chē)庫(kù)里面挑合適的車(chē)出發(fā)。比如,小明最近期末考試了,騎摩托車(chē)去學(xué)校考試,考完試之后,小明就準(zhǔn)備去旅游,這次決定自駕游,開(kāi)著自己家的小汽車(chē)去。這個(gè)場(chǎng)景我們用代碼描述下。

public class SimpleFactoryTest {

    public static void main(String[] args) {
        XiaoMing xiaoMing = new XiaoMing();
        // 小明騎摩托車(chē)去學(xué)校
        IVehicle motorcycle = GarageFactory.getVehicle("motorcycle");
        xiaoMing.goToSchool(motorcycle);

        // 小明開(kāi)汽車(chē)去旅游
        IVehicle car = GarageFactory.getVehicle("car");
        xiaoMing.travel(car);
    }

}

/**
 * 車(chē)庫(kù)
 */
class GarageFactory {

    public static IVehicle getVehicle(String type) {
        if ("car".equals(type)) {
            return new Car();
        } else if ("motorcycle".equals(type)) {
            return new Motorcycle();
        }
        throw new IllegalArgumentException("請(qǐng)輸入車(chē)類(lèi)型");
    }

}

/**
 * 交通工具
 */
interface IVehicle {
    void run();
}

/**
 * 汽車(chē)
 */
class Car implements IVehicle {

    @Override
    public void run() {
        System.out.println("開(kāi)汽車(chē)去。。。。");
    }
}

/**
 * 摩托車(chē)
 */
class Motorcycle implements IVehicle {

    @Override
    public void run() {
        System.out.println("騎摩托車(chē)去。。。。");
    }
}

class XiaoMing {

    public void goToSchool(IVehicle vehicle) {
        System.out.println("小明去學(xué)校");
        vehicle.run();
    }

    public void travel(IVehicle vehicle) {
        System.out.println("小明去旅游");
        vehicle.run();
    }

}

上面代碼看懂了么? 小明家里有一個(gè)車(chē)庫(kù) GarageFactory,里面放著汽車(chē) Car 和摩托車(chē) Motorcycle,小明要出去的時(shí)候,就到車(chē)庫(kù)選擇車(chē),通過(guò)傳遞參數(shù)給 GarageFactory.getVehicle(),指明要什么車(chē),然后小明就騎著車(chē)出發(fā)了。

這個(gè)代碼真正的術(shù)語(yǔ)叫:簡(jiǎn)單工廠模式(Simple Factory Pattern),也叫做靜態(tài)工廠模式。它是工廠方法中的一個(gè)實(shí)現(xiàn)方式,從字面理解就可以知道,它是最簡(jiǎn)單的工廠方法實(shí)現(xiàn)方式。它有一點(diǎn)點(diǎn)小缺陷,就是擴(kuò)展性不夠好,在上面代碼中,小明只能騎摩托車(chē)或者開(kāi)汽車(chē),如果小明要騎單車(chē)出去呢?勢(shì)必得在 GarageFactory 中添加 if 是自行車(chē)的邏輯。這違反了哪條規(guī)則了?是不是那個(gè)允許擴(kuò)展,拒絕修改的開(kāi)閉原則?

不是說(shuō)簡(jiǎn)單工廠這種實(shí)現(xiàn)方式不好,而是擴(kuò)展性不夠,在平時(shí)的開(kāi)發(fā)中,簡(jiǎn)單工廠模式也用得不少。在這個(gè)小明家里車(chē)不多的情況下,用一個(gè)車(chē)庫(kù)也是合適的。

工廠方法

小明老爸近幾年賺了不少,車(chē)迷的兩父子一直買(mǎi)車(chē),家里的車(chē)越來(lái)越多,這時(shí)候,他們決定多建幾個(gè)車(chē)庫(kù),按車(chē)類(lèi)型放置。比如,有一個(gè)汽車(chē)庫(kù),一個(gè)摩托車(chē)庫(kù)。這時(shí)候小明要開(kāi)汽車(chē)就去汽車(chē)庫(kù),要騎摩托車(chē)就去摩托車(chē)庫(kù)。代碼實(shí)現(xiàn)如下。

public class FactoryMethodTest {

    public static void main(String[] args) {
        XiaoMing xiaoMing = new XiaoMing();
        // 小明騎摩托車(chē)去學(xué)校
        VehicleGarage motorcycleGarage = new MotorcycleGarage();
        IVehicle motorcycle = motorcycleGarage.getVehicle();
        xiaoMing.goToSchool(motorcycle);

        // 小明開(kāi)汽車(chē)去旅游
        VehicleGarage carGarage = new CarGarage();
        IVehicle car = carGarage.getVehicle();
        xiaoMing.travel(car);
    }

}

interface VehicleGarage {
    IVehicle getVehicle();
}

/**
 * 汽車(chē)車(chē)庫(kù)
 */
class CarGarage implements VehicleGarage {

    @Override
    public IVehicle getVehicle() {
        return new Car();
    }
}

/**
 * 摩托車(chē)車(chē)庫(kù)
 */
class MotorcycleGarage implements VehicleGarage {

    @Override
    public IVehicle getVehicle() {
        return new Motorcycle();
    }
}

上面代碼重用了簡(jiǎn)單工廠實(shí)現(xiàn)方式的交通接口以及摩托車(chē)和汽車(chē)的實(shí)現(xiàn)類(lèi)。代碼中有 2 個(gè)車(chē)庫(kù),一個(gè)是汽車(chē)車(chē)庫(kù) CarGarage,一個(gè)是摩托車(chē)庫(kù) MotorcycleGarage。如果小明要騎自行車(chē),只需要建一個(gè)自行車(chē)車(chē)庫(kù),完全不用去修改汽車(chē)車(chē)庫(kù)或者摩托車(chē)車(chē)庫(kù),就非常符合開(kāi)閉原則,擴(kuò)展性大大的提高。

總結(jié)

工廠方法模式可以說(shuō)在你能想到的開(kāi)源框架源碼中必定會(huì)使用的一個(gè)設(shè)計(jì)模式,因?yàn)殚_(kāi)源框架很重要一點(diǎn)就是要有擴(kuò)展性,而工廠方法模式恰恰具有可擴(kuò)展性。弄懂了工廠方法模式,以后看開(kāi)源代碼就很得心應(yīng)手啦。

代碼鏈接:Factory method Pattern

推薦閱讀

單一職責(zé)原則(方法:修改名字還是密碼?接口:洗碗、買(mǎi)菜還是倒垃圾?類(lèi):注冊(cè)、登錄和注銷(xiāo))
里氏替換原則(我兒來(lái)自新東方烹飪)
依賴(lài)倒置原則(摳門(mén)的飯店老板)
接口隔離原則(小伙子的作坊)
迪米特法則(手機(jī)上看電子書(shū))
開(kāi)閉原則(社保這點(diǎn)事)
創(chuàng)建型模式:?jiǎn)卫J剑ㄐ∶骶椭挥?1 輛車(chē))

公眾號(hào)后臺(tái)回復(fù)『大禮包』獲取 Java、Python、IOS 等教程
加個(gè)人微信備注『教程』獲取架構(gòu)師、機(jī)器學(xué)習(xí)等教程

創(chuàng)建型模式:工廠方法

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI