This is part 2 of Extract and Override refactoring technique. You can find part 1 in my previous post.
I am going to show another technique by using Factory Method to break dependency in your code.
*WARNING* *WARNING*
Before I begin I would like to say all these techniques are not the best design but they will help you to break dependency and it might make some people flinch for the method but the intention is to get people to start looking at breaking dependency. Hopefully it will lead them to learn better design and make their code more modular in the process of it.
For anyone who doesn’t know Factory Method, you can read the GoF book or Head First Design Patterns. Which I would suggest you to buy if you don’t already own them.
Let’s say you have to send a letter to someone
public class Letter
{
private readonly ILetterSendingService _service;
public Letter(int id)
{
string userName = AppConfig.GetUserName(id);
string address = AppConfig.GetAddress(id);
_service = new LetterSendingService(userName, address);
}
public void SendLetter()
{
//some stuff to verify first
//and do some more processing
//now send the letter
_service.Send();
}
}
Now we see from the above code that it is actually very hard for us to test this Letter class dependency since LetterSendingService is not quite accessible and created in the Construtor of Letter class. So how do we extract and override it then?
Lets give it another shot.
public class Letter
{
private readonly ILetterSendingService _service;
private readonly string _username;
private readonly string _address;
public Letter(int id)
{
_userName = AppConfig.GetUserName(id);
_address = AppConfig.GetAddress(id);
_service = GetService();
}
protected virtual ILetterSendingService GetService()
{
return new LetterSendingService(_username, _address);
}
public void SendLetter()
{
//some stuff to verify first
//and do some more processing
//now send the letter
_service.Send();
}
}
Now with this in place we can create a stub Letter class and override its dependency like this
public class StubLetterWithFakeService: Letter
{
protected override ILetterSendingService GetService()
{
return new FakeLetterSendingService();
}
}
With this in place we can then override the dependency and test the Letter class with a fake dependency.
The downsides
This method maybe great since its easy to work with but it lacks the interaction.
- What if you wanted to check or verify some return values from ILetterSendingService?
- What if SendLetter method returns a boolean value, true if letter was sent and false otherwise
- What if ILetterSendingService interface has 15 methods in them, do we override all of them but we only care about 1 of them, which is SendLetter
A Mocking Framework like Rhino Mock or Moq would do a much better job at this, although you probably can override all the ILetterSendingService method but that is just too much work by hand writing stub etc.
Hopefully this post gave you some ways to think about breaking dependency in the future I will be writing about modular code and using some kind of IoC container to dependency inject and mocking framework to test your code 🙂