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

 

简单工厂的使用,simple factory这个类public。实力类访问权限设置为internal,确保外部只会通过factory拿到实例。

 

 

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

posted @ 2015-02-26 09:20  ChuckLu  阅读(424)  评论(0编辑  收藏  举报