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?
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.
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.
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.
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.
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!
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".
(Just because the creator is abstract, doesn't mean this is the Abstract Factory!).
It is a Factory Method because the children of “Creator” are responsible for implementing the “Create” method.
Another key point is that the creator is returning only one object.
The object could be one of several types, but the types all inherit from the same parent class.
the client maintains a reference to the abstract Creator, but instantiates it with one of the subclasses. (i.e. Creator c = new ConcreteCreator1(); )
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”.
the concrete creator creates the concrete object. In the case of Step One, this would be "Child Class A".
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.
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).
the client maintains a reference to an abstract Factory class, which all Factories must implement. The abstract Factory is instantiated with a concrete factory.
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.
the concrete factory creates the concrete objects.
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.
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.
kick at can：做一个尝试