Question

Lately I've been trying to follow the TDD methodology, and this results in lot of subclasses so that one can easily mock dependencies, etc.

For example, I could have say a RecurringProfile which in turn has methods / operations which can be applied to it like MarkAsCancel, RenewProfile, MarkAsExpired, etc.. Due to TDD, these are implemented as 'small' classes, like MarkAsCancelService, etc.

Does it make sense to create a 'facade' (singleton) for the various methods/operations which can be performed on say a RecurringProfile, for example having a class RecurringProfileFacade. This would then contain methods, which delegate code to the actual sub-classes, eg.:

public class RecurringProfileFacade
{
    public void MarkAsCancelled(IRecurringProfile profile)
    {
        MarkAsCancelledService service = new MarkAsCancelledService();
        service.MarkAsCancelled(profile);
    }
    public void RenewProfile(IRecurringProfile profile)
    {
        RenewProfileService service = new RenewProfileService();
        service.Renew(profile);
    }
    ...
}

Note that the above code is not actual code, and the actual code would use constructor-injected dependencies. The idea behind this is that the consumer of such code would not need to know the inner details about which classes/sub-classes they need to call, but just access the respective 'Facade'.

First of all, is this the 'Facade' pattern, or is it some other form of design pattern?

The other question which would follow if the above makes sense is - would you do unit-tests on such methods, considering that they do not have any particular business logic function?

Was it helpful?

Solution

I would only create a facade like this if you intend to expose your code to others as a library. You can create a facade which is the interface everyone else uses.

This will give you some capability later to change the implementation.

If this is not the case, then what purpose does this facade provide? If a piece of code wants to call one method on the facade, it will have a dependency on the entire facade. Best to keep dependencies small, and so calling code would be better with a dependency on MarkAsCancelledService tha one on RecurringProfileFacade.

OTHER TIPS

In my opinion, this is kind of the facade pattern since you are abstracting your services behind simple methods, though a facade pattern usually has more logic I think behind their methods. The reason is because the purpose of a facade pattern is to offer a simplified interface on a larger body of code.

As for your second question, I always unit test everything. Though, in your case, it depends, does it change the state of your project when you cancel or renew a profile ? Because you could assert that the state did change as you expected.

If your design "tells" you that you could use a Singleton to do some work for you, then it's probably bad design. TDD should lead you far away from thinking about using singletons.

Reasons on why it's a bad idea (or can be an ok one) can be found on wikipedia

My answer to your questions is: Look at other patterns! For example UnitOfWork and Strategy, Mediator and try to acheive the same functionality with these patterns and you'll be able to compare the benefits from each one. You'll probably end up with a UnitOfStrategicMediationFacade or something ;-)

Consider posting this questions over at Code Review for more in depth analysis.

When facing that kind of issue, I usually try to reason from a YAGNI/KISS perspective :

  • Do you need MarkAsCancelService, MarkAsExpiredService and the like in the first place ? Wouldn't these operations have a better home in RecurringProfile itself ?

You say these services are byproducts of your TDD process but TDD 1. doesn't mean stripping business entities of all logic and 2. if you do externalize some logic, it doesn't have to go into a Service. If you can't come up with a better name than [BehaviorName]Service for your extracted class, it's often a sign that you should stop and reconsider whether the behavior should really be extracted.

In short, your objects should remain cohesive, which means they shouldn't encapsulate too many responsibilities, but not become anemic either.

  • Assuming these services are justified, do you really need a Facade for them ? If it's only a convenient shortcut for developers, is it worth the additional maintenance (a change in one of the services will generate a change in the facade) ? Wouldn't it be simpler if each consumer of one of the services knows how to leverage that service directly ?

The other question which would follow if the above makes sense is - would you do unit-tests on such methods, considering that they do not have any particular business logic function?

Unit testing boilerplate code can be a real pain indeed. Some will take that pain, others consider it not worthy. Due to the repetitive and predictable nature of such code, one good compromise is to generate your tests automatically, or even better, all your boilerplate code automatically.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top