【阿里大神讲设计模式】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表示下:
~

如此, 应该就比较清晰了, 这个就是我们今天的主题—-简单工厂.
严格来说, 简单工厂并非一种设计模式, 可以说是一种编码习惯.
那么我们为什么要使用简单工厂, 或者说这么做有什么好处呢?
从我们这个例子中, 可以看到, 小光(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具体创建什么产品不是由传入的参数决定的, 是在内部的逻辑决定的.
转化为类图关系, 更加清晰:


一直在说的话: 所谓架构, 设计模式都是一种思想, 没有固定的招式, 所有的这些招式都是让我们入门, 了解面向对象的基础思想, 然后能运用无形. 共勉.

留个尾子


大家可能有发现, 简单工厂的弊端也是很多的, 表妹(工厂)的责任太重, 包含(UML依赖关系)了所有的具体产品的实现. 另外, 如果需要修改或增加产品, 我们就得改变工厂类的实现. 这显然违反了开闭原则.
故而, 简单工厂, 一般来说, 适用于产品类别较少, 且固定的场景.


原文地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容