工厂模式--大侠,您要预定金疮药还是黑玉断续膏?

师父让我来炼丹

话说,很久以前,武林中各大门派林立,百家争鸣,忽然《九阴真经》再现江湖,各大门派各自暗中派出高手争抢,都想独吞《九阴真经》,习得神功,一统江湖。

闯荡江湖,当然必备各种良药防身,小帅师父在华山脚下的仙草药房,生意忽然好了很多,各种丹药销量大增。
在这里插入图片描述

师父苦心研制的丹药受到的武林人士的肯定,很是开心,其中的行军丹,金创药,黑玉断续膏,号称镇店三宝。

订单如雪花般飞来,师父命小帅在后院加班加点生产,但是由于各种特效药制作工艺复杂,小帅和几个伙计忙的团团转。

客官要问炼丹的场所在何处?

说出来有点不好意思,就在药房的后院。

药品的生产代码如下:

不用设计模式

药品抽象类

abstract public class Drug {

    /**
     * 药品名称
     */
    String name;

    /**
     * 功效
     */
    String efficacy;

    public void packing() {
        System.out.println("打包药品:" + name);
    }

    @Override
    public String toString() {
        // 药丸的功效
        StringBuffer display = new StringBuffer();
        display.append("---- " + name + " 使用说明 ----\n");
        display.append("具有功效:" + efficacy + "\n");
        return display.toString();
    }
}

具体药品:行军丹

public class XingJunDanDrug extends Drug{

    public XingJunDanDrug() {
        name = "行军丹";
        System.out.println("开始制作:祖传秘法秘制七天");
        System.out.println("制作完成-->行军丹");
        efficacy = "江湖中常见的疗伤药丸,尺寸小,便于携带,服用后见效快,恢复生命100点。";
    }

}

具体药品:金疮药

public class JinChuangYaoDrug extends Drug{

    public JinChuangYaoDrug() {
        name = "金疮药";
        System.out.println("开始制作:祖传秘法秘制七七四十九天");
        System.out.println("制作完成-->金疮药");
        efficacy = "闻名天下的佛门疗伤奇药,闯荡江湖必备,加速愈合,服用后立即恢复生命500点。";
    }
}

具体药品:黑玉断续膏

public class HeiYuDuanXuGaoDrug extends Drug{

    public HeiYuDuanXuGaoDrug() {
        name = "黑玉断续膏";
        System.out.println("开始制作:祖传秘法秘制九九八十一天");
        System.out.println("制作完成-->黑玉断续膏");
        efficacy = "传说中的稀世秘药,有再造之力,神奇无比,其价堪比黄金,服用后立即恢复生命2500点。";
    }
}

仙草药房

public class Drugstore {

    /**
     * 药房接到订单生产药品
     * @param type
     * @return
     */
    public Drug orderDrug(String type) {

        Drug drug = null;

        System.out.println("接到订单:" + type);

        // 生产药品
        if("行军丹".equals(type)) {
            drug = new XingJunDanDrug();
        } else if("金疮药".equals(type)) {
            drug = new JinChuangYaoDrug();
        } else if("黑玉断续膏".equals(type)) {
            drug = new HeiYuDuanXuGaoDrug();
        }
		// 打包药品
        drug.packing();

        return drug;

    }

}

测试类

public class DrugstoreTest {

    public static void main(String[] args) {

        Drugstore drugstore = new Drugstore();
        System.out.println("为保证品质,本店所有药品只接受预定:");
        System.out.println();

        // 药房接到行军丹订单
        Drug drug = drugstore.orderDrug("行军丹");
        System.out.println(drug);

        // 药房接到金疮药订单
        drug = drugstore.orderDrug("金疮药");
        System.out.println(drug);

        // 药房接到黑玉断续膏订单
        drug = drugstore.orderDrug("黑玉断续膏");
        System.out.println(drug);

    }
}

测试结果

为保证品质,本店所有药品只接受预定:

接到订单:行军丹
开始制作:祖传秘法秘制七天
制作完成-->行军丹
打包药品:行军丹
---- 行军丹 使用说明 ----
具有功效:江湖中常见的疗伤药丸,尺寸小,便于携带,服用后见效快,恢复生命100点。

接到订单:金疮药
开始制作:祖传秘法秘制七七四十九天
制作完成-->金疮药
打包药品:金疮药
---- 金疮药 使用说明 ----
具有功效:闻名天下的佛门疗伤奇药,闯荡江湖必备,加速愈合,服用后立即恢复生命500点。

