I have long considered the repository pattern to be a foundational design pattern for database connected systems. Recently, however, I’ve started to reconsider this opinion. Read on to find out why.

Remember that design patterns are found by capturing established good practice - they don’t fall fully formed from the brow of a fevered architect.

The Repository design pattern was formulated at a time when writing database connected systems involved a lot of difficult and repetitive coding. Connection strings, authentication and connection management. SQL query generation through string concatenation, commands, queries, recordsets and parameters - there was a lot of code to write.

Isolating all of that complexity behind the wall of a convenient interface, keeping the complexity of database access away from any actual business logic made a lot of sense.

Smart developers have always been productively lazy - given the chance to write the same thing a dozen times, most all will find a way to simplify things through good design and reuse. Early attempts at code reuse within data access layers led to a number of different approaches. Some of these were very simple, some were complex and mature (1) and, I’m sure, some were unmitigated disasters.

(1) Back in 1997 I was working with a mature library known simply as “Mocom Data Access” (or MDA). Even then, it was mature, cross platform, performant and robust. Bypassing the MDA with hand generated SQL was seldom necessary, but could be done easily when required. It had some features (such as the ability to tell if an association had been loaded) that modern ORMs, with their devotion to POCO objects, can’t easily achieve.

Enter the modern Object Relational Mapper, or ORM.

For new projects we start in 2011, we can drop in any one of a large number of mature ORM libraries. These libraries take care of our connection strings, authentication and connection management. They handle SQL query generation, creating command objects and parameters for our queries and transforming recordsets returned from the database into our domain objects.

Hang on, doesn’t that description seem somewhat familiar?

Modern object relational mappers take care of wrapping up (almost) all the complexity that we originally wrapped up by creating repositories.

Doesn’t this mean that the ORM could, in effect, be our repository? Why should we wrap up the ORM and incur the cost of creating and maintaining another abstraction layer if the ORM is already doing this job for us?

There’s a broader lesson here too. The abstractions we employ in our applications have to deliver significant value, else the overhead of defining and maintaining them ends up as a net-negative for our project. Every abstraction we employ needs to pass this threshold of viability - any abstraction whose costs exceed the benefits is hampering our work, not benefiting it.

Next Post
Invalid Build Configuration: Debug|BNB  14 May 2011
Prior Post
Performance Monitoring for Visual Studio  07 May 2011
Related Posts
Browsers and WSL  31 Mar 2024
Factory methods and functions  05 Mar 2023
Using Constructors  27 Feb 2023
An Inconvenient API  18 Feb 2023
Method Archetypes  11 Sep 2022
A bash puzzle, solved  02 Jul 2022
A bash puzzle  25 Jun 2022
Improve your troubleshooting by aggregating errors  11 Jun 2022
Improve your troubleshooting by wrapping errors  28 May 2022
Keep your promises  14 May 2022
Archives
May 2011
2011