女朋友dodo闹脾气,气势汹汹的说“我要吃雪糕”。笔者心里啊乐滋滋的,一支雪糕就能哄回来,不亦乐乎?!

但是,雪糕买回来了,她竟然说“不想吃雪糕了,突然想吃披萨”。呵呵了,憋了一股劲“没问题”,又屁颠屁颠的去把披萨买回来。

世事难料,dodo同学又放大招了,“披萨太上火了,我要吃芝士蛋糕”。

这时候,工厂方法模式该上场了,使用它可以完美的解决不断的产品变更。工厂方法模式是怎么样的?而工厂模式又是怎样解决产品变更呢?一起来看看...

一、工厂方法模式

定义

  定义一个创建对象的工厂接口,工厂方法将实例化推迟到子类中。

定义总是抽象的,先放出工厂方法模式的UML图如下所示:

从上图可以看出,工厂方法模式涉及到以下四个角色的概念:

  - 抽象工厂角色:工厂方法模式的核心,创建产品的工厂类必须实现该接口。

  - 具体工厂角色:该角色实现了抽象工厂接口,具体如何创建产品类就是在该实现类完成。

  - 抽象产品角色:所有产品类的超类,负责实现产品共性的抽象定义。

  - 具体产品角色:该角色实现了抽象产品接口,负责具体的不同产品业务逻辑。

二、实战

上代码

抽象工厂角色代码如下:

public interface Factory {

	// 传入参数的是产品类型,这里返回产品类的抽象工厂类Product
public Product factory(String productType); }

这里做出生产雪糕、披萨的工厂,有了工厂才能生产对应的产品,具体工厂角色代码如下:

// 雪糕的工厂,负责生产雪糕
public class IceCreamFactory implements Factory { @Override
public Product factory() {
return new IceCream();
} }

上面看到抽象角色Product,看代码:

public interface Product {

	public void product();

}

具体角色代码如下:

public class IceCream implements Product {

	@Override
public void product() { /**
* 具体的业务逻辑
*/
System.out.println("雪糕做好了!!");
} }

OK,涉及到工厂方式模式系统的代码基本完成,下面看看客户端怎么使用工厂模式,雪糕准备就绪:

public class Client {

	public static void main(String[] args){

		// 生产雪糕
Factory iceCreamFactory = new IceCreamFactory();
Product iceCream = iceCreamFactory.factory();
iceCream.product(); } }

运行客户端代码,结果如下:

雪糕做好了!!

扩展

雪糕的order已经完成!雪糕不吃,吃披萨?OK,现在就做披萨。同样的先实现抽象工厂和抽象产品角色。

披萨工厂实现如下:

// 披萨的工厂,负责生产披萨
public class PizzaFactory implements Factory { @Override
public Product factory() {
return new Pizza();
} }

接下来就是披萨:

public class Pizza implements Product {

	@Override
public void product() {
/**
* 具体的业务逻辑
*/
System.out.println("披萨做好了!!");
} }

现在我们在客户端中实现生产披萨,代码如下:

public class Client {

	public static void main(String[] args){

		// 生产雪糕
Factory iceCreamFactory = new IceCreamFactory();
Product iceCream = iceCreamFactory.factory();
iceCream.product(); // 生产披萨
Factory pizzaFactory = new PizzaFactory();
Product pizza = pizzaFactory.factory();
pizza.product();
} }

运行结果如下:

雪糕做好了!!

披萨做好了!!

三、工厂方法模式的优缺点

优点

1)优秀的扩展性。假如披萨不想吃了,想吃芝士蛋糕,只需要增加芝士蛋糕的具体工厂和具体产品类,不会影响其他产品的生产。

2)大降低代码的耦合度,客户端最终得到的是产品本身,而不需要知道和操作产品的生产过程。

缺点

1)增加新产品时,需要增加具体的工厂类和具体的产品类,当产品数量多的时候就会造成系统的复杂度增大,也增加了对系统理解的难度。

四、比较

跟策略模式对比:问得最多的一个问题。工厂方法模式和策略的模式有什么区别?区别在于,策略模式强调的是提供不同的策略方案,而工厂方法模式强调的是产品本身。

策略模式接下来也会说到,把策略模式吃透了,回头再跟工厂方法模式对比的时候就恍然大悟了。

总结

首先,上一篇的单例模式很多人都给我提了很不错的建议,也在这篇文章中改进了。工厂方式模式的使用率也非常高,掌握它对把握系统架构会有比较大的提升。下一篇要分享的是:建造者模式

