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【简单工厂,工厂方法以及抽象工厂的比较】的更多相关文章

  1. 设计模式3---工厂模式(Factory Pattern简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  2. C++设计模式 之 “对象创建”模式:Factory Method、Abstract Factory、Prototype、Builder

    part 0 “对象创建”模式 通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式 Fact ...

  3. [Design Patterns] 01. Creational Patterns - Abstract Factory

    设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结,使用设计模式的目的是提高代码的可重用性,让代码更容易被他人理解,并保证代码可靠性.它是代码编制真正实现工程化. 四个关键元素 ...

  4. 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)

    在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...

  5. 【创建型】Abstract Factory模式 & Factory Method模式

    本文主要介绍简单工厂模式与抽象工厂模式.以下如有叙述不当之处,欢迎批评指正,欢迎交流探讨. 一:简单工厂模式 在23种设计模式中,简单工厂模式其实是不在列的,但理解该模式对于抽象工厂模式的思想理解是有 ...

  6. 面向对象设计——抽象工厂(Abstract Factory)模式

    定义 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类.抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道或关心实际产出的具体产品是什么.这样一来,客户就能从具体的产 ...

  7. PHP设计模式(三)抽象工厂模式(Abstract Factory)

    一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...

  8. 设计模式(3)抽象工厂模式(Abstract Factory)

    设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 设计模式(2)工厂方法模式(Factory Method) 源码地址 0 抽象工厂模式简介 0.0 抽象工厂模式定义 抽象工厂 ...

  9. 大白话抽象工厂模式(Abstract Factory Pattern)

    实例分析 大白话工厂方法模式(Factory Method)一文中,我们讲解了日产4S店工厂规模的扩大,创建了针对不同车型的工厂,减少了工厂的工作内容,提高了效率.下面我们继续以4S店的故事讨论抽象工 ...

随机推荐

  1. SGU 185 Two shortest 最短路+最大流

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=21068 Yesterday Vasya and Petya qua ...

  2. UVA 10078 The Art Gallery

    Problem: Century Arts has hundreds of art galleries scattered all around the country and you are hir ...

  3. Codeforce 438D-The Child and Sequence 分类: Brush Mode 2014-10-06 20:20 102人阅读 评论(0) 收藏

    D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input st ...

  4. 用boost共享内存实现进程通信的例子

    发送端 #include "DBProc1.h" #include <string> #include <thread> #include <boos ...

  5. centos6.5安装图形界面,windows远程linux图形界面

    1. 查询是否已安装图形界面 yum grouplist |more 在grouplist的输出结果中的“Installed Groups:”部分中,如果你能找到“X Window System”和G ...

  6. Intent.ACTION广播大全

    Intent.ACTION广播大全 Intent.ACTION_AIRPLANE_MODE_CHANGED; //关闭或打开飞行模式时的广播 Intent.ACTION_BATTERY_CHANGED ...

  7. 简单shell脚本

      简单shell脚本备忘   #!/bin/sh num= ] do table_num=`printf %03d ${num}` echo album_info_${table_num} #mys ...

  8. 一个有趣的Ajax Hack示范

    今天在梦之光芒的BLOG上看见了一个Ajax Hack示范,其实跨站发现很容易,但是要做到大危害还是很难,偷偷COOKIE什么的只针对用户而已,XSS WORM的那种利用才是可怕的. 来看看他的一段V ...

  9. oracle OVER(PARTITION BY) 函数

    OVER(PARTITION BY)函数介绍 开窗函数               Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返 ...

  10. Grid分组汇总

    Ext.onReady(function () {                Ext.define('personInfo', {                    extend: 'Ext. ...