I've been trying to follow the principles of Dependency Injection, but after reading this article, I know I'm doing something wrong.
Here's my situation: My application receives different types of physical mail. All the incoming mail passes through my MailFunnel
object.
While it's running, MailFunnel
receives different types of messages from the outside: Box, Postcard and Magazine.
Each mail type needs to be handled differently. For example, if a Box comes in, I may need to record the weight before delivering it. Consequently, I have BoxHandler
, PostcardHandler
and MagazineHandler
objects.
Each time a new message comes into my MailFunnel
, I instantiate a new corresponding MailHandler
object.
For example:
class MailFunnel { void NewMailArrived( Mail mail ) { switch (mail.type) { case BOX: BoxHandler * bob = new BoxHandler(shreddingPolicy, maxWeightPolicy); bob->get_to_work(); break; case POSTCARD: PostcardHandler * frank = new PostcardHandler(coolPicturePolicy); frank->get_to_work(); break; case MAGAZINE: MagazineHandler * nancy = new MagazineHandler(censorPolicy); nancy->get_to_work(); break; } } private: MaxWeightPolcy & maxWeightPolicy; ShreddingPolicy & shreddingPolicy; CoolPicturePolicy & coolPicturePolicy; CensorPolicy & censorPolicy; }
On one hand, this is great because it means that if I get five different pieces of mail in, I immediately have five different MailHandlers
working concurrently to take care of business. However, this also means that I'm mixing object creation with application logic - a big no-no when it comes to Dependency Injection.
Also, I have all these policy references hanging around in my MailFunnel
object that MailFunnel
really doesn't need. The only reason that MailFunnel
has these objects is to pass them to the MailHandler
constructors. Again, this is another thing I want to avoid.
All recommendations welcome. Thanks!
This looks more like a factory to me. Move the invocation of the get_to_work() method out of the invocation and return the handler. The pattern works pretty well for a factory.
class MailHandlerFactory
{
IMailHandler* GetHandler( Mail mail )
{
switch (mail.type)
{
case BOX:
return new BoxHandler(shreddingPolicy, maxWeightPolicy);
break;
case POSTCARD:
return new PostcardHandler(coolPicturePolicy);
break;
case MAGAZINE:
return new MagazineHandler(censorPolicy);
break;
}
}
private:
MaxWeightPolcy & maxWeightPolicy;
ShreddingPolicy & shreddingPolicy;
CoolPicturePolicy & coolPicturePolicy;
CensorPolicy & censorPolicy;
}
class MailFunnel
{
MailHandlerFactory* handlerFactory;
MailFunnel( MailHandlerFactory* factory ) {
handlerFactory = factory;
}
void NewMailArrived( Mail mail ) {
IMailHandler handler = handlerFactory.GetHandler(mail);
handler.get_to_work();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With