接到订单:黑玉断续膏
开始制作:祖传秘法秘制九九八十一天
制作完成-->黑玉断续膏
打包药品:黑玉断续膏
---- 黑玉断续膏 使用说明 ----
具有功效:传说中的稀世秘药,有再造之力,神奇无比,其价堪比黄金,服用后立即恢复生命2500点。

有什么问题?

所有的原材料和设备都堆在后院,杂乱不堪,而且每种药的生产工序和流程都不一样,每一种药品的生产设备都不一样。

小帅和几个伙计,终日奔波在不同的药品生产设备之间,还要理清楚各种各样的草药,一不小心就弄乱了。

仙草店的生意越来越好,小帅和伙计很本忙不过来,药品的产量却越来越低了。

“有问题啊,药房类直接依赖具体的药品类,药品类直接在药房类中创建,药房类和具体的药品类高耦合,这违反了依赖倒置原则:要依赖抽象,不要依赖具体类

在这里插入图片描述

还有,药房既负责销售又负责生产,增加了复杂性,功能不够单一啊,这违反了单一职责原则”,有一天,师父忽然有感而发。

小帅在旁边听得一脸懵逼,感觉和师父不是同一个时代的人。

过了几日,黑玉断续膏的原料断货,停止生产,师父又开发了一款新药,灵葫仙丹,恢复内力很有疗效,深受各路武林人士喜爱,马上加入生产。
在这里插入图片描述
“还是有问题啊,每停止生产或者新生产一款药品,都要修改药店的设备和原料,对店铺影响很大啊“,有一天师父在院子里打坐,若有所思的说,接着忽然冒出一句奇怪的话来:“这违反了开闭原则,应该对扩展开发,对修改封闭”,听得小帅一头雾水。

这一不小心就违反了三大设计原则:依赖倒置原则,单一职责原则,开闭原则。。。

这该如何是好?

小帅每日苦苦思索,始终不得要领,脸上多了几分与年龄不相符的忧愁,再想下去,头发都要掉了,只好向师父请教。

师父微微一笑,心中早有对策。

没过几日,师父忽然决定在店铺附近的山脚下建一个工厂,把原材料和设备都搬过去,专门生产药品,店里只负责销售,让销售和生产分离开来。

“师父你要建一个工厂?”

“嗯,一个简单的工厂。”

师父专门拨了一大笔银两,找了村里最能干的几位壮士,几个月后一个崭新的工厂就建好了,小帅和伙计们都高高兴兴地搬了进去。

简单工厂

简单工厂的类图如下:
图片来源:https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/simple_factory.html
(图片来源:https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/simple_factory.html)

简单工厂类

public class SimpleDrugFactory {

    /**
     * 生产药品
     * @param type
     * @return
     */
    public static Drug createDrug(String type) {

        Drug drug = null;

        // 生产药品
        if ("行军丹".equals(type)) {
            drug = new XingJunDanDrug();
        } else if ("金疮药".equals(type)) {
            drug = new JinChuangYaoDrug();
        } else if ("黑玉断续膏".equals(type)) {
            drug = new HeiYuDuanXuGaoDrug();
        } else if ("灵葫仙丹".equals(type)) {
            drug = new LinHuXianDanDrug();
        }

        return drug;
    }
}

新的仙草药房

public class Drugstore {

    /**
     * 药房接到订单生产药品
     * @param type
     * @return
     */
    public Drug orderDrug(String type) {

        Drug drug = null;

        System.out.println("接到订单:" + type);

        // 通过工厂生产药品
        drug = SimpleDrugFactory.createDrug(type);

        // 打包药品
        drug.packing();

        return drug;
    }
}

简单工厂解决了什么问题?

药品的生产从药房搬到了工厂里,新增了一个简单工厂类,修改了药店里生产药品的代码,除此之外,其他代码都没有变。

有了新的工厂,仙草药店现在只负责销售了,工厂专门负责生产药品,这样各自负责自己的职责,效率大大提高了。这就符合了单一职责原则

在这里插入图片描述

简单工厂使药房类和具体的药品类解耦,依赖了药品抽象类,符合了依赖倒置原则

什么是依赖倒置原则?

依赖倒置原则:要依赖抽象,不要依赖具体类。

也就是说,不能让高层组件依赖低层组件,不管高层还是低层组件都应该依赖于抽象。

