简单工厂 抽象工厂模式,工厂方法模式和抽象工厂模式的区别

抽象工厂模式探讨--《玉林师范学院学报》2014年02期
抽象工厂模式探讨
【摘要】:工厂模式是常用的设计模式,一般分为简单工厂模式、工厂方法模式、抽象工厂模式三类.工厂方法模式是对简单工厂模式推广,抽象工厂模式是对工厂方法模式推广.简单工厂模式和工厂方法模式是针对单个产品族的问题,如果对应于多个产品族,则不宜解决.针对这一问题,本文通过Java语言实现了抽象方法模式来解决多个产品族的问题.
【作者单位】:
【关键词】:
【分类号】:TP311.11【正文快照】:
计模式是针对某一领域问题的最佳解决方法,是一套可以反复使用、多数人知晓的设计方案,是经验总结.Java EE主流框架应用了多个设计模式完成,设计模式是Java EE的重要理论基础.最为著名的四人帮的《设计模式》[1]书中介绍了23种基本设计模式,最常用的设计模式有单
欢迎:、、)
支持CAJ、PDF文件格式,仅支持PDF格式
【相似文献】
中国期刊全文数据库
陈灯,王勇,徐启丰;[J];计算机仿真;2003年12期
孙林记;陶宏;;[J];漯河职业技术学院学报;2009年02期
田虹;卢毅;;[J];武汉理工大学学报(信息与管理工程版);2006年11期
魏一搏;郭友;;[J];信息系统工程;2010年02期
张丽萍;曹静;陈晓娟;;[J];兰州交通大学学报;2010年03期
向华;;[J];长江大学学报(自然科学版)理工卷;2009年02期
王善桃;;[J];中小企业管理与科技(上旬刊);2010年12期
贾延明;张永涛;;[J];计算机系统应用;2011年01期
陈传波,李涛,张道杰;[J];计算机工程与科学;2004年10期
周坤;;[J];教育教学论坛;2011年08期
中国重要会议论文全文数据库
路阳;;[A];中国农业工程学会2011年学术年会(CSAE 2011)论文摘要集[C];2011年
中国硕士学位论文全文数据库
高增智;[D];南昌大学;2012年
王苏文;[D];南昌大学;2008年
叶超;[D];南昌大学;2012年
徐瑜;[D];华中科技大学;2006年
郑庭明;[D];山东大学;2007年
魏一搏;[D];河北科技大学;2010年
孙默泓;[D];复旦大学;2010年
成卓;[D];天津大学;2010年
冯熙麟;[D];电子科技大学;2011年
张珩;[D];电子科技大学;2012年
&快捷付款方式
&订购知网充值卡
400-819-9993
《中国学术期刊(光盘版)》电子杂志社有限公司
同方知网数字出版技术股份有限公司
地址:北京清华大学 84-48信箱 大众知识服务
出版物经营许可证 新出发京批字第直0595号
订购热线:400-819-82499
服务热线:010--
在线咨询:
传真:010-
京公网安备75号简单工厂模式,工厂方法模式和抽象工厂模式的异同_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
简单工厂模式,工厂方法模式和抽象工厂模式的异同
上传于||文档简介
&&本​人​学​习​模​式​是​遇​到​这个​相​关​模​式​所​摘​录​下​的​笔​记​。
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩1页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢简单工厂模式、工厂方法模式 与 抽象工厂模式 的区别?
这个博客里说:“其实工厂方法模式是用来创建一个产品的等级结构的,而抽象工厂模式是用来创建多个产品的等级结构的。工厂方法创建一般只有一个方法,创建一种产品。抽象工厂一般有多个方法,创建一系列产品。”那么根据这里的例子来看,工厂方法模式只是在简单工厂模式的基础上,给工厂加多了一个接口,这样做又有什么好处?
加接口是为了隐藏复杂的创建过程,方便扩展。「大话设计模式」中用工厂模式实现对员工表进行由SQL Server到Access的转换,但公司不可能只有员工表,若要对部门表处理,需要增加至少三个类。所以要加接口,体现开放-封闭原则。
已有帐号?
无法登录?
社交帐号登录  之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略。这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处。工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。下面结合例子分析三者的区别。
  首先是简单工厂模式,这里以工厂生产产品为例。
