包你懂设计模式之:工厂方法模式

在之前的博客中我介绍了简单工厂这个设计模式,今天我们需要里面的内容作为基础来讲解工厂方法模式,没有看到这边文章的小伙伴请戳:简单工厂模式

通过上面的准备知识,我们了解了简单工厂是如何实现的,我们现在来分析一下。我们在客户端想要得到一个操作的实例时,需要调用 CalculateFactory 类中的 GetCalculate() 方法,并且传递一个参数告诉工厂类我们需要实例化哪个具体操作,这样工厂类就会帮我们创建出来。这样做的好处在于客户端不在关注实例创建的具体细节,就能拿到对应实例。工厂类代码:

public static class CalculateFactory
    {
        public static Calculate GetCalculate(string op)
        {
            Calculate calculate = null ;
            switch (op) {
                case "+":
                    calculate = new Add();
                    break;
                case "-":
                    calculate = new Sub();
                    break;
                case "*":
                    calculate = new Mul();
                    break;
                case "/":
                    calculate = new Div();
                    break;
                default:
                    calculate = new Add();
                    break;
            }
            return calculate;
        }
    }

但是我们看到工厂类里面的代码是很杂乱的,能做很多事情:能创建减法实例、加法实例等等,它违背了设计模式的基本原则之单一职责原则(单一职责:如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。)。并且我们如果要增加一个新的运算的话,我们还是得修改代码,为switch语句增加一个分支,很显然这又违背了开闭原则(开闭原则:对修改关闭,对拓展开放),因为每一次修改代码都可能会对原先的代码产生影响,使得原先的代码不可靠,需要重新测试。

而工厂方法模式针对此做了点升级,其实很简单很粗暴,就是把工厂拆开,加减乘除四个运算,我们就拆成四个工厂呗。比如加法/减法工厂的代码时下面这个:

其他的几个操作也是这样写,相当于就是把原想的工厂类拆成四个单独的类,最后我们在使用这些类的时候,用下面的方法来写: 

 我们可以对上面的代码进行进一步的抽象,我们能看到所有的工厂方法都具有相似的逻辑,我们可以抽象出一个接口出来,然后后面新加的工厂都实现这个接口,同时我们原有的四个操作都实现了  Operation 类 , 所以代码可以重构成下面这样:

 为了尽可能的以来抽象我们将代码做了如上的改动。

总结:

可以看出来,工厂方法模式可以通过简单工厂改进而来,但是我们也可以明显的感觉的它貌似没有简单工厂简洁,同样的功能实现代码更多,而且类的数量也多。

尽管这样,好处也是显而易见的。当我们要新增一种运算的时候,我们需要做的时添加一个运算类,然后添加一个针对这个运算的工厂,我们用拓展实现,而不是修改,这样就避免了修改代码出现BUG的情况。而且实际开发的时候某些对象的创建不时new一下就行的,可能还需要一些参数,一些逻辑,我们用工厂方法就可以把这些逻辑隔离开,不会像简单工厂一样都合并在一个方法中,增加了代码的复杂度。

这篇写的比较匆忙也比较杂乱,但总结起来就几句话,就是在简单工厂的基础上进一步抽象和推广,把原先工厂方法进行拆分,每一个对象对应一个工厂。它保持了简单工厂的优点,也克服了缺点,当然代码量也加多了点,这是为数不多的缺点之一。

再进一步,几分钟了解抽象工厂模式  ==》 抽象工厂模式

猜你喜欢

转载自blog.csdn.net/maaici/article/details/108006839