嘻哈說:設計模式之工廠方法模式

一、嘻哈說

這首歌還沒寫不能發java

由於本節的工廠方法模式與抽象工廠模式存在關聯度,因此會在下一節《抽象工廠模式》中混成一首歌發。設計模式

二、簡單工廠模式的定義

現實中的工廠,是用來生產產品的,而代碼中的工廠,則是建立對象的,bash

用來建立對象,那確定就是建立型模式了。ide

咱們常常會用到三種和工廠相關的設計模式:簡單工廠模式、工廠方法模式、抽象工廠模式。學習

這節我們要說的是——工廠方法模式。ui

不過,再說工廠方法以前,咱們要先說下簡單工廠模式。咱們從簡單的開始入手,由簡入繁。spa

簡單工廠模式呢,它不屬於Gof23種設計模式之一,但它在實際的項目中常常被用到,因此咱們仍是頗有必要學習,而且它的思想也很是簡單,能夠說是工廠方法模式的一個引導。設計

咱們來看一下簡單工廠方法的定義。code

又稱爲靜態工廠模式,由一個工廠對象決定建立出哪種產品類的實例。cdn

注意這裏的定義,是一個工廠對象

怎麼實現呢?實現的套路是什麼?

定義一個工廠類,能夠根據參數的不一樣返回不一樣類的實例,被建立的實例一般有共同的父類。

三、場景

場景與建造者模式有點相似,仍是熟悉的餃子,仍是熟悉的配方,仍是熟悉的味道,扯遠了...

美食餃子

番茄餐廳的後廚。

廚師長:老闆,我據說隔壁餐廳買來了一個機器,包餃子神器,一輸入參數,餃子直接出鍋,高科技呀,跟餃子工廠似的。

老闆:你的意思是我們也去買個?

廚師長:嗯,我是想提這個建議的,一鍵出餃子,想一想內心還有點小激動呢。

老闆:你不會是爲了圖省事吧?

求生欲極強的廚師長:固然不是,我是以爲餃子神器效率高,可以給咱們飯店帶來更大的價值。

老闆:嗯,那我贊成了,錢從你工資里扣。

委屈的廚師長:老闆,這樣不合適吧?我上有老,下有...

老闆:打住,逗你的,看把你給嚇得。效率提升但味道下降,這種神器我們飯店不會用的。

咱們今天的例子,就是餃子工廠,能夠生產各類餃子餡、皮。

四、簡單工廠模式

簡單工廠UML圖

簡單工廠模式的UML類圖。

package com.fanqiekt.factory.simple;

/**
 * 餃子餡
 *
 * @Author: 番茄課堂-懶人
 */
public interface IStuffing {

    void make();

}
複製代碼

IStuffing:產品(餃子餡)的接口,共有的父類。

make()就是製造餃子皮的方法。

package com.fanqiekt.factory.simple;

/**
 * 豬肉大蔥餡
 * @Author: 番茄課堂-懶人
 */
public class PorkStuffing implements IStuffing {

    @Override
    public void make() {
        System.out.println("製做豬肉大蔥餡");
    }

}
複製代碼
package com.fanqiekt.factory.simple;

/**
 * 茴香雞蛋餡
 * @Author: 番茄課堂-懶人
 */
public class FoeniculumVulgareStuffing implements IStuffing {

    @Override
    public void make() {
        System.out.println("製做茴香雞蛋餡");
    }

}
複製代碼
package com.fanqiekt.factory.simple;

/**
 * 韭菜雞蛋餡
 * @Author: 番茄課堂-懶人
 */
public class ChineseChivesStuffing implements IStuffing {

    @Override
    public void make() {
        System.out.println("製做韭菜雞蛋餡");
    }

}
複製代碼

具體的產品類,餃子餡中的大戶:豬肉大蔥餡、茴香雞蛋餡、韭菜雞蛋餡。

package com.fanqiekt.factory.simple;

/**
 * 餃子餡工廠類
 * @Author: 番茄課堂-懶人
 */
public class StuffingFactory {
    public static IStuffing getStuffing(String key){
        IStuffing stuffing = null;
        switch (key){
            case "豬肉大蔥":
                stuffing = new PorkStuffing();
                break;
            case "韭菜雞蛋":
                stuffing = new ChineseChivesStuffing();
                break;
            case "茴香雞蛋":
                stuffing = new FoeniculumVulgareStuffing();
                break;
        }
        return stuffing;
    }
}
複製代碼

StuffingFactory:餃子餡工廠類。