听不懂,太抽象对不对?

小帅也听不懂啊,师父耐心的给他讲解,还画了一幅图。。。

这里的药房就是高层组件,具体的丹药就是低层组件,刚开始在药房里直接生产药品,药房(高层组件)依赖具体丹药(低层组件)。

药房(高层组件)和具体丹药(低层组件)之间高耦合,这就是传统的依赖关系

为什么叫传统的依赖关系呢?可能是因为人们天然的认为高层的组件都应该依赖底层的组件,这样更符合人们的常识。

依赖倒置?有点反常识啊,但是在软件设计中,这样更有好处哦。

后面我们采用了简单工厂模式,药房(高层组件)依赖于药品类(抽象),具体丹药(低层组件)也依赖于(实现)药品类(抽象),这就倒置了依赖

药房(高层组件)和具体丹药(低层组件)之间实现了解耦,这样就符合依赖倒置原则了!

在这里插入图片描述

原来如此,小帅恍然大悟。。。

还有什么问题?

虽然把所有的生产设备都搬到简单工厂里了,但是随着师父开发的新品越来越多,工厂也变得越来越大,越来越复杂。

简单工厂模式有一组 if 分支判断逻辑,每上一种新产品都要修改工厂的生产线,需要修改工厂类的代码,还是违反了开闭原则,没有对扩展开发,对修改封闭啊

是不是应该用多态或其他设计模式来替代呢?实际上,如果 if 分支并不是很多,代码中有 if 分支也是完全可以接受的。

不过,小帅看得更长远,他觉得以后生产的丹药会越来越多,一个工厂根本放不下那么多生产设备。

他向师父提议:”要不,我们把大工厂拆分成一个个小工厂,每个工厂只生产一种药品,这样管理起来就简单多了。“

师父年纪虽然大了,但是心态还是很年轻的,具有持续发展的战略眼光,马上采纳了小帅的建议,建了很多小工厂,每个工厂只负责生产一种丹药。

工厂模式

工厂方法模式(Factory Method Pattern)又称为工厂模式,定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

工厂模式类图如下:
在这里插入图片描述
(图片来源:https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/factory_method.html)

工厂接口

public interface IDrugFactory {
    /**
     * 生产药品
     * @return
     */
    Drug createDrug();
}

行军丹工厂

public class XingJunDanDrugFactory implements IDrugFactory{
    public Drug createDrug() {
        return new XingJunDanDrug();
    }
}

金疮药工厂

public class JinChuangYaoDrugFactory implements IDrugFactory {
    public Drug createDrug() {
        return new JinChuangYaoDrug();
    }
}

黑玉断续膏工厂

public class HeiYuDuanXuGaoDrugFactory implements IDrugFactory{
    public Drug createDrug() {
        return new HeiYuDuanXuGaoDrug();
    }
}

新的仙草药房

public class Drugstore {

    /**
     * 药房接到订单生产药品
     * @param type
     * @return
     */
    public Drug orderDrug(String type) {

        IDrugFactory drugFactory = null;
        Drug drug = null;

        System.out.println("接到订单:" + type);

        // 获取对应的工厂
        if ("行军丹".equals(type)) {
            drugFactory = new XingJunDanDrugFactory();
        } else if ("金疮药".equals(type)) {
            drugFactory = new JinChuangYaoDrugFactory();
        } else if ("黑玉断续膏".equals(type)) {
            drugFactory = new HeiYuDuanXuGaoDrugFactory();
        } else if ("灵葫仙丹".equals(type)) {
            drugFactory = new LinHuXianDanDrugFactory();
        }

        // 生产对应的药品
        drug = drugFactory.createDrug();

        // 打包药品
        drug.packing();

        return drug;

    }

}

其他代码都没有变化,新的仙草药房只要根据不同的药品去不同的工厂拿货就行了。

这样以后新增一种丹药,只要新增一个实现IDrugFactory 的工厂类就行了,不用修改工厂代码,工厂方法模式比起简单工厂模式更加符合开闭原则

不过,应用多态或设计模式来替代 if 分支判断逻辑,也并不是没有任何缺点的,它虽然提高了代码的扩展性,更加符合开闭原则,但也增加了类的个数,牺牲了代码的可读性。

现在工厂类里的if判断逻辑消除了,但是,if逻辑判断,从简单工厂类里又移回药房了。

