A while back I had the funny task to obtain users from the AD and do present them in a neatly designed list. Since neatly organized employee lists hold a certain coolness factor, soon other departments grew jealous and wanted peeking their own employees, only with more info available and more neatly organized.
Now nothing holds more fun to the everyday developer than maintaining classes that does the same thing, only in a slightly different way. So I thought the logic can be made reusable, and by employing the magic of generics combined with the template method design pattern, the soon-to-come new departments needing slightly different info for their neatly organized employee lists could be taken care very fast.
So what is a template method and how does it work? Template method is just a fancy name for a method that your base class will call, and you can override its implementation in subclasses. I created a sample project and pushed it to GitHub, so let’s review what’s in there.
The gist of the template method is found in the class ADUserFinderAbstract<T>. Here’s how it’s looks like:
As you see, there’s a method called GetUser which goes into the AD and try to find a user. Then it calls an abstract method in the same class, called convertPrincipal, and passes the found user (or null, to be entirely correct) to this method. You can easily guess what is the point of this whole thing: override the abstract method in a subclass, and provide different implementations depending on various business needs. That’s what is done in the solution.
There are two implementations, one (EmailADUserFinder) simply returns the e-mail address of the user, the other (ComplexADUserFinder) does a lot more work, and tries to load department information, too.
And why go generic? In this particular business case, a generic implementation was more than ideal. I could map to the UserPrincipal object whatever entity I wanted, and do work with that. But template methods doesn’t necessary have to be generic methods of course. It only grants more power in this case.
I hope you’ll find this post useful, don’t forget to check out the GitHub project again!