views:

44

answers:

3

I have an interface, IMessage and a class which have several methods for creating different types of message like so:

class MessageService
{
    IMessage TypeAMessage(param 1, param 2)
    IMessage TypeBMessage(param 1, param 2, param 3, param 4)
    IMessage TypeCMessage(param 1, param 2, param 3)
    IMessage TypeDMessage(param 1)    
}

I don't want this class to do all the work for creating these messages so it simply delegates to a MessageCreatorFactory which produces an IMessageCreator depending on the type given (an enumeration based on the type of the message TypeA, TypeB, TypeC etc)

interface IMessageCreator
{
     IMessage Create(MessageParams params);
}

So I have 4 implementations of IMessageCreator: TypeAMessageCreator, TypeBMessageCreator, TypeCMessageCreator, TypeDMessageCreator

I ok with this except for the fact that because each type requires different parameters I have had to create a MessageParams object which contains 4 properties for the 4 different params, but only some of them are used in each IMessageCreator.

Is there an alternative to this? One other thought I had was to have a param array as the parameter in the Create emthod, but this seems even worse as you don't have any idea what the params are. Or to create several overloads of Create in the interface and have some of them throw an exception if they are not suitable for that particular implementation (ie you called a method which needs more params, so you should have called one of the other overloads.)

Does this seem ok? Is there a better solution?

A: 

In my oppinion having four overloads of IMessage Create is much better then having one method with MessageParam in it.

Just throw an exception for those methods that are not supporting by the implementation of creator.

As result you will have great benefit in probably a week or a month when you open your code again. This implementation will be more obvious to you then the current one

Andrey Tagaew
Thanks, the problem I see with this is that if the number of different parameters increases, then the number of overloads increases and each existing implementation need to be updated to add the new overload. whereas with a MessageParam object, only a new field needs to be added and nothing else needs to change. Also if I have a new message that takes a different combination of existing parameters I need a new overload, but with the existing method I can use the unaltered Messageparams.
Sam Holder
Man, i got the idea. If the main reason why you want to have different creator classes, is because the size of the file, then it can be overcome.You may create partial class and separate all creators by different files, but all they will be in one factory class.
Andrey Tagaew
+2  A: 

This is really a violation of the spirit of the Factory method pattern. If you require different parameters for the construction of your different types, you're implicitly forcing the caller to know, in advance, what type is being constructed. This completely eliminates the benefit of this pattern.

For example, if you're specifying an enum (TypeA, TypeB, TypeC), you might as well just construct TypeA directly. If you want to allow multiple subclasses to implement TypeA, make a factory just for TypeA...

Reed Copsey
A: 

I don't see any reason why your TypeXMessageCreator classes should implement a common interface. I would get rid of IMessageCreator entirely, and just have 4 separate factories to create IMessage objects.

If the creation of IMessage objects requires some common logic, you can put that logic in a separate class and use it from within the factories.

Remember that inheritance is not for code reuse.

Paolo Capriotti