|
|
Comments and Discussions
|
|
 |

|
Hi,
Thanks for the article.
I have one question- Why does interface require createproduct method. As the object is already getting initialized and added to hashtable when client calls RegisterProduct Method. So when client calls GetRoomType it will get the object from the collection.
|
|
|
|

|
Can i achieve that using Ninject?
|
|
|
|
|
|

|
Very nice article.
thanks
|
|
|
|

|
thank you for your nice article ...
i have a question
In the implementation-3 i don't understand why u have called CreateProduct() method
in GetRoomType in RoomFactory class as
return room.CreateProduct();
u have created products and put them in the dictionary previously...
i have put just return room; and it works ...
and u have called this method CreateProduct() only in this place, so i suggest delete this method from interface and sub-classes that implement it ..
thank you in advance
|
|
|
|

|
You need to create a new product, and not always return the same product. This is a factory where you clone your products not returning always the same sample.
|
|
|
|

|
Nice article, but, in my humble opinion, I wouldn't recommend this solution for complex cases.
Honestly, I think abstract factories should only be used in simple situations. When you come to a point where you need more flexibility, you will want to use a complete Inversion of Control library like these http://elegantcode.com/2009/01/07/ioc-libraries-compared/[^].
To be more specific, let me exemplify. Suppose you want to add a new room type. You would obligatorily have to touch the RoomTypes enumeration. Since your factory depends on this enumeration, you'd have to rebuild the factory to add another room type. Depending on the case, that might be a serious disadvantage. A really good abstract factory does not have any dependencies on the available concrete types.
Another lack of flexibility is in the control over the lifetime of the created objects. Sometimes, you need the created object to be singleton. Some other times, you might need only one instance to be created per each HttpRequest. For example, your hotel might have only one PresidentialSuiteRoom.
What if you need to pass some parameters to the constructor? The guest might want a room in the top floor. Or, making it more complex, he/she might want a room with a view to the beach AND to be at least on the third floor.
To cover all these cases and much more, you definitely need an IoC framework with DI (dependency injection). If you're not familiar with these subjects, I strongly suggest you to study it. It's a very deep and interesting subject.
see ya
|
|
|
|

|
The following line in your post is crucially important:
jpbochi wrote: A really good abstract factory does not have any dependencies on the available concrete types.
In fact, avoiding this dependency is precisely the reason for creating factories in the first place. As jpbochi points out, unfortunately all the solutions in the OP's otherwise comprehensive post rely on an enumeration that must be updated whenever a new concrete type is added, and thus they all violate the Open/Closed Principle.
As an alternative to an IoC solution, total loose coupling can be achieved with a simple "plugin" architecture:
1. Instead of using an enumeration type for a key, use an open-ended type (such as a string) and mandate a sound naming policy to avoid name collisions.
2. Place a DLL (or whatever is appropriate for your language) for each concrete type implementing a given interface in some well-known location (e.g. those implementing IFoo could go in the directory C:\MyProg\Plugins\Foo)
3. On program startup, scan each DLL in this directory and call a RegisterType() function in each to register each concrete type.
This way, adding a new concrete type is as simple as deploying a new DLL file to a specific directory. That is how you add concrete types while respecting the OCP.
This also has the obvious efficiency advantage of not having to scan through every type in the assembly, checking for whether it implements a given interface, like the OP's solution #4 does. (Aside: I'm not familiar with .NET, so maybe this is a silly question, but how would that foreach loop in solution #4 find a concrete type anyway if nothing has specifically created an instance of one yet with new? The first attempt to create an object of a given concrete type would come via the factory function itself, so that concrete type would not even appear to exist yet at registration time. I assume .NET loads types lazily -- is that correct?)
WTJW
|
|
|
|

