zoukankan      html  css  js  c++  java
  • 悟空模式-java-普通工厂模式

    【大圣看玩多时,问土地道:“此树有多少株数?”土地道:“有三千六百株。前面一千二百株,花微果小,三千年一熟,人吃了成仙了道,体健身轻。中间一千二百株,层花甘实,六千年一熟,人吃了霞举飞升,长生不老。后面一千二百株,紫纹缃核,九千年一熟,人吃了与天地齐寿,日月同庚。”大圣闻言,欢喜无任,当日查明了株树,点看了亭阁回府。自此后,三五日一次赏玩,也不交友,也不他游。】

    在《西游记》第五回《乱蟠桃大圣偷丹 反天宫诸神捉怪》里有上面这一段关于蟠桃园里不同种类蟠桃树的描述,那么这里就用蟠桃园为例来描述一下普通工厂模式的运作方式:

    蟠桃

    package com.tirion.design.simple.factory;
    
    public interface FlatPeach {
    
        void printLevel();
    
        void printCycleTime();
    }

    低级蟠桃

    package com.tirion.design.simple.factory;
    
    public class LowLevelFlatPeach implements FlatPeach {
    
        LowLevelFlatPeach(){
            printCycleTime();
            printLevel();
        }
    
        @Override
        public void printLevel() {
            System.out.println("低级蟠桃");
        }
    
        @Override
        public void printCycleTime() {
            System.out.println("三千年一熟");
        }
    
    }

    中级蟠桃

    package com.tirion.design.simple.factory;
    
    public class MiddleLevelFlatPeach implements FlatPeach {
    
        MiddleLevelFlatPeach(){
            printCycleTime();
            printLevel();
        }
    
        @Override
        public void printLevel() {
            System.out.println("中级蟠桃");
        }
    
        @Override
        public void printCycleTime() {
            System.out.println("六千年一熟");
        }
    
    }

    高级蟠桃

    package com.tirion.design.simple.factory;
    
    public class HighLevelFlatPeach implements FlatPeach {
    
        HighLevelFlatPeach(){
            printCycleTime();
            printLevel();
        }
    
        @Override
        public void printLevel() {
            System.out.println("高级蟠桃");
        }
    
        @Override
        public void printCycleTime() {
            System.out.println("九千年一熟");
        }
    
    }

    蟠桃园

    package com.tirion.design.simple.factory;
    
    public class FlatPeachGarden {
        public static FlatPeach produce(String level) {
            System.out.println("生长出...");
            if ("low".equals(level)) {
                return new LowLevelFlatPeach();
            } else if ("middle".equals(level)) {
                return new MiddleLevelFlatPeach();
            } else if ("high".equals(level)) {
                return new HighLevelFlatPeach();
            } else {
                System.out.println("没有对应等级的蟠桃");
                return null;
            }
        }
    }

    王母娘娘

    package com.tirion.design.simple.factory;
    
    public class TheQueenMother {
    
        public static void getFlatPeach(String level) {
            FlatPeach flatPeach = FlatPeachGarden.produce(level);
            if (flatPeach == null) {
                System.out.println("王母娘娘没有得到蟠桃");
            } else {
                System.out.println("王母娘娘获得了蟠桃");
            }
        }
    
        public static void main(String[] args) {
            TheQueenMother.getFlatPeach("low");
            TheQueenMother.getFlatPeach("middle");
            TheQueenMother.getFlatPeach("high");
            TheQueenMother.getFlatPeach("super high");
        }
    }

    这里的蟠桃园就是一个蟠桃工厂,在这个工厂里有三种产品:三千年一熟的低级蟠桃、六千年一熟的中级蟠桃以及九千年一熟的高级蟠桃,王母娘娘需要蟠桃的时候,就可以通过调用蟠桃园的produce方法,传入她所需要的蟠桃等级,就可以获得对应等级的蟠桃。

    下面是上述代码的执行结果:

    生长出...
    三千年一熟
    低级蟠桃
    王母娘娘获得了蟠桃
    生长出...
    六千年一熟
    中级蟠桃
    王母娘娘获得了蟠桃
    生长出...
    九千年一熟
    高级蟠桃
    王母娘娘获得了蟠桃
    生长出...
    没有对应等级的蟠桃
    王母娘娘没有得到蟠桃

    这个示例的类图如下:

    从上图可以看出,蟠桃真正的消费者王母娘娘The Queen Mother,并不需要接触到具体的蟠桃FlatPeach。当王母娘娘需要蟠桃的时候,她只需要调用工厂类蟠桃园FlatPeachGarden的produce方法,告知它自己需要的蟠桃等级level,就可以获取到对应的蟠桃了,如果她给了蟠桃园错误的指令,则不会获取到蟠桃。

    所以,普通工厂模式的优点在于,产品的消费者并不需要知道产品生产的细节,消费者只需要调用工厂类创建产品的方法就可以了,产品创建的具体逻辑交给了工厂类来独立处理,这就实现了责任的分离,消费者负责获取产品,工厂类负责创建产品。

    接着我们再看一下普通工厂模式的扩展性如何:

    假设现在出现了一个突发情况,蟠桃园的九千年高级蟠桃被孙悟空全部偷吃掉了,蟠桃园工厂目前提供不了九千年高级蟠桃了,我们如何在程序中体现这个逻辑的改动呢?非常简单,只需要修改蟠桃园类的生产逻辑就可以了。

    package com.tirion.design.simple.factory;
    
    public class FlatPeachGarden {
        public static FlatPeach produce(String level) {
            System.out.println("生长出...");
            if ("low".equals(level)) {
                return new LowLevelFlatPeach();
            } else if ("middle".equals(level)) {
                return new MiddleLevelFlatPeach();
            } else if ("high".equals(level)) {
                System.out.println("高级蟠桃被孙悟空偷吃完了");
                return null;
                // return new HighLevelFlatPeach();
            } else {
                System.out.println("没有对应等级的蟠桃");
                return null;
            }
        }
    }

    其他部分代码不需要改变,程序的执行结果如下:

    生长出...
    三千年一熟
    低级蟠桃
    王母娘娘获得了蟠桃
    生长出...
    六千年一熟
    中级蟠桃
    王母娘娘获得了蟠桃
    生长出...
    高级蟠桃被孙悟空偷吃完了
    王母娘娘没有得到蟠桃
    生长出...
    没有对应等级的蟠桃
    王母娘娘没有得到蟠桃

    也就是说,对于产品生产逻辑的变更,我们只需要修改普通工厂模式的核心逻辑类——工厂类就可以了。

    我们现在再假设另外一种情况,蟠桃园经过神仙们多年的精心培育,出现了新的品种——超高级蟠桃SuperHighLevelFlatPeach,我们如何改变现有代码,去体现这个变更呢?也非常方便,只需要在FlatPeach体系下增加这个新的蟠桃,然后再修改一下蟠桃园类生产对应蟠桃的逻辑就可以了:

    package com.tirion.design.simple.factory;
    
    public class SuperHighLevelFlatPeach implements FlatPeach {
    
        SuperHighLevelFlatPeach(){
            printCycleTime();
            printLevel();
        }
    
        @Override
        public void printLevel() {
            System.out.println("超高级蟠桃");
        }
    
        @Override
        public void printCycleTime() {
            System.out.println("一万年一熟");
        }
    
    }
    package com.tirion.design.simple.factory;
    
    public class FlatPeachGarden {
        public static FlatPeach produce(String level) {
            System.out.println("生长出...");
            if ("low".equals(level)) {
                return new LowLevelFlatPeach();
            } else if ("middle".equals(level)) {
                return new MiddleLevelFlatPeach();
            } else if ("high".equals(level)) {
                return new HighLevelFlatPeach();
            } else if ("super high".equals(level)) {
                return new SuperHighLevelFlatPeach();
            } else {
                System.out.println("没有对应等级的蟠桃");
                return null;
            }
        }
    }

    变更后代码的执行结果如下:

    生长出...
    三千年一熟
    低级蟠桃
    王母娘娘获得了蟠桃
    生长出...
    六千年一熟
    中级蟠桃
    王母娘娘获得了蟠桃
    生长出...
    九千年一熟
    高级蟠桃
    王母娘娘获得了蟠桃
    生长出...
    一万年一熟
    超高级蟠桃
    王母娘娘获得了蟠桃

    可以看到,一万年一熟的超高级蟠桃比较容易地融入了原有的代码结构。但是这里违反了开闭原则,每次对蟠桃种类进行扩展都需要修改蟠桃园类,这一点很不方便。

    以上的这些扩展均不用修改消费者的代码,说明这些代码的扩展对消费者来说是透明的,这一点在很多设计模式中都非常重要。

    普通工厂模式的缺点也很明显,如果蟠桃园里的蟠桃种类非常多且经常调整的话,我们就要经常去修改蟠桃园生产蟠桃的方法,而且这个方法本身会非常复杂,效率也会非常低下。而且如果哪一天,孙悟空将这个蟠桃园捣毁了,工厂类无法继续正常运作,那么整个体系就完全瘫痪了,这一点非常不安全。同时它违反了单一职责原则,蟠桃园既要负责管理生产蟠桃的逻辑判断,又要负责蟠桃实例的创建。

    为了解决这些问题,我们将会引入相对更加高级的工厂模式,请继续阅读悟空模式-java-工厂方法模式,这里对普通方法模式的介绍就到这里,你可以将它记忆为蟠桃园模式。

    如果你认为文章中哪里有错误或者不足的地方,欢迎在评论区指出,也希望这篇文章对你学习java设计模式能够有所帮助。转载请注明,谢谢。

    更多设计模式的介绍请到悟空模式-java设计模式中查看。

  • 相关阅读:
    pyppeteer
    maven生命周期clean,compile,install,package区别
    centos7安装anyproxy
    安装jupyter notebook
    Linux-Centos7下安装Anaconda
    python文件 启动django项目
    PyCharm实用插件
    pyqt5 安装额外的工具
    PyQt5高级界面控件之QTableWidget的具体使用方法
    k8s Metrics Server 获取资源指标与 hpa 部署
  • 原文地址:https://www.cnblogs.com/tirion/p/7526366.html
Copyright © 2011-2022 走看看