设计模式Java源码GitHub下载:https://github.com/jetLee92/DesignPattern

我的Java设计模式-工厂方法模式的更多相关文章

  1. JAVA设计模式--工厂方法模式

    工厂方法设计模式 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关.是具体工厂角色必须实现的接口或者必须继承的父类.在java中它由抽象类或者接口来实现.具体工厂角色:它含有和具体业务逻辑有关 ...

  2. Java设计模式—工厂方法模式&抽象工厂模式

    工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在 ...

  3. Java设计模式-工厂方法模式(Virtual Constructor/Polymorphic Factory)

    工厂方法模式(Virtual Constructor/Polymorphic Factory) 工厂方法模式是类的创建模式,又叫做虚拟构造子模式(Virtual Constructor)或者多态性工厂 ...

  4. Java设计模式-工厂方法模式(Factory Method)

    工厂方法模式(Factory Method) 工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建.在以下的三种模式中,第一种如果传入的字符串有误,不能正确创 ...

  5. Java设计模式---工厂方法模式(Factory-Method)

    一.普通工厂模式 建立一个工厂类,对实现了同一接口的一些类进行实例的创建 实例代码: 发送短信和邮件的例子,首先创建接口: public interface Sender { public void ...

  6. 4. 星际争霸之php设计模式--工厂方法模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  7. C++设计模式——工厂方法模式

    本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.» 本文链接:http://www.jellythink.com/arch ...

  8. 深入浅出设计模式——工厂方法模式(Factory Method)

    介绍在简单工厂模式中,我们提到,工厂方法模式是简单工厂模式的一个延伸,它属于Gof23中设计模式的创建型设计模式.它解决的仍然是软件设计中与创建对象有关的问题.它可以更好的处理客户的需求变化. 引入我 ...

  9. 24种设计模式--工厂方法模式【Factory Method Pattern】

    女娲补天的故事大家都听说过吧,今天不说这个,说女娲创造人的故事,可不是“造人”的工作,这个词被现代人滥用了. 这个故事是说,女娲在补了天后,下到凡间一看,哇塞,风景太优美了,天空是湛蓝的,水是清澈的, ...

随机推荐

  1. 如何将Windows7系统中“运行”历史记录全部清除

    如何将Windows7系统中“运行”历史记录全部清除.. 如何将Windows7系统中“运行”历史记录全部清除 1.任务栏空白处按下鼠标右键,在右键菜单栏中选择“属性”, 2.切换到“开始菜单”选项卡 ...

  2. Javascript是单线程的深入分析(转)

    http://www.cnblogs.com/Mainz/p/3552717.html

  3. emacs命令记录

    C-代表按住Ctrl键 M-代表按住Alt键,也可以用按一下ESC放开代替   最先要记住的 M-x <cmd>      输入指令执行,在输入时用Tab可以自动补全或列出项目 C-g   ...

  4. 7.7 WPF后台代码绑定如果是属性,必须指定一下数据上下文才能实现,而函数(click)就不用

    如: private bool _IsExportWithImage; /// <summary> /// 是否选择导出曲线图 /// </summary> public bo ...

  5. python pip升级失败

    接上篇,使用命令:python -m pip install --upgrade pip 发现pip升级时报错,无法升级 解决方法: 1.使用如下命令,查看具体失败原因: pip install -- ...

  6. .NET CORE 学习笔记之安装EF【Microsoft.EntityFrameworkCore】扩展报错

    最近在学习.NET CORE ,刚开始就遇到问题了. 安装EF框架的试试就报错, 报错如下: 错误 程序包还原失败.正在回滚“XXX”的程序包更改. 找了好久的方案,网上也没搜到对应的问题和方案,然而 ...

  7. Grails笔记三:完整的文件上传实例

    文件上传在web应用中是比较普遍的,相对于使用jsp等技术实现文件上传,Grails的文件上传着实让人喜爱,因为极其简单,让人看一遍就容易轻松记住!不多说,实例如下: 假设已有一个名为uploadFi ...

  8. matlab-常用函数(1)

    rng('shuffle'): matlab help文档中的解释 rng('shuffle'): seeds the random number generator based on the cur ...

  9. RSA算法介绍

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt279 2.1.1     算法实现 首先, 找出三个数, p, q, r,其 ...

  10. [转]Java se 7 最新特性研究(一)

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp81   从2006到现在等待了多年的jdk7终于发布了.这里将对它的一些 ...