• 悟空模式-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设计模式中查看。

  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/tirion/p/7526366.html
Copyright © 2020-2023  润新知