阿里大神講設計模式】2.小光熱干面提供飲料了---簡單工廠

前情提要

本意是想像美劇的previously那樣, 不知道怎么翻譯好, 求翻譯達人賜教…
上集講到, 小光辭了工作, 開起了熱干面的店子, 用Builder模式改造了熱干面的構建過程, 是日漸穩定有效起來, 生意也是越來越好.

但是小光是善于觀察的同學啊, 他發現熱干面真的好干啊(好像一般人也都能發現, 鬼臉~). 心想, 解決用戶痛點才產品的存在根本啊, 是時候推出新東西了.

于是他決定跟推出自己的光氏飲料產品.

飲料的制作

經過一番調查和走訪, 小光發現幾個特點:

大家對這個飲料要求不高(碼農的屌絲特性啊) , 解渴為主.
因為趕著上班, 一般要求要快, 最好可以直接拿走.
品種要豐富, 大家口味不一啊.
于是, 小光選用了最新的XX牌 (有廣告商找我嗎? 哈哈.) 速溶飲料. 制作飲料的過程很簡單, 很快, 小光做出了第一杯飲料—-橙汁:

public class OrangeJuice {
    public void make() {
        // 1. 拿出一次性飲料杯
        System.out.println("拿出一次性飲料杯");
        // 2. 加入速溶橙汁粉
        System.out.println("加入速溶橙汁粉");
        // 3. 加水沖兌
        System.out.println("加水");
        // 4. 加蓋, 打包
        System.out.println("加蓋, 打包");
    }
}

小光的思考

看起來, 程序似乎是可以運轉了, 讓我們投入生產吧…
然而, 小光何許人啊, 畢竟是在碼農界混了好些年的同志啊. 還沒有投入使用, 就發現了”問題”:

飲料有很多種, 過程都類似, 只是放的速溶包不一樣. 如果我每個都這么寫, 改天真有人找我打廣告, 杯子上印個二維碼什么的, 我不是每個飲料的制作過程都要改啊

靈光一現, 小光想起了面向對象思想中提到的抽象, 封裝, 于是乎, 小光改寫了自己的程序:

他抽象出來一個”Drink”類:

public abstract class Drink {
    
    public void make() {
        // 1. 拿出一次性飲料杯
        System.out.println("拿出一次性飲料杯");
        // 2. 加入速溶橙汁粉
        System.out.println("加入" + getInstantPackage());
        // 3. 加水沖兌
        System.out.println("加水");
        // 4. 加蓋, 打包
        System.out.println("加蓋, 打包");
    }
    
    abstract String getInstantPackage();
}

可樂, 酸梅湯, 橙汁皆繼承了Drink:

public class Coke extends Drink {
    @Override
    String getInstantPackage() {
        return "速溶可樂粉";
    }
}
public class PlumJuice extends Drink {
    @Override
    String getInstantPackage() {
        return "速溶酸梅粉";
    }
}
public class OrangeJuice extends Drink {
    @Override
    String getInstantPackage() {
        return "速溶橙汁粉";
    }
}

開賣

制作完飲料, 準備開賣了, 是這樣的:

public class XiaoGuang {
    public static void main(String[] args) {
        OrangeJuice orangeJuice = new OrangeJuice();
        orangeJuice.make();
    }
}

第二天, 生意實在太好, 小光請了表妹臨時來幫忙泡制飲料. 而且, 小光還發現自己也無需關注用戶要什么飲料了, 直接讓用戶告訴表妹, 表妹直接制作飲料給用戶就行~

表妹負責根據用戶要求生產飲料:

public class Cousins {
    
    public static Drink create(String drinkType) {
        //  Java7開始, switch支持String
        switch (drinkType) {
            case "橙汁":
                return new OrangeJuice();
            case "酸梅湯":
                return new PlumJuice();
            case "可樂":
                return new Coke();
            default:
                return new OrangeJuice();
        }
    }
}

小光不再關注飲料具體種類:

public class XiaoGuang {
    public static void main(String[] args) {
        Drink drink = Cousins.create("可樂");
        drink.make();
    }
}

加上飲料套餐之后, 生意果然越來越好, 估計也有美女助陣的加成, 哈哈…

故事之后

可能有些同學已經看出一點熟悉感了, 我們把這些關系一個UML表示下:

image

如此, 應該就比較清晰了, 這個就是我們今天的主題—-簡單工廠.

嚴格來說, 簡單工廠并非一種設計模式, 可以說是一種編碼習慣.
那么我們為什么要使用簡單工廠, 或者說這么做有什么好處呢?

從我們這個例子中, 可以看到, 小光(Client類)不需要去關注飲料泡制(Drink make)這個過程了, 有更多的時間去接待客戶, 只需從表妹(工廠類)那拿到相應的飲料給客戶即可.

這個其實是蘊含了單一職責的編程思想:

小光的職責是接待客戶
表妹的職責是泡制飲料
簡單工廠一般來說, 使用一個靜態方法來生產產品, 故而有時也稱之為靜態工廠方法模式.

擴展閱讀

在這個故事的過程中, 我們提到了面向對象的抽象, 封裝特性. 實際上我們所有的OOD原則, 設計模式, 都是基于面向對象的思想的, 離不開抽象, 封裝, 繼承, 多態幾大特性. 隨著對這些設計模式的分析, 也可以讓我們加深面向對象的編程思想.

以Glide為例, 其中的DefaultConnectivityMonitorFactory.java就是一個類似的簡單工廠實現:

public class DefaultConnectivityMonitorFactory implements   ConnectivityMonitorFactory {
    
  @NonNull
  public ConnectivityMonitor build(
      @NonNull 
      Context context,
      @NonNull 
      ConnectivityMonitor.ConnectivityListener listener) {
        final int res = context.checkCallingOrSelfPermission("android.permission.ACCESS_NETWORK_STATE");
        final boolean hasPermission = res == PackageManager.PERMISSION_GRANTED;
        if (hasPermission) {
            return new DefaultConnectivityMonitor(context, listener);
        } else {
            return new NullConnectivityMonitor();
        }
  }
}

與表妹Cousins(工廠)的實現很類似, 只是這個Factory具體創建什么產品不是由傳入的參數決定的, 是在內部的邏輯決定的.
轉化為類圖關系, 更加清晰:

image

一直在說的話: 所謂架構, 設計模式都是一種思想, 沒有固定的招式, 所有的這些招式都是讓我們入門, 了解面向對象的基礎思想, 然后能運用無形. 共勉.

留個尾子

大家可能有發現, 簡單工廠的弊端也是很多的, 表妹(工廠)的責任太重, 包含(UML依賴關系)了所有的具體產品的實現. 另外, 如果需要修改或增加產品, 我們就得改變工廠類的實現. 這顯然違反了開閉原則.

故而, 簡單工廠, 一般來說, 適用于產品類別較少, 且固定的場景.

轉載鏈接

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容