|
You're absolutely right. One easy way to remove the dependency on the enumeration is by using another "key" to identify the concrete types.
wtwhite wrote: This also has the obvious efficiency advantage of not having to scan through every type in the assembly, [...]
How would you find the types to register without scanning all types in the assemblies?
wtwhite wrote: [...] how would that foreach loop in solution #4 find a concrete type anyway if nothing has specifically created an instance of one yet with new? The first attempt to create an object of a given concrete type would come via the factory function itself, so that concrete type would not even appear to exist yet at registration time. I assume .NET loads types lazily -- is that correct?
I'll try and answer that. I don't know which language you're more familiar with, but, in .NET, you don't need to instantiate types. In fact, you can't do that. To get a Type instance, you need to call a reflection function, like Assembly.GetTypes().
The foreach in the solution #4 will enumerate through all the types of the current executing assembly and register only a few selected types. In that way, a simple association between a key value and a Type is kept in the factory. No real instances exist at this point. IRoomType instances are created only when GetRoomType() is called.
The authors have chosen Activator.CreateInstance() to create a instance from a Type. Basically, this function will search for a constructor with no parameters for the specified Type and call it.
By the way, looking at the code now, I spotted some possible bugs.
A. If a registered type has no parameterless constructor, Activator.CreateInstance() will fail. It might be a good idea to avoid that. Maybe, it would be better to not even register the type;
B. If an abstract class implements the IRoomType interface and has the Key property, it would get registered. Since it's impossible to instantiate abstract classes, the factory should not accept registering one;
C. The singleton pattern is not thread-safe. This might help: http://msdn.microsoft.com/en-us/library/ms998558.aspx[^].
One last comment. If you don't need/want to use IoC and prefer the approach that wtwhite suggested, you can use the MEF framework (http://www.codeplex.com/MEF[^]). It so useful that Microsoft has included it inside the .NET Framework 4.0, which is still in beta, unfortunately.
thanks!
JP
|
|
|
|