在这里插入图片描述
if逻辑判断转了一圈,又回到了药房类中,新增一个新工厂需要改动药房类的代码,这样药房类就不符合开闭原则了啊。

真是忧伤呢,改如何解决呢?

如何去掉if逻辑判断

“可以再建一个生产工厂的工厂,然后用Map消除if逻辑判断”,小帅灵光一现。

生产工厂的工厂

public class DrugFactoryMap {

    private static final Map<String, IDrugFactory> cachedFactories = new HashMap<String, IDrugFactory>();

    static {
        cachedFactories.put("行军丹", new XingJunDanDrugFactory());
        cachedFactories.put("金疮药", new JinChuangYaoDrugFactory());
        cachedFactories.put("黑玉断续膏", new HeiYuDuanXuGaoDrugFactory());
        cachedFactories.put("灵葫仙丹", new LinHuXianDanDrugFactory());
    }

    public static IDrugFactory getFactory(String type) {
        if(type == null || type.isEmpty()) {
            return null;
        }
        return cachedFactories.get(type);
    }
}

药房类直接从DrugFactoryMap类中取对应的工厂就行了,成功的把if逻辑判断转移到了DrugFactoryMap类的Map中了。
在这里插入图片描述
DrugFactoryMap类其实就上面的简单工厂的另一种实现方式。

上面的方式就是简单工厂+工厂模式啊。

我去,要建好多工厂啊。。。

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

抽象工厂类图如下:
在这里插入图片描述
(图片来源:https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/abstract_factory.html)

师父真是个很有上进心的人啊,平时这么忙了,还废寝忘食地开发新产品,你看,这几个月师父又发明了新配方,在原来的行军丹,金疮药,黑玉断续膏中加入了秘制草药和矿物质,使行军丹,金疮药,黑玉断续膏不仅能恢复生命值而且还能同时恢复内力

这种神奇的超级药丸,极其珍贵,只限量供应vip客户。

仙草药房在武林中的名号越来越响了。

但是,新品研发出来了,有一个问题,就是每种新的丹药都要建一个对应的工厂啊,随着药品越来越多,工厂也越来越多,建工厂可是个烧钱的东西,慢慢得师父也觉得有点不妥。

小帅天天在各个工厂之间奔波,对工厂的运转非常了解,他发现有些药品的制造工艺有些相似之处。

例如:普通的行军丹,金疮药和黑玉断续膏,都用到了天山雪莲和忘忧水,需要在八卦炉中提炼。

超级的行军丹,金疮药和黑玉断续膏,都采用了华山脚下的神秘矿物质,需要吸收日月精华,加上秘制草药作为药引,才具有恢复内力的功效。

”不如,我们把普通的行军丹,金疮药和黑玉断续膏都集中在一个工厂里生产,称为H系列,把同时具有恢复内力功效的行军丹,金疮药和黑玉断续膏放到另一个工厂里生产,叫做S系列,如何?“

”如此甚好!“,师父大喜,立马下令改造组合工厂,一个生产H系列产品,另一个生产S系列产品。

完整的代码如下:

药品抽象类

abstract public class Drug {

    /**
     * 药品名称
     */
    String name;

    /**
     * 功效
     */
    String efficacy;


    public void packing() {
        System.out.println("打包药品:" + name);
    }

    @Override
    public String toString() {
        // 药丸的功效
        StringBuffer display = new StringBuffer();
        display.append("---- " + name + " 使用说明 ----\n");
        display.append("具有功效:" + efficacy + "\n");
        return display.toString();
    }
}

普通行军丹

public class XingJunDanDrug extends Drug {

    public XingJunDanDrug() {
        name = "行军丹";
        System.out.println("开始制作:祖传秘法秘制七天");
        System.out.println("制作完成-->行军丹");
        efficacy = "江湖中常见的疗伤药丸,尺寸小,便于携带,服用后见效快,恢复生命100点。";
    }
}

普通金疮药

public class JinChuangYaoDrug extends Drug {

    public JinChuangYaoDrug() {
        name = "金疮药";
        System.out.println("开始制作:祖传秘法秘制七七四十九天");
        System.out.println("制作完成-->金疮药");
        efficacy = "闻名天下的佛门疗伤奇药,闯荡江湖必备,加速愈合,服用后立即恢复生命500点。";
    }
}

普通黑玉断续膏

public class HeiYuDuanXuGaoDrug extends Drug {

