MyException - 我的异常网
当前位置:我的异常网» 设计模式 » 悟空形式-java-工厂方法模式

悟空形式-java-工厂方法模式

www.MyException.Cn  网友分享于:2013-09-19  浏览:0次
悟空模式-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.factory.method;

public abstract class FlatPeachGarden {
    public abstract FlatPeach produce();
}

低级蟠桃园

package com.tirion.design.factory.method;

public class LowLevelFlatPeachGarden extends FlatPeachGarden {

    @Override
    public FlatPeach produce() {
        return new LowLevelFlatPeach();
    }
}

中级蟠桃园

package com.tirion.design.factory.method;

public class MiddleLevelFlatPeachGarden extends FlatPeachGarden {

    @Override
    public FlatPeach produce() {
        return new MiddleLevelFlatPeach();
    }
}

高级蟠桃园

package com.tirion.design.factory.method;

public class HighLevelFlatPeachGarden extends FlatPeachGarden {

    @Override
    public FlatPeach produce() {
        return new HighLevelFlatPeach();
    }
}

王母娘娘

package com.tirion.design.factory.method;


public class TheQueenMother {

    public static FlatPeach getLowLevelFlatPeach() {
        FlatPeachGarden garden = new LowLevelFlatPeachGarden();
        FlatPeach flatPeach = garden.produce();
        if (flatPeach == null) {
            System.out.println("王母娘娘没有得到蟠桃");
        } else {
            System.out.println("王母娘娘获得了蟠桃");
        }
        return flatPeach;
    }

    public static FlatPeach getMiddleLevelFlatPeach() {
        FlatPeachGarden garden = new MiddleLevelFlatPeachGarden();
        FlatPeach flatPeach = garden.produce();
        if (flatPeach == null) {
            System.out.println("王母娘娘没有得到蟠桃");
        } else {
            System.out.println("王母娘娘获得了蟠桃");
        }
        return flatPeach;
    }

    public static FlatPeach getHighLevelFlatPeach() {
        FlatPeachGarden garden = new HighLevelFlatPeachGarden();
        FlatPeach flatPeach = garden.produce();
        if (flatPeach == null) {
            System.out.println("王母娘娘没有得到蟠桃");
        } else {
            System.out.println("王母娘娘获得了蟠桃");
        }
        return flatPeach;
    }

    public static void main(String[] args) {
        TheQueenMother.getLowLevelFlatPeach();
        TheQueenMother.getMiddleLevelFlatPeach();
        TheQueenMother.getHighLevelFlatPeach();
    }
}

在上面的代码中,我们将三种蟠桃分别交给三个不同类别的蟠桃园进行管理,每个蟠桃园负责生产某一种类的蟠桃,这样就把不同蟠桃的管理拆分开来,不再集中于一个蟠桃园,降低了系统的耦合风险。代码执行结果如下:

找到对应等级的蟠桃园
三千年一熟
低级蟠桃
王母娘娘获得了蟠桃
找到对应等级的蟠桃园
六千年一熟
中级蟠桃
王母娘娘获得了蟠桃
找到对应等级的蟠桃园
九千年一熟
高级蟠桃
王母娘娘获得了蟠桃

王母娘娘想要哪个种类的蟠桃,就派仙女去对应的蟠桃园去采摘,这就是工厂方法模式的运作方式,上例的类图如下:

现在我们将工厂方法模式与普通方法模式进行比较,看看工厂方法模式在面对一些问题时会有什么样的表现:

现在蟠桃园出现了同样的情况,悟空把高级蟠桃园里的桃子全部偷吃光了,又把中间蟠桃园的仙女用定身法术定住了,我们如何处理这样的变化呢?方法如下:

修改高级蟠桃园类和中级蟠桃园类

package com.tirion.design.factory.method;

public class HighLevelFlatPeachGarden extends FlatPeachGarden {

    @Override
    public FlatPeach produce() {
        System.out.println("高级蟠桃被齐天大圣偷吃光了!");
        return null;
        // return new HighLevelFlatPeach();
    }
}
package com.tirion.design.factory.method;