|
Thanks for the helpful reply. Being largely ignorant of .NET, I went and quickly scanned a tutorial webpage on .NET assemblies to find out what they actually are: according to my mental model of things, it seems that a .NET assembly is basically a .NET-specific DLL or EXE file enhanced with better versioning and type information, and a sound policy ("strong naming") for naming shared assemblies (DLLs).
I was worried that .NET assemblies couldn't be installed "just anywhere" in the filesystem, but then I found this link: http://stackoverflow.com/questions/932339/net-assembly-plugin-security[^], which seems to be doing what I suggested earlier using the Assembly.LoadFile() function. So I suppose a "plugin directory" approach is possible after all.
So, I would suggest that concrete classes be deployed as separate assemblies in a known subdirectory. For easy management, I would recommend 1 concrete type per assembly, although you could certainly group together concrete types that will be deployed together into a single assembly. However, instead of iterating over all types contained in these assemblies as you, the OP and the poster of the above link propose, I suggest that it's much healthier to have each assembly provide a function, called say RegisterTypes(), which will register all relevant types in that assembly. This way, the decisions regarding which types in a given assembly get registered are made entirely by the assembly itself, so it's not possible to accidentally add types that "shouldn't" be added, such as mock/test versions of classes (it's impossible to determine these by any programmatic means, even if other cases such as abstract classes can be tested for via reflection).
If you put just 1 or a small number of concrete classes, and nothing else, into an assembly, then the speed impact of looping over all types in an assembly with GetTypes() will be very small -- but having RegisterTypes() just explicitly list the types will always be fast, even if that's not the case. It's still low-maintenance, since each assembly contains only 1 or a small number of concrete classes to register.
Your comments regarding constructors that need parameters are sound, though I think this is a more general problem. (Like most problems, it can be solved with another level of indirection: require all constructors for classes implementing IFoo to take a single argument of type IFooConstructorArgument, an interface type which lumps together all parameters; then establish a parallel hierarchy of concrete types implementing this interface, and have each IFoo-derived constructor downcast its argument appropriately.)
The languages I'm most familiar with are C and C++ BTW.
|
|
|
|

|
I almost completely agree with you. A RegisterTypes() function per assembly would be much better than scanning all types in each assembly. It would even be possible for a assembly to decide dynamically which types to register.
The reason for the "almost" above is this: In .NET, you cannot define a function outside a class. So, you would have to declare the RegisterTypes() function inside a class; and, in order to find it, you would have to find this class. You fall back to a similar problem. How to find a specific class inside an assembly?
One simplistic solution would be to settle a constant name for the class, but an assembly can easily have more than one class with the same name by placing them in different namespaces. I have thought about this and I think I've found a good solution using Custom Attributes (http://msdn.microsoft.com/en-us/library/sw480ze8%28VS.100%29.aspx[^]). Specifically, I would use an assembly attribute that points to the class where the RegisterTypes() function is.
Since a code snippet is worth some hundreds of words, here is how the attribute declaration would look like:
[AttributeUsage(AttributeTargets.Assembly)]
public class PluginAttachPointAttribute : Attribute
{
public Type AttachPoint { get; private set; }
public PluginAttachPointAttribute(Type attachPoint)
{
this.AttachPoint = attachPoint
}
}
And here is how an user assembly would use it:
[assembly: PluginAttachPoint(typeof(TypeProvider))]
class TypeProvider
{
Type[] RegisterTypes()
{
}
}
I have ran into similar problems in the past, but I haven't thought about using an assembly custom attribute before. There might be some catches around it. Anyway, I guess this discussion has expanded my mind in this point.
thanks!
JP
|
|
|
|

|
Yes, allowing the assembly to decide dynamically which types to register is a good idea which I hadn't considered. RegisterTypes() could e.g. check aspects of the environment and decide whether to register NTFSFoo or FAT32Foo or both.
jpbochi wrote: In .NET, you cannot define a function outside a class.
All that is necessary is that a function for registering types must somehow be locatable within each assembly. It looks like your approach of using assembly attributes is a good way to do that.
BTW, I can't claim any credit for these ideas for how to organise plugins -- they basically come straight from how COM does things. There are a lot of good ideas in COM, though it took me a while to fully appreciate them. Unfortunately the process of creating and using COM objects was never as simple and natural as it is with .NET objects, because it was designed for a native code environment without good infrastructural support (type safety etc.).
And yes, I've certainly learned heaps from this discussion! Glad the feeling's mutual
|
|
|
|

|
It does suggest that it might be worth while also creating an interface for the
interface IFactoryObject
{
string Key{get;}
IFactoryObject CreateObject();
}
and on the abstract base factory creating
public abstract RegisterFactoryObject(IFactoryObject obj)
Although it's not that neat in that you if you register and IRoom :IFactoryObject and you get back an IDinner :IFactoryObject bad things will happen.
Great article
Thanks,
Matthew @ pelsys
|
|
|
|

|
I like this article very much. You gave a clear explanation of the topic, showed the advantages and disadvantages of different approaches, and showed out it fit into the larger picture of patterns in general. Nice job.
|
|
|
|

|
Article Looks Good ! One small suggestion, It would be better if you provide hyperlink to the table content.
|
|
|
|

|
Isn't the class diagram at the bottom labeled FactoryMethodPattern actually a depiction of an Abstract Factory?
|
|
|
|

|
Hello,
Thanks for reading through my article. It’s always nice to receive some feedback
Well, with regards to your question the answer goes like this...
Factory Method Pattern provides an interface for creating an object, but let subclasses decide which class to instantiate.
Whereas Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.
The diagram I have shown depicts Factory method pattern as I am creating an object of type Room only. Notice that there is only one Abstract product type i.e. IRoomType in this case.
If I were to depict Abstract Factory Pattern, it would mean I am creating families of related/dependent objects. For e.g.
1 family could be - AC Room, AC Kitchen, AC Library
2nd - NonAC Room, NonAC Kitchen, NonAC Library
3rd - Deluxe Room, Deluxe Kitchen, Deluxe Library
In this case, the class diagram would be as follows:
<img src="http://img34.imageshack.us/img34/6554/absfactory.th.png" border="0">
|
|
|
|

|
In a tile game, I declared an interface for the tile objects, and then an interface for a tile-object factory. Then I wrote a method to build a dictionary of tile-object factories. I don't like the use of reflection for such purposes, because it assumes that (1) identifiers used in code will have meaning to the end user, and (2) if self-registering classes are used, it assumes that the mere existence of a class is sufficient reason to expose it to the end user.
If wishes to have the ability to add or remove tile types by adding and removing source files, one may define a partial class called TileRegistrar which defines a Startup event that accepts a callback delegate via which tile classes may register, and a RegisterAll method which accepts a delegate which will be passed to the event. Other source files containing tile class definitions could also contain partial class definitions for TileRegistrar, each containing a uniquely-named Startup event handler which would register any class definitions as appropriate.
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
How to Remove Conditional Checks
| Type | Article |
| Licence | CPOL |
| First Posted | 22 Jun 2009 |
| Views | 49,657 |
| Downloads | 1,040 |
| Bookmarked | 109 times |
|
|