    public HeiYuDuanXuGaoDrug() {
        name = "黑玉断续膏";
        System.out.println("开始制作:祖传秘法秘制九九八十一天");
        System.out.println("制作完成-->黑玉断续膏");
        efficacy = "传说中的稀世秘药,有再造之力,神奇无比,其价堪比黄金,服用后立即恢复生命2500点。";
    }
}

超级行军丹

public class SuperXingJunDanDrug extends Drug {

    public SuperXingJunDanDrug() {
        name = "超级行军丹";
        System.out.println("开始制作:祖传秘法秘制七天");
        System.out.println("制作完成-->超级行军丹");
        efficacy = "江湖中常见的疗伤药丸,尺寸小,便于携带,服用后见效快,恢复生命100点,具备超级功效-->同时恢复50点内力。";
    }
}

超级金疮药

public class SuperJinChuangYaoDrug extends Drug {

    public SuperJinChuangYaoDrug() {
        name = "超级金疮药";
        System.out.println("开始制作:祖传秘法秘制七七四十九天");
        System.out.println("制作完成-->超级金疮药");
        efficacy = "闻名天下的佛门疗伤奇药,闯荡江湖必备,加速愈合,服用后立即恢复生命500点,具备超级功效-->同时恢复250点内力。";
    }
}

超级黑玉断续膏

public class SuperHeiYuDuanXuGaoDrug extends Drug {

    public SuperHeiYuDuanXuGaoDrug() {
        name = "超级黑玉断续膏";
        System.out.println("开始制作:祖传秘法秘制九九八十一天");
        System.out.println("制作完成-->超级黑玉断续膏");
        efficacy = "传说中的稀世秘药,有再造之力,神奇无比,其价堪比黄金,服用后立即恢复生命2500点,具备超级功效-->同时恢复1000点内力。";
    }
}

抽象工厂

public interface IDrugFactory {

    /**
     * 生产药品
     * @return
     */
    Drug createDrug(String type);
}

生产普通丹药的工厂

public class NormalDrugFactory implements IDrugFactory {

    /**
     * 生产普通药品
     * @param type
     * @return
     */
    @Override
    public Drug createDrug(String type) {

        Drug drug = null;

        // 生产药品
        if ("行军丹".equals(type)) {
            drug = new XingJunDanDrug();
        } else if ("金疮药".equals(type)) {
            drug = new JinChuangYaoDrug();
        } else if ("黑玉断续膏".equals(type)) {
            drug = new HeiYuDuanXuGaoDrug();
        }

        return drug;
    }
}

生产超级丹药的工厂

public class SuperDrugFactory implements IDrugFactory{

    /**
     * 生产超级药品
     * @param type
     * @return
     */
    @Override
    public Drug createDrug(String type) {

        Drug drug = null;

        // 生产超级药品
        if ("行军丹".equals(type)) {
            drug = new SuperXingJunDanDrug();
        } else if ("金疮药".equals(type)) {
            drug = new SuperJinChuangYaoDrug();
        } else if ("黑玉断续膏".equals(type)) {
            drug = new SuperHeiYuDuanXuGaoDrug();
        }

        return drug;
    }
}

药房类

public class Drugstore {

    /**
     * 药房接到订单生产药品
     * @param type
     * @return
     */
    public Drug orderDrug(String type, boolean isVip) {

        IDrugFactory drugFactory = null;

        if(isVip) {
            drugFactory = new SuperDrugFactory();
            System.out.println("接到VIP订单:" + type + " 切换超级工厂");
        } else {
            drugFactory = new NormalDrugFactory();
            System.out.println("接到普通订单:" + type + " 切换普通工厂");
        }

        // 通过工厂生产药品
        Drug drug = drugFactory.createDrug(type);

        // 打包药品
        drug.packing();

        return drug;

    }

}

测试类

public class DrugstoreTest {

    public static void main(String[] args) {

        // 是否vip客户
        boolean isVip = false;
        Drugstore drugstore = new Drugstore();
        System.out.println("为保证品质,本店所有药品只接受预定:");
        System.out.println();

        // 药房接到行军丹订单
        Drug drug = drugstore.orderDrug("行军丹", isVip);
        System.out.println(drug);

        // 药房接到金疮药订单
        drug = drugstore.orderDrug("金疮药", isVip);
        System.out.println(drug);

        // 药房接到黑玉断续膏订单
        drug = drugstore.orderDrug("黑玉断续膏", isVip);
        System.out.println(drug);

    }
}