簡單工廠中只有一個工廠類,而且提供了一個靜態公有方法,能夠根據參數的不一樣返回不一樣類的實例。

這也是簡單方法爲何要被稱之爲靜態工廠模式的緣由。

package com.fanqiekt.factory.simple;

/**
 * 客戶端
 * @Author: 番茄課堂-懶人
 */
public class Client {

    public static void main(String args[]){
        IStuffing stuffing = StuffingFactory.getStuffing("豬肉大蔥");
        stuffing.make();

        System.out.println("------------");

        stuffing = StuffingFactory.getStuffing("韭菜雞蛋");
        stuffing.make();

        System.out.println("------------");

        stuffing = StuffingFactory.getStuffing("茴香雞蛋");
        stuffing.make();
    }

}
複製代碼

客戶端類。

咱們能夠看出,簡單工廠不愧爲簡單工廠,就是赤裸裸的簡單。

但簡單並不普通,它完美的展示了工廠方法的思想,讓工廠建立對象,而不是對象A去建立對象B。

這樣能夠避免對象A與對象B之間的耦合。

咱們運行一下,看結果。

製做豬肉大蔥餡
------------
製做韭菜雞蛋餡
------------
製做茴香雞蛋餡
複製代碼

五、工廠方法模式的定義

若是按照簡單工廠的寫法,在不使用java的反射的前提下,擴展性是不好的。

若是添加一種餃子餡,必須修改工廠中的判斷。

因此咱們來介紹一下另一種工廠模式——工廠方法模式,下面,咱們有請男主出場。

咱們先來看看,工廠方法模式的官方定義:

定義一個用於建立對象的接口,讓子類決定實例化哪個類。

從定義中,咱們能夠看出實現的套路:定一個建立對象的接口,而後每一個工廠去實現該接口實例化特定的對象,這樣就使一個類的實例化延遲到其子類。

每個產品都有相應的工廠,這就是與簡單工廠模式最大的區別。

而後,調用者能夠自由的 選擇使用哪一個工廠去建立對象。

六、工廠方法模式

工廠方法UML圖

工廠方法模式的UML類圖。

產品(餃子餡)與簡單工廠模式的代碼一致,這裏就不貼出來了。

package com.fanqiekt.factory.method;

/**
 * 工廠接口
 * @Author: 番茄課堂-懶人
 */
public interface IFactory {

    IStuffing getStuffing();

}
複製代碼

IFactory:工廠的接口。

定義一個用於建立對象的接口。

getStuffing()得到產品(餃子餡)的方法,交給具體的子類來實現。使一個類的實例化延遲到其子類。

package com.fanqiekt.factory.method;

/**
 * 豬肉大蔥餡工廠
 * @Author: 番茄課堂-懶人
 */
public class PorkFactory implements IFactory {
    @Override
    public IStuffing getStuffing() {
        return new PorkStuffing();
    }
}
複製代碼
package com.fanqiekt.factory.method;

/**
 * 茴香雞蛋餡工廠
 * @Author: 番茄課堂-懶人
 */
public class FoeniculumVulgareFactory implements IFactory {
    @Override
    public IStuffing getStuffing() {
        return new FoeniculumVulgareStuffing();
    }
}
複製代碼
package com.fanqiekt.factory.method;

/**
 * 韭菜雞蛋餡工廠
 * @Author: 番茄課堂-懶人
 */
public class ChineseChivesFactory implements IFactory {
    @Override
    public IStuffing getStuffing() {
        return new ChineseChivesStuffing();
    }
}
複製代碼

具體的工廠類。

爲每一個產品(餃子餡)提供一個工廠類:豬肉大蔥餡工廠、茴香雞蛋餡工廠、韭菜雞蛋餡工廠。

這樣的設計,擴展起來也很是的方便,例如增長三鮮餡,只須要增長產品類(三鮮餡)、工廠類(三鮮餡)就能夠了。不會影響其餘。

七、區別

簡單工廠模式,只有一個工廠類,根據參數的不一樣返回不一樣類的實例。

工廠方法模式,定義一個建立對象的接口,存在實現該接口的多個工廠類。調用者選擇使用哪一個工廠。

八、END

從下一節課程開始,《嘻哈說——設計模式》系列的課程將不在其餘渠道發佈,改成公衆號《番茄課堂》獨家發佈,期待你們的關注。

今天就先說到這裏,下一節說《抽象工廠模式》,感謝你們支持。

相關文章
相關標籤/搜索