Using objects or repository interface in constructor

I’ve been really trying to use the Single Responsibility Pattern in all of the classes I design. Recently, I needed to create code to query a list of holidays from the database, and then create a method that allows you to get the number of holidays between two given dates.

Here was my first stab at the constructor:

public HolidayCalculator(IEnumerable<DateTime> holidays)

It’s simple and easy to understand. Then I started thinking about some of the dependency injected examples I’ve seen. For example, one of the Spring.NET IoC quickstarts has a similar example, except that they’re trying to list movies. In their example, they use an IMovieFinder interface. That interface has a single method that retrieves a list of movies. Using this concept, my constructor would look like (and what I ultimately changed it to):

public HolidayCalculator(IHolidayRepository holidayRepository)

That example originally seemed unnecessarily complex to me. Why separate something so simple and disconnected into an interface? Well, it turns out there are a couple of good reasons that you might want to do this.

Delay loading

With my original constructor, I had to load all of the holidays from the repository (ultimately a database in the production environment) to even create an instance of this class. This is certainly less than ideal when I want to use this class as a singleton that may get created early in the application.

Single Responsibility

In my original design, I was accepting in a list that would get cached in my holiday calculator. My class now has two responsibilities. It has to calculate holidays, and it has to cache the holiday list. What if I wanted to change how the list was cached? I would have to change the class, which is not ideal.

Holiday-Calculator-Design

Ideally, this class would load the holiday list each time it needs to perform a calculation. The implementation passed into the constructor would be responsible for caching. In fact, we can now easily separate out the caching feature, and the holiday loading feature. Both classes would implement the IHolidayRepository interface and would be chained together. The caching class would take an IHolidayRepository.

Incremental Coding

Following the Agile philosophy, I can now deliver code faster. I don’t need to add a caching layer. I can have a working application in less time, and then later evaluate if I need to cache the holiday data.

Conclusion

Overall, this design is a little more work, but I think the benefits outweigh the extra classes and interface I needed to create. This design makes it easy to test, and each class has almost no code in it. Reading it and understanding it is extremely simple.

Kick It!

3 Comments so far »

  1. Greg Beech said,

    Wrote on July 25, 2008 @ 1:54 am

    It seems to me that depending on whether you take a set of values or a repository, you’ll have classes with quite different semantics.

    The first example that takes a sequence of holiday dates would be a stateful class that is used to perform multiple calculations on a set of data which requires the data to be consistent between the calculations, and then the instance would be discarded. The second example that takes a repository would be a stateless class that performs a single calculation on a set of data that is retrieved each time.

    So which one you choose would depend on whether you need to perform multiple calculations that share a consistent data set. You might even combine both approaches and have a stateless service which retrieves data from the repository and then constructs a stateful class for the duration of the method call using the list of dates, to perform a number of calculations that need consistent data.

  2. beefarino said,

    Wrote on July 25, 2008 @ 9:19 am

    Nice post, very succinct example of the problem and benefits you get from the extra effort.

    I’ve gone back and forth on this one, sometimes preferring the simplicity of an available collection and other times wanting all the benefits you get with a strategy pattern.

    The compromise I find myself using these days is to have ctors that accept the “most minimal” interface required so the class can to its job (IEnumerable in your example), and then ensure that interface is available on the repository, usually via direct implementation but sometimes using an adapter. I find this doesn’t really add any measurable work, keeps the objects simple, seperated, and testable, and fits extremely well with IoC frameworks.

  3. Weekly Links #11 | GrantPalin.com said,

    Wrote on July 28, 2008 @ 10:27 am

    [...] Using objects or repository interface in constructor A brief and tidy example of dependency injection. [...]

Comment RSS · TrackBack URI

Leave a Comment

Name: (Required)

E-mail: (Required)

Website:

Comment: