你了解的工厂模式可能有误

5月一个酷热的中午,我跟刚来不久的小兄弟,小当闲聊起了公司用的的设计模式。

我侃侃而谈道:“咱们公司,使用的设计模式不多,也就是 策略,门面,简单工厂,工厂,单例,命令,组合,模板等。”

小当:“什么是简单工厂啊?,跟工厂模式有区别吗?”

我一听,便双手交叉于胸前,略有深意的说:“你了解的工厂模式是什么?”

小当非常流利的说:“将创建的对象方法,抽取到一个类中,根据类型不同创建相应的对象。”

我叹了口气:“小当,你了解的工厂模式有误哦,这个是简单工厂”

小当充满疑惑的说:“那什么是工厂模式,什么又是简单工厂呢?”

我喝了一口水,娓娓道来:“

简单工厂不是设计模式,而是一种编程习惯。

将创建对象的方法,抽取到一个公共类中,根据类型不同创建相应的对象。

不属于23种GOF设计模式之一。

就拿获取算奖器的例子来说吧,PL3,DLT等都有自己的算奖器。简单工厂实现方式如下:

package factory;
public class SimpleCalculatorFactoryDemo {
    public static abstract class Calculator{
        private String type;
        public Calculator(String type) {
            this.type = type;
        }
        public void calculate(){
            System.out.println(" This "+type+" calculate is done");
        }
    }
    public static class PL3Calculator extends Calculator{
        public PL3Calculator() {
            super("PL3");
        }
    }
    public static class DLTCalculator extends Calculator{
        public DLTCalculator() {
            super("DLT");
        }
    }

    public static class SimpleCalculatorFactory{
        public  Calculator createCalculator(String type){
            if ("PL3".equals(type)) { return new PL3Calculator(); }
            else if ("DLT".equals(type)){ return new DLTCalculator(); }
            return null;
        }
    }

    public static class PrizeTicketHandler{
        SimpleCalculatorFactory factory;
        public PrizeTicketHandler(SimpleCalculatorFactory factory){
            this.factory=factory;
        }
        public Calculator getCalculator(String type){
            return factory.createCalculator(type);
        }
    }
    public static void main(String[] args) {
        SimpleCalculatorFactoryDemo. SimpleCalculatorFactory factory=new SimpleCalculatorFactory();
        PrizeTicketHandler prizeTicketHandler=new PrizeTicketHandler(factory);
        prizeTicketHandler.getCalculator("DLT").calculate();
    }
}

其类图如下:

我正准备往下说简单工厂的缺点的时候,小当嚼着苹果不耐烦的说:"这个你不用细说的,我早就烂熟于心了。"

抿了抿嘴,一笑说道:“那这种方式存在什么问题?”

小当停止嚼苹果,思考了10几秒说:“每新增一个类,工厂中的if判断语句也相应增加,对系统的维护和扩展非常不利。”

我点头表示认可的说道:

“确实,随着具体的产品类增加,简单工厂的逻辑需要修改,逐渐变得不易扩展和维护,并没有做的对修改关闭,对扩展开发。”

小当吃了一大口苹果后,若有所思的说道:“咱们系统中可不是这样写的,获取算奖器是分数字彩和竞彩的。”

我喝了口水后,尝试引导小当,问道:“你还记得咱们系统是如何实现的吗?”

小当扔掉苹果核,擦擦手说道:“ 当然,其实现大致如下 ”

package factory;
public class FactoryCalculatorDemo {
    public static abstract class Calculator{
        private String type;
        public Calculator(String type) {
            this.type = type;
        }
        public void calculate(){
            System.out.println(" This "+type+" calculate is done");
        }
    }
    public static class PL3Calculator extends Calculator {
        public PL3Calculator() {
            super("PL3");
        }
    }
    public static class DLTCalculator extends Calculator {
        public DLTCalculator() { super("DLT"); }
    }
    public static class BSKCalculator extends Calculator {
        public BSKCalculator() {
            super("BSK");
        }
    }
    public static class FTCalculator extends Calculator {
        public FTCalculator() {
            super("FT");
        }
    }

    public static abstract class CalculatorFactory{
        public abstract Calculator createCalculator(String type);
    }

    public static class NumberLotteryCalculatorFactory extends CalculatorFactory {
        @Override
            public Calculator createCalculator(String type){
                if ("PL3".equals(type))
                { return new PL3Calculator(); }
                else if ("DLT".equals(type))
                { return new DLTCalculator(); }
                return null;
            }
    }

    public static class JCCalculatorFactory extends CalculatorFactory {
        @Override
        public Calculator createCalculator(String type){
            if ("BSK".equals(type))
            { return new BSKCalculator(); }
            else if ("FT".equals(type))
            { return new FTCalculator(); }
            return null;
        }
    }

    public static void main(String[] args) {
        //调用者,知悉使用的子类
        CalculatorFactory calculatorFactory=new NumberLotteryCalculatorFactory();
        calculatorFactory.createCalculator("PL3").calculate();
        calculatorFactory=new JCCalculatorFactory();
        calculatorFactory.createCalculator("FT").calculate();
    }
}

其类图如下:

我看后很欣慰他掌握的挺好,我可以放心的走了。随后不等小当说话,强行总结说道:

这个就是工厂模式了,定义了一个创建对象的接口,但由子类觉得要实例化的类是哪一个,即由NumberLotteryCalculatorFactory 和JCCalculatorFactory 决定实例化的类

小当抢着说:“NumberLotteryCalculatorFactory 和JCCalculatorFactory也实现了平行层级关系,若果有新加入的类,加入一个对应的工厂子类就好,不需要修改原来的代码”。

“是的” 我点头说道。

小当摸了摸下巴,又问道:“工厂模式了解了,那为什么系统中还会使用简单工厂呢?”

我一笑说道:“咱们校验器部分就是使用的简单工厂,校验器只有3个:注数,格式,金额,基本上不会变。所以使用简单工厂就好,记住实现功能越简单越好,Keep it Simple is best

总结:

工厂模式:定义了一个创建对象的接口,但由子类觉得要实例化的类是哪一个。

至于选择具体选择简单工厂还是工厂模式,完全看业务需要,实现功能越简单越好。

Keep it Simple is best。 ----温安适 20180525

写在最后:

预计29号,就要离开这家公司了,这篇文章最后也道个别。这家公司给的工资不高,但是积累了很多经验,无论是技术,还是管理,又提升了逆商,非常感谢,再见彩福达。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏测试开发架构之路

C语言程序设计50例(二)(经典收藏)

【程序11】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月    后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总...

496100
来自专栏大闲人柴毛毛

三分钟理解“简单工厂模式”——设计模式轻松掌握

实际问题: 由于超市隔三差五就要办促销活动,但每次促销活动的方式不一样,所以需要开发一个软件,营业员只要输入原价再选择活动类型后,就能计算出折扣以后的价钱。 普...

394120
来自专栏猿人谷

C++命名规则

如果想要有效的管理一个稍微复杂一点的体系,针对其中事物的一套统一、带层次结构、清晰明了的命名准则就是必不可少而且非常好用的工具。 活跃在生物学、化学、军队、监狱...

23760
来自专栏非著名程序员

七夕节,程序员特有的表白方式!

以上这首告白书,来自于网络,我只是找到了这首程序员的告白诗,最早的时间出现在 2009 年 1 月 5 日,不知道作者是谁。(侵删)

32310
来自专栏发现才可以探索

一句话木马

“一句话木马”短小精悍,而且功能强大,隐蔽性非常好,在入侵中始终扮演着强大的作用,居家生活搞站越货必备神器。

26400
来自专栏take time, save time

你所能用到的数据结构(六)

八、数据结构不一定很枯燥   正如我现在实习的公司的一个同事说的那样,数据结构是一本催眠的书,我想对于大多数人应该是这样的,当然对我也是,看着一大堆的算法,结...

34750
来自专栏web前端教室

[先行者课程] -- 用js实现倒计时功能的业务逻辑

今天是2017年3月19号,周日,我们一起来学习“倒计时”这个前端“需求”。 一,看一下上周的作业,视差滚动的作业; 二,开始分享学习倒计时应用。 因为时间的关...

31950
来自专栏一个会写诗的程序员的博客

Kotlin 语言极简介绍《Kotlin极简教程》正式上架:

当然,事物都是具备两面性的。Kotlin也有缺点。 虽然,官方说100%与 Java 互操作,但是在 Java 调用 Kotlin 的时候还是存在一些不方便的...

9130
来自专栏ACM小冰成长之路

HDU-6010-Daylight Saving Time

ACM模版 描述 ? 题解 这个题的难点在于题目不好懂,只要读懂了题目,细心一些的人都能做出来。 大致的思路是先预处理出来每年的两个时间节点,也就是每年三月份的...

25090
来自专栏Java帮帮-微信公众号-技术文章全总结

Java基础-day05-超市收银系统案例题

Java基础-day05-超市收银系统案例题 案例描述 将超市购物小票案例中,键盘录入部分封装为方法。 将switch语句完成的三个分支代码逻辑封装为3个方法 ...

65340

扫码关注云+社区

领取腾讯云代金券