美文网首页
第八章 雷锋依然在人间 - 工厂方法模式

第八章 雷锋依然在人间 - 工厂方法模式

作者: amazing_s10plus | 来源:发表于2019-08-18 15:01 被阅读0次

    这一章讲的是简单工厂模式和工厂方法模式的比较。
        先是说,小菜有个同学薛磊风(学雷锋),平时默默无闻,一天不幸出了车祸,然后同学们就去医院看望他,才知道他三年如一日地为一位孤寡老人做好事,然后他现在住院了嘛,就拜托小菜他们替他照顾一下老人家。
        坦白讲呢,如果是我的话,我做不到这么伟大,我只想照顾好自己的家人就够了。
        然后呢,小菜和大鸟说了这个事情,他们就开始谈论设计模式了,今天讨论的是简单工厂和工厂方法模式。
        简单工厂就是第一章讲的那个,在工厂类中有switch来生成对应的运算子类,而工厂方法模式呢,是在抽象工厂下面又扩展了对应的加减乘除四个工厂,有什么区别呢?
        在简单工厂中,如果要新增运算,那么就要修改工厂类,增加switch的分支,这就违背了开-闭原则,而工厂方法中,新增运算是新增对应的运算工厂类,这样不违背开闭原则。
        简单工厂模式最大的优点是工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类,对于客户端来说,去除了与具体产品相关的依赖。比如计算器例子中,客户端不用管该用哪个类的实例,只需要把运算符传给工厂就行。但是不可避免的违背了开闭原则,因为新增运算符势必需要修改工厂类。

        下面来重点理解一下工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪个子类,把一个类的实例化延迟到子类中。
        工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法模式把简单工厂的内部判断逻辑移到了客户端中,你想要增加功能,本来是改工厂类,现在是修改客户端。

    回到这一章的故事上来,用代码来表示帮助老人这个故事:

    /***
     * 雷锋抽象类
     */
    public abstract class LeiFeng {
    
        //    扫地
        abstract void sweep();
    
        //    洗衣服
        abstract void wash();
    
        //    买米
        abstract void buyRice();
    
    }
    

    现在三个学生去做好事,学生类Student继承LeiFent,在客户端中这样调用:

    public static void main(String[] args) {
    
            LeiFeng student1 = new Student();
            LeiFeng student2 = new Student();
            LeiFeng student3 = new Student();
    
            student1.sweep();
            student2.wash();
            student3.buyRice();
        }
    

    如果此时这三个不是学生,而是志愿者,那么就需要修改每个new Student()的地方,改成new Volunteer(),
    如果用简单工厂来描述,就是:

    switch 
      "学生" :
        new Student();
        break;
      "志愿者":
        new Volunteer();
        break;
    

    每个实例化学生的地方,都要写Factory.createLeiFeng("学生"),如果需要改成志愿者,那么每个地方都要修改;

    而如果用工厂方法模式来描述这个例子,就是:
    先创建StudentFactory和VolunteerFactory两个工厂类,继承LeiFengFactory,在客户端中:

    LeiFengFactory leiFengFactory = new StudentFactory();
    LeiFeng leiFeng1 = leiFengFactory.createLeiFeng();
    LeiFeng leiFeng2 = leiFengFactory.createLeiFeng();
    LeiFeng leiFeng3 = leiFengFactory.createLeiFeng();
    
    leiFeng1.buyRice();
    leiFeng2.sweep();
    leiFeng3.wash();
    

    这样,如果要改成志愿者做好事,那么只需要修改new StudentFactory()为new VolunteerFactory(),只需要改这一个地方就行。

    工厂方法模式比简单工厂要高明一点,它既封装了创建对象的过程,又克服了开闭原则,缺点是每加一个产品,就要对应增加一个工厂类。 -- “反射,可以解决这个问题。”

    相关文章

      网友评论

          本文标题:第八章 雷锋依然在人间 - 工厂方法模式

          本文链接:https://www.haomeiwen.com/subject/qeuqjctx.html