public class MiddleLevelFlatPeachGarden extends FlatPeachGarden {

    @Override
    public FlatPeach produce() {
        System.out.println("齐天大圣把中级蟠桃园的仙女定住了,没办法取蟠桃!");
        return null;
        // return new MiddleLevelFlatPeach();
    }
}

其他类不变,再来看代码的允许结果:

找到对应等级的蟠桃园
三千年一熟
低级蟠桃
王母娘娘获得了蟠桃
找到对应等级的蟠桃园
齐天大圣把中级蟠桃园的仙女定住了,没办法取蟠桃!
王母娘娘没有得到蟠桃
找到对应等级的蟠桃园
高级蟠桃被齐天大圣偷吃光了!
王母娘娘没有得到蟠桃

也就是说,哪个具体的工厂类出现了变化,我们就修改对应的工厂类就可以了,这样代码修改不会影响其他没有发生变化的业务代码逻辑,符合“单一职责原则”。产品的选择方案与工厂本身分离开来,工厂只要负责创建产品实例就可以了。

我们再来看另外一种情况,高级蟠桃被悟空吃掉了之后,也许是被齐天大圣的灵气所激发,部分果核后来居然生长出了一种新的蟠桃树,一万年一熟,我们叫它超高级蟠桃。下面我们将对工厂方法模式的蟠桃园体系进行调整,以适应蟠桃品种的变化:

超高级蟠桃

package com.tirion.design.factory.method;

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.factory.method;

public class SuperHighLevelFlatPeachGarden extends FlatPeachGarden {

    @Override
    public FlatPeach produce() {
        return new SuperHighLevelFlatPeach();
    }
}

这样,我们就把这种新的蟠桃品种加入进来了。王母娘娘暂时还不知道有了新的蟠桃,哪天她知道了,就派人去超高级蟠桃园去采摘就可以了。

从上面可以看出,增加一个新的蟠桃品种只需要增加一个新的产品类(超高级蟠桃)和一个新的产品工厂(超高级蟠桃园),而不必更改原有体系中任何一个类的代码,这样就符合了“开闭原则”。

所以说,工厂方法模式是普通工厂模式为了适应更多的未来变化而衍生出来的更高级的工厂模式,它解决了一些普通工厂模式违背的设计原则问题,即单一职责原则开闭原则

但是,工厂方法模式也有它的缺陷,那就是随着产品越来越多,每个产品都需要新建一个产品类和对应的工厂类,这样最终会导致类非常多。消费者也很难管理这些类。以上面的例子来说,就是最终蟠桃园里有好几十种蟠桃,王母娘娘也搞不清楚到底要哪些蟠桃,派仙女去哪些蟠桃园去采摘,最终引发体系混乱,代码修改难度加大,风险也随之上升。

为了解决这个问题,我们引入了悟空模式-java-抽象工厂模式,关于工厂方法模式的介绍就到这里,你可以将它记忆为多蟠桃园模式

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

文章评论

程序员和编码员之间的区别
程序员和编码员之间的区别
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序员应该关注的一些事儿
程序员应该关注的一些事儿
编程语言是女人
编程语言是女人
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员都该阅读的书
程序员都该阅读的书
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
一个程序员的时间管理
一个程序员的时间管理
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
Java程序员必看电影
Java程序员必看电影
旅行,写作,编程
旅行,写作,编程
 程序员的样子
程序员的样子
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
10个调试和排错的小建议
10个调试和排错的小建议
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
程序员的鄙视链
程序员的鄙视链
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
每天工作4小时的程序员
每天工作4小时的程序员
代码女神横空出世
代码女神横空出世
中美印日四国程序员比较
中美印日四国程序员比较
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
总结2014中国互联网十大段子
总结2014中国互联网十大段子
我是如何打败拖延症的
我是如何打败拖延症的
漫画:程序员的工作
漫画:程序员的工作
那些争议最大的编程观点
那些争议最大的编程观点
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
如何成为一名黑客
如何成为一名黑客
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
我的丈夫是个程序员
我的丈夫是个程序员
鲜为人知的编程真相
鲜为人知的编程真相
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有