Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching Code Location in a Domain Driven Design

In an application that has followed a Domain Driven Design where you have the following sorts of concepts

  1. A repository that deals with the DataBase access
  2. A application service that co-ordinates interactions between enties and value objects etc.

where in general would you put caching code to elimenate an expensive call to the database?

I have seen code bases that just cache all over the place and it is difficult to monitor memory usage and difficult to provide guidelines to other developers.

Please understand that I know you should only cache data when you need to, I am just asking a general question.

like image 688
DownChapel Avatar asked Jan 08 '10 15:01

DownChapel


2 Answers

The wonderful thing about abstract Repositories is that you can use the Decorator pattern to implement such cross-cutting concerns as caching.

As an example, given an IMyRepository interface, you can create a MyCachingRepository like this pseudo code:

public class MyCachingRepository : IMyRepository
{
    private readonly IMyRepository repository;

    public MyCachingRepository(IMyRepository repository)
    {
        if(repository == null)
        {
            throw new ArgumentNullException("repository");
        }

        this.repository = repository;
    }

    public Foo SelectFoo(int id)
    {    
        Foo foo = ... // attempt to get foo from cache

        if // foo is not it cache
        {
            foo = this.repository.SelectFoo(id);
            // save foo in cache
        }
        return foo;
    }
}

In this example, GetFoo is defined by IMyRepository. Notice how the decorated Repository is only invoked if the item isn't found by the cache.

This follows the Single Resposibility Principle because the real caching implementation can concentrate on retrieving and saving data, whereas the caching Decorator can concentrate on caching. This lets you vary the two independently of each other.

In our current project we used this approach, and what is extra nice is that we could do it as an afterthought without even touching the original Repositories. This is in spirit of the Open/Closed Principle.

like image 50
Mark Seemann Avatar answered Nov 15 '22 12:11

Mark Seemann


I'd put it into the repositories. The repositories should be defined by a contract, and the usage of a cache should be hidden behind that contract, so it's transparent for the consumer of the repository.

like image 38
cwap Avatar answered Nov 15 '22 12:11

cwap