产品类的共同接口
* @author CIACs
7 public interface Product {
//声明类所需继承的共同接口,也可以是抽象类
* @author CIACs
7 public class ProductA implements Product {
public ProductA() {
System.out.println("ProductA");
* @author CIACs
7 public class ProductB implements Product {
public ProductB() {
System.out.println("ProductB");
* @author CIACs
7 public class Factory {
//可以在工厂类中添加任何你所需要的逻辑
public static Product create(String str)
//生成ProductA
if(str.equalsIgnoreCase("ProductA"))
return new ProductA();
//生成ProductB
if(str.equalsIgnoreCase("ProductB"))
return new ProductB();
return null;
* @author CIACs
7 public class Client {
public static void main(String[] args) {
//调用Factory的静态方法生成所要的类
Factory.create("productA");
Factory.create("ProductB");
控制台输出结果:
  简单工厂模式实现了生成产品类的代码跟客户端代码分离,在工厂类中你可以添加所需的生成产品的逻辑代码,但是问题来了,优秀的java代码是符合&开放-封闭&原则的,也就是说对扩展开发,对修改关闭,如果你要加一个产品类C,你就要修改工厂类里面的生成产品的代码,在这里你就要增加if-else判断。对于这个问题,我们的工厂方法模式就可以解决这个问题。
  接下来是工厂方法模式
&产品类中增加了ProductC(其他产品类的代码是可以重用上面的,只要把包名更改了就行)。
1 package factoryM
* @author CIACs
8 public class ProductC implements Product {
public ProductC() {
System.out.println("productC");
声明工厂接口
1 package factoryM
* @author CIACs
7 public interface Factory {
//声明产生产品类的方法
public Product createProduct();
产生ProductA的FactoryA
1 package factoryM
* @author CIACs
7 public class FactoryA implements Factory {
//实现工厂类的方法生成产品类A
public Product createProduct()
return new ProductA();
产生ProductB的FactoryB
1 package factoryM
* @author CIACs
7 public class FactoryB implements Factory {
//实现工厂类的方法生成产品类B
public Product createProduct()
return new ProductB();
产生ProductC的FactoryC
1 package factoryM
* @author CIACs
7 public class FactoryC implements Factory {
//实现工厂类的方法生成产品类C
public Product createProduct()
return new ProductC();
1 package factoryM
* @author CIACs
7 public class Client {
public static void main(String[] args) {
factory = new FactoryA();
factory.createProduct();
factory = new FactoryB();
factory.createProduct();
factory = new FactoryC();
factory.createProduct();
控制台输出结果:
&  工厂方法模式中我们把生成产品类的时间延迟,就是通过对应的工厂类来生成对应的产品类,在这里我们就可以实现&开发-封闭&原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果产品类过多,我们就要生成很多的工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同牌子产的车里面会有跑车类型,家庭类型,商用类型等的车,不同牌子的车的跑车类型的车可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。
   最后是抽象工厂模式,在这里我们为不同产品附加上对应的礼物,就是说ProductA中会有GiftA。
增加的Gift接口
1 package abstractF
* @author CIACs
7 public interface Gift {
//声明产品赠品的接口,当然也可以是抽象类,同样为了简单就不声明方法了
1 package abstractF
* @author CIACs
7 public class GiftA implements Gift {
public GiftA()
System.out.println("GiftA");
1 package abstractF
* @author CIACs
7 public class GiftB implements Gift {
public GiftB()
System.out.println("GiftB");
Factory接口
1 package abstractF
* @author CIACs
*声明Product类工厂和Gift类工厂的工同工厂接口
7 public interface Factory {
public Product createProduct();
public Gift createGift();
生成ProductA和GiftA的FactoryA
1 package abstractF
* @author CIACs
*FactoryA可以生成ProductA和GiftA
7 public class FactoryA implements Factory {
public Product createProduct()
return new ProductA();
public Gift createGift()
return new GiftA();
生成ProductB和GiftB的FactoryB
1 package abstractF
* @author CIACs
*FactoryB可以生成ProductB和GiftB
7 public class FactoryB implements Factory {
public Product createProduct() {
return new ProductB();
public Gift createGift() {
return new GiftB();
1 package abstractF
* @author CIACs
7 public class Client {
public static void main(String[] args) {
factory = new FactoryA();
factory.createProduct();
factory.createGift();
factory = new FactoryB();
factory.createProduct();
factory.createGift();
控制台输出结果:
  抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了&开放-封闭&原则,是三个模式中较为抽象,并具一般性的模式。我们在使用中要注意使用抽象工厂模式的条件。
阅读(...) 评论()温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
成功一定有方法,失败一定有原因,
不为失败找借口,只为成功找方法。
To be a better
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
&如果老板要坐奥迪,同理。&这便是简单工厂模式了。那么它带了了什么好处呢?首先,符合现实中的情况;而且客户端免除了直接创建产品对象的责任,而仅仅负责“消费”产品(正如暴发户所为)。下面我们从开闭原则上来分析下简单工厂模式。当暴发户增加了一辆车的时候,只要符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。(即创建一个新的车类,继承抽象产品Car)那么 对于产品部分来说,它是符合开闭原则的——对扩展开放、对修改关闭;但是工厂类不太理想,因为每增加一辆车,都要在工厂类中增加相应的商业逻辑和判 断逻辑,这显自然是违背开闭原则的。&而在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以这可能会把我们的上帝类坏了。正如我前面提到的简单工厂模式适用于业务简单的情况下或者具体产品很少增加的情况。而对于复杂的业务环境可能不太适应了。这就应该由工厂方法模式来出场了!!&四、工厂方法模式抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。来用类图来清晰的表示下的它们之间的关系:&&&话说暴发户生意越做越大,自己的爱车也越来越多。这可苦了那位司机师傅了,什么车它都要记得,维护,都要经过他来使用!于是暴发户同情他说:我给你分配几个人手,你只管管好他们就行了!于是工厂方法模式的管理出现了。代码如下:&&&使用开闭原则来分析下工厂方法模式。当有新的产品(即暴发户的汽车)产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。(即当有新产品时,只要创建并基础抽象产品;新建具体工厂继承抽象工厂;而不用修改任何一个类)工厂方法模式是完全符合开闭原则的!&使用工厂方法模式足以应付我们可能遇到的大部分业务需求。但是当产品种类非常多时,就会出现大量的与之对应的工厂类,这不应该是我们所希望的。所以我建议在这种情况下使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。当然特殊的情况,就要特殊对待了:对于系统中存在不同的产品树,而且产品树上存在产品族(下一节将解释这个名词)。那么这种情况下就可能可以使用抽象工厂模式了。&五、小结让我们来看看简单工厂模式、工厂方法模式给我们的启迪:如果不使用工厂模式来实现我们的例子,也许代码会减少很多——只需要实现已有的车,不使用多态。但是在可维护性上,可扩展性上是非常差的(你可以想象一下添加一辆车后要牵动的类)。因此为了提高扩展性和维护性,多写些代码是值得的。&&六、抽象工厂模式先来认识下什么是产品族: 位于不同产品等级结构中,功能相关联的产品组成的家族。图中的BmwCar和BenzCar就是两个产品树(产品层次结构);而如图所示的BenzSportsCar和BmwSportsCar就是一个产品族。他们都可以放到跑车家族中,因此功能有所关联。同理BmwBussinessCar和BenzBusinessCar也是一个产品族。可以这么说,它和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且抽象工厂模式是三个里面最为抽象、最具一般性的。抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象。而且使用抽象工厂模式还要满足一下条件:1.系统中有多个产品族,而系统一次只可能消费其中一族产品2.同属于同一个产品族的产品以其使用。来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。&&其中:BenzSportCar和BenzBusinessCar属于产品树;同理BmwSportCar和BmwBusinessCar。而BenzSportCar和BmwSportCar和AudiSportCar属于产品族。所以抽象工厂模式一般用于具有产品树和产品族的场景下。抽象工厂模式的缺点:如果需要增加新的产品树,那么就要新增三个产品类,比如VolvoCar,VolvoSportCar,VolvoSportCar,并且要修改三个工厂类。这样大批量的改动是很丑陋的做法。所以可以用简单工厂配合反射来改进抽象工厂:UML图略。&&策略模式&从策略一词来看,策略模式是种倾向于行为的模式.有点类似找仗时的做战方案,一般司令员在做战前都会根据实际情况做出几套不同的方案,如果当时情况有变,就会根据相应的条件来判定用哪一套方案来替换原定方案。但无论如何替换,替换多少次,仗还是要打的。& 举例:导出成EXCEL,WORD,PDF文件的功能,这三类导出虽然具体操作略有不同,但是大部分都相同。策略模式与工厂模式从uml图上来说,基本一致。只是强调的封装不同。我们以工厂模式和策略模式的比较来讲解策略模式。工厂模式我们可以做如下理解:假设有Audi的公司生产汽车,它掌握一项核心的技术就是生产汽车,另一方面,它生产的汽车是有不同型号的,并且在不同的生产线上进行组装。当客户通过销售部门进行预定后,Audi公司将在指定的生产线上为客户生产出它所需要的汽车。策略(Strategy)模式在结构上与工厂模式类似,唯一的区别是工厂模式实例化一个产品的操作是在服务端来做的,换句话说客户端传达给服务端的只是某种标识,服务端根据该标识实例化一个对象。而策略模式的客户端传达给服务端的是一个实例,服务端只是将该实例拿过去在服务端的环境里执行该实例的方法。这就好比一个对汽车不甚了解的人去买车,他在那一比划,说要什么什么样的,销售部门根据他的这个“比划”来形成一份订单,这就是工厂模式下的工作方式。而策略模式下那个顾客就是个行家,他自己给出了订单的详细信息,销售部门只是转了一下手就交给生产部门去做了。通过两相对比,我们不难发现,采用工厂模式必须提供足够灵活的销售部门,如果用户有了新的需求,销售部门必须马上意识到这样才可以做出合适的订单。所以倘一款新车出来了,生产部门和销售部门都需要更新,对顾客来说也需要更新对新车的描述所以需要改动的地方有三处。而策略模式中的销售部门工作比较固定,它只负责接受订单并执行特定的几个操作。当一款新车出来时,只需要对服务端的生产部门和客户端的代码进行更新,而不需要更新销售部门的代码。&技术支持: 简单工厂和策略的基础都是因为面向对象的封装与多态。他们实现的思想都是先设定一个抽象的模型并从该模型派生出符合不同客户需求的各种方法,并加以封装。工厂模式和策略模式的区别在于实例化一个对象的位置不同,对工厂模式而言,实例化对象是放在服务端的,即放在了工厂类里面;而策略模式实例化对象的操作在客户端,服务端的“销售部门”只负责传递该对象,并在服务端的环境里执行特定的操作。。。工厂模式要求服务端的销售部门足够灵敏,而策略模式由于对策略进行了封装,所以他的销售部门比较傻,需要客户提供足够能区分使用哪种策略的参数,而这最好的就是该策略的实例了。&&策略模式的优缺点& 策略模式的主要优点有:策略类之间可以自由切换,由于策略类实现自同一个抽象,所以他们之间可以自由切换。易于扩展,增加一个新的策略对策略模式来说非常容易,基本上可以在不改变原有代码的基础上进行扩展。避免使用多重条件,如果不使用策略模式,对于所有的算法,必须使用条件语句进行连接,通过条件判断来决定使用哪一种算法,在上一篇文章中我们已经提到,使用多重条件判断是非常不容易维护的。& 策略模式的缺点主要有两个:维护各个策略类会给开发带来额外开销,可能大家在这方面都有经验:一般来说,策略类的数量超过5个,就比较令人头疼了。必须对 客户端(调用者)暴露所有的策略类,因为使用哪种策略是由客户端来决定的,因此,客户端应该知道有什么策略,并且了解各种策略之间的区别,否则,后果很严 重。例如,有一个排序算法的策略模式,提供了快速排序、冒泡排序、选择排序这三种算法,客户端在使用这些算法之前,是不是先要明白这三种算法的适用情况? 再比如,客户端要使用一个容器,有链表实现的,也有数组实现的,客户端是不是也要明白链表和数组有什么区别?就这一点来说是有悖于迪米特法则的。适用场景&&&&&&& 做面向对象设计的,对策略模式一定很熟悉,因为它实质上就是面向对象中的继承和多态,在看完策略模式的通用代码后,我想,即使之前从来没有听说过策略模式,在开发过程中也一定使用过它吧?至少在在以下两种情况下,大家可以考虑使用策略模式,几个类的主要逻辑相同,只在部分逻辑的算法和行为上稍有区别的情况。有几种相似的行为,或者说算法,客户端需要动态地决定使用哪一种,那么可以使用策略模式,将这些算法封装起来供客户端调用。&&&&&& 策略模式是一种简单常用的模式,我们在进行开发的时候,会经常有意无意地使用它,一般来说,策略模式不会单独使用,跟模版方法模式、工厂模式等混合使用的情况比较多。&转载:/zhangchenliang/p/3700820.html
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别',
blogAbstract:'结合简单示例和UML图,讲解工厂模式简单原理。&一、引子话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰)、Bmw(宝马)、Audi(奥迪)),还雇了司机为他开车。不过,爆发户坐车时总是这样:上Benz车后跟司机说“开奔驰车!”,坐上Bmw后他说“开宝马车!”,坐上 Audi后他说“开奥迪车!”。你一定说:这人有病!直接说开车不就行了?!而当把这个爆发户的行为放到我们程序语言中来,我们发现C语言一直是通过这种方式来坐车的!',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:9,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'成功一定有方法,失败一定有原因,\n不为失败找借口,只为成功找方法。
\nTo be a better
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 抽象工厂模式 的文章

 

随机推荐