Martin Fowler writes:
"A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers."
Of all the design patterns I have tried to use at work I like the repository pattern the best, perhaps because I had the chance to work on an application that used the repository pattern for a recent work project.
The project I was working on was an typical of those may of us face on a day to day basis. A former colleague had done some work on a WPF-based scripting engine prototype that was to be used in a phone survey project that project tanked, but it was thought that the scripting prototype would be useful in a big compliance project I was leading. The original developer was no longer available, so it was up to me to re-factor the code for the new project.
I faced of number interesting challenges on this project. One was that I had to wrap the engine in a COM+ wrapper for use by an older VB6 type project. Ugly (I hate COM), but pretty straight forward.
Another issue was that the engine was done using WPF and my WPF experience is (was) minimal at best. I had hoped that I could just use what had already been done, but while re-factoring I found out that the WPF part of the prototype was not as complete as I had hoped, so I had an interesting hack and slash session with the WPF code, changing it to be more robust and functional. This was an interesting journey in and of itself that I'll write about later.
The next issue I encountered (and the one this post is about) is that the original project's CRUD stored script responses in a snow-flake scheme SQL database that at the time was thought best for the survey project the engine was originally designed for. I found that the original scheme was over-kill for what I needed, so I designed a straight three table relational scheme to hold the script responses that I thought much handier for what I needed for this project.
Fortunately for me the original developer on the project had the foresight to use a repository pattern for the project (he used other patterns as well, but more on that later), implemented using interfaces. Its use made it very easy for me to replace the original CRUD class, with one of my own. All I had to do was write my class, implementing the existing interfaces and about 5 minutes later I was done. In my implementation I used LINQ to SQL, someone else could come in behind me and use Entity Framework & SQL, another could use ADO.NET or someone could write a class that implements an Oracle back end.
This was a great real-world example of a bunch of things that we all hear about, but sometimes don't appreciate until we see it for real. For instance the use of a repository pattern made it much easier for me to replace the snow flake scheme with a better one. The big lesson I took out of this is that the use of design patterns allows developers to develop in a much more disciplined and thus more maintainable way.