2010-04-02 11 views
1

J'ai une interface, IMessage et une classe qui ont plusieurs méthodes pour créer différents types de messages comme ceci:Que dois-je faire si j'ai une méthode d'usine qui nécessite des paramètres différents pour différentes implémentations?

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)  
} 

Je ne veux pas cette classe pour faire tout le travail pour la création de ces messages afin simplement les délégués à un MessageCreatorFactory qui produit une IMessageCreator en fonction du type donné (une énumération en fonction du type de TypeA message, TypeB, TypeC etc.)

interface IMessageCreator 
{ 
    IMessage Create(MessageParams params); 
} 

J'ai donc 4 implémentations de IMessageCreator: TypeAMessageCreator, TypeBMessageCreator, TypeCMessageCreator, TypeDMessageCreator

Je ok avec ce à l'exception du fait que parce que chaque type nécessite des paramètres différents que j'ai dû créer un objet MessageParams qui contient 4 propriétés pour les 4 différents params, mais seulement certains d'entre eux sont utilisés dans chaque IMessageCreator.

Existe-t-il une alternative à cela? Une autre idée que j'avais était d'avoir un tableau param comme paramètre dans la méthode Create, mais cela semble encore pire car vous n'avez aucune idée de ce que sont les params. Ou pour créer plusieurs surcharges de Create dans l'interface et que certaines d'entre elles lancent une exception si elles ne conviennent pas à cette implémentation particulière (par exemple, vous appelez une méthode qui nécessite plus de paramètres, donc vous devriez avoir appelé l'une des autres surcharges).

Cela vous semble-t-il correct? Y a-t-il une meilleure solution?

Répondre

5

Ceci est vraiment une violation de l'esprit du Factory method pattern. Si vous avez besoin de différents paramètres pour la construction de vos différents types, vous forcez implicitement l'appelant à savoir, à l'avance, quel type est en cours de construction. Cela élimine complètement le bénéfice de ce modèle. Par exemple, si vous spécifiez une énumération (TypeA, TypeB, TypeC), vous pourriez tout aussi bien construire TypeA directement. Si vous souhaitez autoriser plusieurs sous-classes à implémenter TypeA, créez une fabrique uniquement pour TypeA ...

0

Dans mon oppinion ayant quatre surcharges de IMessage Create est beaucoup mieux alors avoir une méthode avec MessageParam dedans. Il suffit de lancer une exception pour les méthodes qui ne sont pas prises en charge par l'implémentation de creator.

En conséquence, vous aurez un grand avantage dans probablement une semaine ou un mois lorsque vous ouvrez à nouveau votre code. Cette implémentation sera plus évidente pour vous que l'actuelle

+0

Merci, le problème que je vois avec ceci est que si le nombre de différents paramètres augmente, alors le nombre de surcharges augmente et chaque implémentation existante doit être mise à jour pour ajouter la nouvelle surcharge.alors qu'avec un objet MessageParam, seul un nouveau champ doit être ajouté et rien d'autre ne doit changer. Aussi, si j'ai un nouveau message qui prend une combinaison différente de paramètres existants, j'ai besoin d'une nouvelle surcharge, mais avec la méthode existante, je peux utiliser le Messageparams non modifié. –

+0

Mec, j'ai eu l'idée. Si la raison principale pour laquelle vous voulez avoir différentes classes de créateurs, c'est parce que la taille du fichier, alors il peut être surmonté. Vous pouvez créer une classe partielle et séparer tous les créateurs par des fichiers différents, mais ils seront tous dans une classe de fabrique. –

0

Je ne vois aucune raison pour laquelle vos classes TypeXMessageCreator doivent implémenter une interface commune. Je voudrais me débarrasser de IMessageCreator entièrement, et juste avoir 4 usines distinctes pour créer IMessage objets.

Si la création d'objets IMessage nécessite une logique commune, vous pouvez placer cette logique dans une classe distincte et l'utiliser dans les usines. N'oubliez pas que l'héritage n'est pas pour la réutilisation du code.