设计模式(02) 工厂方法模式+简单工厂模式(上)

来源:互联网 发布:抓取网页内容工具 mac 编辑:程序博客网 时间:2024/06/05 21:52

From Now On,Let us begin Design Patterns。

简单工厂模式 + 工厂方法模式

定义

  • 定义一个用创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 Define aninterface for creating an object, but let subclasses decide which class toinstantiate. Factory Method lets a class defer instantiation to subclasses.

在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动。

如何能轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程呢

工厂模式的优点:

  • 良好的封装性,代码结构清晰。一个对象创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的具体过程,从而也降低了模块间的耦合。

  • 扩展性非常优秀。在增加产品类的情况下,只要适当修改具体的工厂类或扩展一个工厂类,就可以满足变化。

  • 屏蔽产品类。这一特点很重要,产品类的实现如何变化,调用者不需要关心,它只要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化。(直接案例:JDBC连接数据库,更换数据库类型时只需要切换一下驱动名称)。

  • 工厂方法是典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类都不用关心,符合迪米特法则,不需要的就不去交流;符合依赖倒置原则,只依赖产品类的抽象;符合里氏替换原则,使用产品子类替换产品父类。

工厂模式的缺点:

工厂模式的使用场景:

工厂方法是创建一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要慎重考虑是否要增加一个工厂类进行管理。

需要灵活的、可扩展的框架时,可以考虑采用工厂方法模式。(例如:需要设计一个连接邮件服务器的框架,有三种网络协议可以选择:POP3、IMAP、HTTP,我们可以把这三种连接方法作为产品类)再定义一个工厂方法,按照不同的传入条件,选择不同的连接方式。

工厂模式的实现方法(简单工厂模式 + 工厂方法模式):

1.简单工厂模式:
我们举一个例子来说明问题吧,这个例子的原型来自《设计模式之禅》

1)还没有工厂时代:假如还没有工业革命,如果一个客户要一款奔驰车,一般的做法是客户自己手工去创建一款奔驰车,然后拿来用。

2)简单工厂模式:后来出现工业革命,社会分工变得细化。用户不用去创建奔驰车。因为客户有一个工厂来帮他创建奔驰.想要什么车,这个工厂就可以建。比如想要320i系列车。工厂就创建这个系列的车。即工厂可以创建产品。

3)工厂方法模式时代:为了满足客户,奔驰车系列越来越多,如320i,523i,30li等系列一个工厂无法创建所有的宝马系列。于是由单独分出来多个具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。但是奔驰工厂还是个抽象。需要指定某个具体的工厂才能生产不同系列的奔驰车出来。

4)抽象工厂模式时代:随着客户的要求越来越高,奔驰车必须配置空调。于是这个工厂开始生产奔驰车和需要的空调。(这一篇我们下一篇接着说)

最终是客户只要对奔驰的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调奔驰车.

这就是工厂模式。

开始吧:

简单工厂模式:奔驰车的诞生

很久很久以前,有一个兄弟,他们梦想着做一辆汽车,他就是Benz兄弟。很幸运,他掌握了制造汽车的方法:于是乎,刚刚开始的时候,一个客户说要一台benz的S系,他就手工做一台,另个客户说要一台benz的M系,他们就手工再做一台。于是,场景是这样的:
这里写图片描述
源代码如下:
这里写图片描述

有一天,卡尔奔驰老师傅发现这样不行呀,太累了,而且,只有卡尔兄弟知道怎么去创建一款车,他和车就紧密耦合在一起了(除了他别人都不会造车,这不行呀)。为了降低耦合,就出现了工厂类(他办了一个工厂),把创建汽车的操作细节都放到了工厂里面去,客户直接使用工厂的创建汽车的方法,传入想要的奔驰车型号就行了,而不必去管创建的细节.这就是工业革命了:简单工厂模式

即我们建立一个工厂类方法来制造新的汽车对象。简单工厂模式:
这里写图片描述

源代码如下:

汽车产品:
这里写图片描述

工厂职能:
这里写图片描述

顾客买车:
这里写图片描述

终于,上面的就是简单工厂模式,生产汽车的工作交给了工厂,顾客直接向工厂买车。
简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。
先来看看它的组成:
1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在Java中由一个具体类实现。

下面我们从开闭原则(对扩展开放;对修改封闭)上来分析下简单工厂模式。

当客户不再满足现有的车型号的时候,想要一种速度快的新型车(我们上例的super超跑),只要这种车符合抽象产品制定的合同,那么只要通知工厂类知道就可以让工厂去生产了对吧。所以对产品部分来说,它是符合开闭原则的,我们新加的SuperBenzCar可以直接继承BenzCar,实现对扩展开放;但是工厂部分BenzFactory好像不太理想,因为每增加一种新型车,都要在工厂类中增加相应的创建业务逻辑(createBenzCar(String type)方法需要新增case),这显然是违背开闭原则的。可想而知对于新产品的加入,工厂类是很被动的,源代码总是要被改来改去。对于这样的工厂类,我们称它为全能类或者上帝类。一个工厂BenzFactory必须要具备制造所有车的能力。
这个时候,我们如果不希望karl-benz先生经营失败,奔驰汽车消失在地球上。我们就应该帮他一把,很简单:我们把工厂抽象出来,刚刚我们是面向实现编程,这次我们要面向接口编程,还记得依赖倒置原则吗?说干就干,开始:

工厂方法模式:不同系类奔驰车的涌现

之前一个工厂要负责所有系列的奔驰汽车的生产,导致了当我们需要任何型号的奔驰汽车,都会去找同一家工厂,这样的工厂,简直跟上帝一样,啥都会。导致需要新的型号的汽车的时候,benc公司会对这个工厂进行改造,假如以后不需要这款汽车的时候,我们又得修改这个工厂,所以这个工厂会越来越大,越来越繁琐。这样不利于benc汽车推出多个系列,多个型号的汽车。

即我们建立多个工厂来制造新的汽车对象。工厂方法模式:
这里写图片描述

源代码如下:

不同工厂:易于管理和扩展
这里写图片描述

不同的系列奔驰:
这里写图片描述

顾客买车:
这里写图片描述

买车结果:
这里写图片描述

工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。下一篇是:抽象工厂模式。

阅读全文
0 0