Creating loosely coupled code with the REPOSITORY pattern

Recently, I finished reading the excellent book by Eric Evans on Domain-Driven Design: Domain-Driven Design: Tackling Complexity in the Heart of Software

One of the takeaways from that book which I’ve seen used in one of my past jobs is the REPOSITORY pattern. According to the author, “A REPOSITORY represents all objects of a certain type as a conceptual set (usually emulated). It acts like a collection, except with more elaborate querying capability” (Evans 2004)

REPOSITORY pattern diagram

So how we we get loosely coupled code using the REPOSITORY pattern? Let’s use an example to illustrate this. Imagine that you are building a software for Real Estate firms. As a broker of a Real Estate firm, I want to see the total list of property sales for a particular agent. The broker will be the client sending a request to the SalesRepository. The search criteria can be a simple method call like getByAgentId(agentId).

getByAgentId(agentId) is one of the public API of the SalesRepository. So it knows what to do next, which is to use the agentId as a part of a query to get the right data from the data source.

As a result, the client is decoupled from the specific data source. The client has no idea what the data source is nor does it care about that. The data source could be a relational database like SQL Server or a document-oriented database like MongoDB. All the client needs to know is the public API needed to get the resource that it wants.

One benefit is that we can easily write unit tests for the client where instead of actually hitting our data source, we can create a canned response imitating a real response from the SalesRespository. This way, we can actually develop the client in parallel with SalesRepository.

Another benefit is that in case the data source changes in the future, let’s say from SQL Server to MongoDB, only the SalesRespository has to be altered in order to meet the new query needs of the new database. The client is protected from change as long as the public API of the SalesRespository does not change.

In summary, loosely coupled code is good because it allows for more flexibility. REPOSITORY pattern acts as a protective layer between the client and the data source which allows the client to be loosely coupled instead of tightly coupled with the implementation of the data fetching code.

Written on September 25, 2021