测试结果
isVip = false 普通工厂

为保证品质,本店所有药品只接受预定:

接到普通订单:行军丹 切换普通工厂
开始制作:祖传秘法秘制七天
制作完成-->行军丹
打包药品:行军丹
---- 行军丹 使用说明 ----
具有功效:江湖中常见的疗伤药丸,尺寸小,便于携带,服用后见效快,恢复生命100点。

接到普通订单:金疮药 切换普通工厂
开始制作:祖传秘法秘制七七四十九天
制作完成-->金疮药
打包药品:金疮药
---- 金疮药 使用说明 ----
具有功效:闻名天下的佛门疗伤奇药,闯荡江湖必备,加速愈合,服用后立即恢复生命500点。

接到普通订单:黑玉断续膏 切换普通工厂
开始制作:祖传秘法秘制九九八十一天
制作完成-->黑玉断续膏
打包药品:黑玉断续膏
---- 黑玉断续膏 使用说明 ----
具有功效:传说中的稀世秘药,有再造之力,神奇无比,其价堪比黄金,服用后立即恢复生命2500点。

isVip = true 切换超级工厂

为保证品质,本店所有药品只接受预定:

接到VIP订单:行军丹 切换超级工厂
开始制作:祖传秘法秘制七天
制作完成-->超级行军丹
打包药品:超级行军丹
---- 超级行军丹 使用说明 ----
具有功效:江湖中常见的疗伤药丸,尺寸小,便于携带,服用后见效快,恢复生命100点,具备超级功效-->同时恢复50点内力。

接到VIP订单:金疮药 切换超级工厂
开始制作:祖传秘法秘制七七四十九天
制作完成-->超级金疮药
打包药品:超级金疮药
---- 超级金疮药 使用说明 ----
具有功效:闻名天下的佛门疗伤奇药,闯荡江湖必备,加速愈合,服用后立即恢复生命500点,具备超级功效-->同时恢复250点内力。

接到VIP订单:黑玉断续膏 切换超级工厂
开始制作:祖传秘法秘制九九八十一天
制作完成-->超级黑玉断续膏
打包药品:超级黑玉断续膏
---- 超级黑玉断续膏 使用说明 ----
具有功效:传说中的稀世秘药,有再造之力,神奇无比,其价堪比黄金,服用后立即恢复生命2500点,具备超级功效-->同时恢复1000点内力。

抽象工厂模式可以快速的切换不同的系列,实现了系列和系列之间的隔离。

如果药房接到了普通订单,就去普通工厂下单生产,如果接到了vip订单就去超级工厂下单生产,这样就能快速切换生产不同的系列产品了。

总结

简单工厂模式:如果对象的创建逻辑都比较简单的时候,直接用new 来创建对象就可以了,推荐使用简单工厂模式,将多个对象的创建逻辑放到一个工厂类中。虽然也会有if逻辑判断,如果不是太复杂,也是可以接受的,也可以通过map来消除if判断。

工厂方法模式:如果每个对象的创建逻辑都比较复杂的时候,为了避免设计一个过于庞大的简单工厂类,推荐使用工厂方法模式,将创建逻辑拆分得更细,每个对象的创建逻辑独立到各自的工厂类中。同时,创建代码抽离到独立的工厂类之后可以方便复用。

抽象工厂模式:如果需要随时切换不同的系列产品,推荐使用抽象工厂模式,实现不同系列之间的隔离,快速切换工厂。

华山论剑

全真教掌门王重阳「中神通」为免江湖仇杀不断,提出「华山论剑」,胜者为「天下第一高手」,并可拥有《九阴真经》。

大战在即,天下豪杰这几日都赶往华山,华山脚下好不热闹,大家都想见证天下第一高手的诞生。

近日,仙草药房忽然来了几波神秘人物,看似都很有来头,师父不敢怠慢,依次请入内屋详谈。

小帅发现好几位神秘客人的订单中都有号称“黑黄金”的超级黑玉断续膏,这可稀奇了,超级黑玉断续膏贵比黄金,产量极其稀少,不是一般的客人有资格和能力预定的,师父只供应极少数的vip客户。

小帅偷偷看了一下客户名单,光看名字就惊出一身冷汗,他们分别是:(东邪)黄药师,(西毒)欧阳锋,(南帝)段智兴,(北丐)洪七公。

git代码链接







在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章