Before you apply the template, you should have a clear idea of what you get by doing this, in which case I really don’t see that introducing a static “Factory” is gaining you. Look at this from the PacketFactory client PacketFactory : did he introduce it by reducing the connection between the client and various specific IPacket performers? I would not argue that since the client should already know what type of IPacket it wants, specifying the enumeration value is either PacketType.Info , PacketType.Message , or PacketType.Log . How does this differ from a client who knows about the Info , Message and Log classes? Since "Factory" is a static class, the client is also associated with the return type of IPacket , as if it would just call the constructor of the corresponding IPacket constructor, because you would have to change the client to work with another type of IPacket anyway.
So, if you really have to use any Factory, I would suggest using the Abstract Factory template, so that Factory clients depend only on the Factory interface and therefore able to work with different types of IPacket without the need for change. For instance:
public interface IPacketFactory { IPacket CreatePacket(); IPacket CreatePacket(Client creator, DateTime creationTime, string data); } public class MessageFactory : IPacketFactory { public CreatePacket() { return new Message(); } public CreatePacket(Client creator, DateTime creationTime, string data) { return new Message(creator, creationTime, data); } }
As far as Factory should allow building IPacket without specifying the creator, the data and time of creation are either independent of class invariants. If class invariants can be satisfied when fields are not specified, then this is fine, otherwise they should be necessary. Part of the task of the class should be to make sure that it cannot be constructed in an invalid state, since users of this class will depend on what happens.
In the case when one of the IPacket developers needs additional parameters:
The Factory sample needs to be a single interface for all artists, so if it makes sense to use the Create method with additional parameters for all factories, you can add them to the interface. One of the forms is to transfer an object with various properties / methods that the Create method can use to obtain additional parameter values that it needs. A special case is Double Dispatch, where the caller himself transmits (in this case, the Client) and then is called from the Create method.
You must remember that the goal is to abstract the type of IPacket , so if you start to feel that Client beginning to implicitly know which type is being built, then you may need to take a step back and consider whether Factory. The only other option is to provide additional information when building the Factory (i.e., Pass it to the constructor).
public class MessageFactory : IPacketFactory { private object _data; public MessageFactory(object extraData) { _data = extraData; } IPacket CreatePacket(Client creator, DateTime creationTime, string data) { return new Message(creator, creationTime, data, _extraData); }
Those represent some of the parameters, but in any case, I would strongly recommend that you not use the static or single class "Factory", because it will strongly combine your client class with Factory and most likely an IPacket subclass.