Simple Factory vs. Factory Method vs. Abstract Factory【简单工厂,工厂方法以及抽象工厂的比较】
I ran into a question on stackoverflow the other day that sort of shocked me.
It was a piece of code, with the author asking why it wasn't a factory pattern.
The thing that shocked me was that the pattern that everyone was agreeing was a factory method pattern, really wasn't.
I’m pretty sure that this a rare occurrence for stackoverflow, they seem to have an abundance of gifted developers who love to answer questions.
Regardless, here is my proverbial kick at can, trying to explain the differences as clearly as I can.
(BTW, if you're looking for a different take on patterns, I'd recommend the Head First Design Patterns book, which I thought provided a pretty good introduction into patterns, in way that doesn't put you to sleep.)
For this post, I simply want to discuss three factory designs: the Simple Factory, the Factory Method Pattern, and the Abstract Factory Pattern.
But instead of concentrating on learning the patterns (you can find all these and more at dofactory ), I’m going to concentrate on what I see as the key differences between the three, and how you can easily recognize them.
As a bit of background, the thing that all three have in common is that they are responsible for creating objects.
The calling class (which we call the “client”) wants an object, but wants the factory to create it.
I guess if you wanted to sound really professional, you could say that factories are used to encapsulate instantiation.
So what's the difference between a simple factory, a factory method design pattern, and an abstract factory?
Simple Factory


The easiest way for me to remember this is that a simple factory is called directly by the class which wants to create an object (the calling class is referred to as the "client"). The simple factory returns one of many different classes. All the classes that a simple factory can return either inherit from the same parent class, or implement the same interface.

Step One:
you call a method in the factory. Here it makes sense to use a static method. The parameters for your call tell the factory which class to create.
步骤1:调用简单工厂中的方法。使用静态方法比较合适。通过传递参数来告知简单工厂,带创建的是哪一个类的对象。
Step Two:
the factory creates your object. The only thing to note is that of all the objects it can create, the objects have the same parent class, or implement the same interface.
步骤2:简单工厂创建了你需要的对象。你唯一需要注意的是,所有简单工厂能创建的对象,它们有相同的父类或实现了同一个接口。
Step Three:
factory returns the object, and this is why step two makes sense. Since the client didn't know what was going to be returned, the client is expecting a type that matches the parent class /interface.
步骤3:工厂返回对象,使得步骤2有意义。调用简单工厂的类不知道返回的是什么,所以客户端类会用父类或接口类型的变量来接收返回的对象。
Sticklers will note that this is not an “official” design pattern. While this is true, I find it useful and think that it merits discussion!
细心的人可能会发现,简单工厂并不是一个官方的设计模式。确实是这样的,但我发现这个是很有用的,并认为有价值来讨论简单工厂。
ps:可以结合这篇文章看http://www.cnblogs.com/zhili/p/SimpleFactory.html
Factory Method

The official definition of the pattern is something like: a class which defers instantiation of an object to subclasses.
工厂方法设计模式的定义:将对象的实例化延迟到子类的一个类。
An important thing to note right away is that when we're discussing the factory pattern, we're not concentrating on the implementation of the factory in the client,
一件需要立即知道并且重要的事情是:我们讨论工厂方法模式,我们并不关心在客户端如何实现
but instead we're examining the manner in which objects are being created.
而是关心对象被创建的方式。
In this example the client doesn't have a direct reference to the classes that are creating the object, but instead has reference to the abstract "Creator".
在工厂方法中,客户端类没有负责创建对象的类的引用,而是拥有一个抽象的Creator的引用。
(Just because the creator is abstract, doesn't mean this is the Abstract Factory!).
虽然creator 是抽象的,但并不意味着它是抽象工厂。
It is a Factory Method because the children of “Creator” are responsible for implementing the “Create” method.
因为Creator的子类负责实现Create方法,所以它是工厂方法。
Another key point is that the creator is returning only one object.
另外一个关键点是:creator 仅仅返回一个对象
The object could be one of several types, but the types all inherit from the same parent class.
这个对象可能有几种类型,但是所有的类型都从同一个父类继承。

Step One:
the client maintains a reference to the abstract Creator, but instantiates it with one of the subclasses. (i.e. Creator c = new ConcreteCreator1(); )
步骤1:客户端拥有抽象Creator的引用,但是通过Creator的一个子类来实例化它。
Step Two:
the Creator has an abstract method for creation of an object, which we'll call "Create". It's an abstract method which all child classes must implement. This abstract method also stipulates that the type that will be returned is the Parent Class or the Interface of the “product”.
步骤2:Creator抽象类,有一个用来创建对象的抽象方法Create。因为Create方法是抽象的,所以所有的子类都必须实现它。Create确保了方法的返回类型是父类或者接口。
Step Three:
the concrete creator creates the concrete object. In the case of Step One, this would be "Child Class A".
步骤3:具体的creator负责创建具体的对象。在步骤1的情况下,这会是子类A。
Step Four:
the concrete object is returned to the client. Note that the client doesn’t really know what the type of the object is, just that it is a child of the parent.
步骤4:将具体的对象返回给客户端类。需要注意的是客户端类不知道返回的对象的具体类型,只知道返回的是父类的一个子类。
Abstract Factory

This is biggest pattern of the three. I also find that it is difficult to distinguish this pattern from the Factory Method at a casual glance. For instance, in the Factory Method, didn’t we use an abstract Creator? Wouldn’t that mean that the Factory Method I showed was a actually an Abstract Factory? The big difference is that by its own definition, an Abstract Factory is used to create a family of related products (Factory Method creates one product).
Step One:
the client maintains a reference to an abstract Factory class, which all Factories must implement. The abstract Factory is instantiated with a concrete factory.
步骤1:客户端有抽象工厂类的引用,所有的工厂都需要实现抽象工厂。抽象工厂的引用需要用某一个具体的工厂类进行实例化
Step Two:
the factory is capable of producing multiple types. This is where the “family of related products” comes into play. The objects which can be created still have a parent class or interface that the client knows about, but the key point is there is more than one type of parent.
步骤2:工厂要求生产多个不同类型的商品。即产品族的概念。创建的对象仍然有一个父类或接口(对于客户端可知的),但关键点是,此处有多个父类或接口
Step Three:
the concrete factory creates the concrete objects.
步骤3:具体的工厂负责创建具体的产品
Step Four:
the concrete objects are returned to the client. Again, the client doesn’t really know what the type of the objects are, just that are a children of the parents.
步骤4:具体的产品返回给客户端。客户端仍然不知道返回的对象类型是什么,仅知道父类的类型。
See those concrete factories? Notice something vaguely familiar? There using the Factory Method to create objects.
看到具体的工厂了吗?发现似曾相识的地方了吗?这里在使用工厂方法创建对象。
总结:
So, being as brief as I can:
- A Simple factory is normally called by the client via a static method, and returns one of several objects that all inherit/implement the same parent.
- The Factory Method design is really all about a “create” method that is implemented by sub classes.
- Abstract Factory design is about returning a family of related objects to the client. It normally uses the Factory Method to create the objects.
参考:
http://corey.quickshiftconsulting.com/blog/first-post
词汇:
proverbial :谚语的;众所周知的;
kick at can:做一个尝试
抽象工厂的实际运用:
在System.Data中。
DbProviderFactory作为抽象工厂,其下有CreateConnection和CreateCommand2个方法。
其中CreateConnection返回的类型是基类DbConnection,CreateCommand返回的类型是基类DbCommand
从DbConnection派生了2个子类:SqlConnection和OleDbConnection
从DbCommand派生了2个子类:SqlCommand和OleDbCommand
从抽象工厂派生出了多个工厂类,例如SqlClientFactory和OleDbFactory
这2个子工厂实现了CreateConnection以及CreateCommand方法
SqlClientFactory的CreateConnection返回的是DbConnection的子类SqlConnection;CreateCommand返回的是DbCommand的子类SqlCommand;但是方法的返回类型,还是对应的基类DbConnection以及DbCommand
OleDbFactory的CreateConnection返回的是DbConnection的子类OleDbConnection;CreateCommand返回的是DbCommand的子类OleDbCommand;但是方法的返回类型,还是对应的基类DbConnection以及DbCommand
Simple Factory vs. Factory Method vs. Abstract Factory【简单工厂,工厂方法以及抽象工厂的比较】的更多相关文章
- 设计模式3---工厂模式(Factory Pattern简单工厂、工厂方法、抽象工厂)
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...
- C++设计模式 之 “对象创建”模式:Factory Method、Abstract Factory、Prototype、Builder
part 0 “对象创建”模式 通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式 Fact ...
- [Design Patterns] 01. Creational Patterns - Abstract Factory
设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结,使用设计模式的目的是提高代码的可重用性,让代码更容易被他人理解,并保证代码可靠性.它是代码编制真正实现工程化. 四个关键元素 ...
- 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)
在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...
- 【创建型】Abstract Factory模式 & Factory Method模式
本文主要介绍简单工厂模式与抽象工厂模式.以下如有叙述不当之处,欢迎批评指正,欢迎交流探讨. 一:简单工厂模式 在23种设计模式中,简单工厂模式其实是不在列的,但理解该模式对于抽象工厂模式的思想理解是有 ...
- 面向对象设计——抽象工厂(Abstract Factory)模式
定义 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类.抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道或关心实际产出的具体产品是什么.这样一来,客户就能从具体的产 ...
- PHP设计模式(三)抽象工厂模式(Abstract Factory)
一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...
- 设计模式(3)抽象工厂模式(Abstract Factory)
设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 设计模式(2)工厂方法模式(Factory Method) 源码地址 0 抽象工厂模式简介 0.0 抽象工厂模式定义 抽象工厂 ...
- 大白话抽象工厂模式(Abstract Factory Pattern)
实例分析 大白话工厂方法模式(Factory Method)一文中,我们讲解了日产4S店工厂规模的扩大,创建了针对不同车型的工厂,减少了工厂的工作内容,提高了效率.下面我们继续以4S店的故事讨论抽象工 ...
随机推荐
- 【BZOJ】【2631】Tree
LCT 又一道名字叫做Tree的题目…… 看到删边加边什么的……又是动态树问题……果断再次搬出LCT. 这题比起上道[3282]tree的难点在于需要像线段树维护区间那样,进行树上路径的权值修改&am ...
- SpringMVC:com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax;
今天用SpringMVC做修改添加操作,之前的操作都实现了添加修改,但始终报com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have ...
- Poj 1032 分类: Translation Mode 2014-04-04 09:09 111人阅读 评论(0) 收藏
Parliament Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16521 Accepted: 6975 Descr ...
- JS 数组的基础知识
数组 一.定义 1.数组的文字定义 广义上说,数组是相同类型数据的集合.但是对于强类型语言和弱类型语言来说其特点是不一样的.强类型语言数组和集合有以下特点. 数组强类型语言:1.数组里面只能存放相同数 ...
- windows_phone指定时间后执行函数
开发windows phone 应用程序时需要在一段指定的时间后执行某些函数,于是乎想到了通过DispatcherTimer类来实现,再在.Tick后面添加自己想要的事件 DispatcherTime ...
- 十个实用但IE不支持的CSS属性
对IE浏览器尤其是IE6的抱怨基本已进入麻痹状态,偶尔甚至产生非常消极的想法:这个世界只有一个浏览器就好了,哪怕这唯一的浏览器就是IE6.当然,这样的想法是非常病态的,马上打消.本文里面,介绍了10个 ...
- Grid分组特性
Ext.onReady(function () { Ext.define('personInfo', { extend: 'Ext. ...
- 转 wince程序 中使用Listview显示图标问题 (C#) .
思路: 1.窗体控件:lstaqgl [Listview控件名称] imageList1[ImageList控件] 2. 图片路径添加到—imageList1——Listview显示图片从 ima ...
- Error Code: 1175 Mysql中更新或删除时报错(未带关键字条件)
SET SQL_SAFE_UPDATES = 0; SQL_SAFE_UPDATES = {0 | 1} 如果设置为0,则MySQL会放弃在WHERE子句或LIMIT子句中不使用关键字的UPDATE或 ...
- ZOJ3231 Apple Transportation(最小费用流)
题目给你一棵苹果树,然后每个结点上有一定的苹果树,你要将苹果运输达到某个状态,使得均方差最小. 将苹果x个从a->b的花费是x*w,w是边权. 当时比赛的时候想的就是,最后达到的状态一定是sum ...