zoukankan      html  css  js  c++  java
  • 简单工厂模式与工厂方法模式

    简单工厂模式的结构图

    image

    简单工厂方法模式的结构图

    image

    关于工厂,我们最常识的理解就是给工厂提供原料,原料工厂根据我们提供的原料的不同,去制造出不同的新产品.

    那在程序设计中,我们的工厂就是一个类,那这个类的原料是什么呢?客户代码所传入的参数了,我们根据参数的不同来判断客户要的什么样的新产品,客户只管给原料,至于给了原料之后,传回的对象是什么,他就不那么关心了.

    在简单工厂中,根据前面的结构图,我们的目标是得到一个运算类,至于这个运算类到底是属于哪个子类的,由工厂中CreateOperate来决定.如果说我们传给了简单工厂类不同的参数,那么它就会根据不同的参数去实例化出加,减,乘,除的对象,然后我们在客户端再用一个运算类的引用去接收简单工厂所返回的对象.

    客户端的代码大概是这样的:

    Operation oper;

    oper=OperationFactory.createOperate(“+");

    oper.NumberA = 1;

    oper.NumberB = 2;

    oper.GetResult();

    在工厂方法模式中,我们的目标依然是要得到一个运算类.但现在工厂已经不再是一个类了,也就是说判断具体要实例化哪个类的决定权已经不在,而且下放到了它的实现者手上.所以它的了类都得通过某种方式去覆写父类或者是去实现接口中的共同方法.它的客户端代码是这样的:

    IFactory operFactory = new AddFactory();

    Operation oper;

    oper=operFactory .createOperate();   //关于父类或者接口中的createOperate方法已经在子类AddFactory中被覆写或者实现.

    oper.NumberA = 1;

    oper.NumberB = 2;

    oper.GetResult();

    那简单工厂和工厂方法到底有什么地方上的区别呢?

    有的,想象一下如果我现在想加一个&的操作,如果是在简单方法中,需要改变的地方有,添加一个&类,然后中在工厂中添加关于&的一个判断分支.

    如果在工厂方法中呢?我们同样需要添加一个&类,还需要添加一个&的工厂类去实现工厂类中的方法.

    在这里能看出些什么了吗?

    简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖.但这里面我们一定要去修改工厂类中的代码,这就违反了面向对象中的一个重要原则:OCP原则,也即开放封闭原则.而工厂方法很好的解决了这个问题,它定义了一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类.

    工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行.你想要加功能,本来是改工厂类的,而现在是修改客户端.

    总的来说,工厂方法克服了简单工厂违背开放封闭原则的缺点,以了封闭对象创建过程的优点.它们都是集中封闭了对象的创建,使得要更换对象时,不需要做大的改动就可以实现,降低了客户唾弃与产品对象的耦合.工厂方法模式是简单工厂模式的进一步抽象和推广.由于使用了多态性,工厂方法械保持了简单工厂模式的优点,而且克服了它的缺点,但缺点是由于每加一个产品,就需要加一个产品工厂类,增加了额外的开发量.

    还有判断分支的问题,也许我们可以用反射机制来解决这个问题.

  • 相关阅读:
    LeetCode——Generate Parentheses
    LeetCode——Best Time to Buy and Sell Stock IV
    LeetCode——Best Time to Buy and Sell Stock III
    LeetCode——Best Time to Buy and Sell Stock
    LeetCode——Find Minimum in Rotated Sorted Array
    Mahout实现基于用户的协同过滤算法
    使用Java对文件进行解压缩
    LeetCode——Convert Sorted Array to Binary Search Tree
    LeetCode——Missing Number
    LeetCode——Integer to Roman
  • 原文地址:https://www.cnblogs.com/laizhd/p/2122007.html
Copyright © 2011-2022 走看看