在域驱动设计中缓存代码位置

发布于 2024-08-16 21:53:12 字数 222 浏览 3 评论 0原文

在遵循域驱动设计的应用程序中,您具有以下类型的概念:

  1. 处理数据库访问的存储库;
  2. 协调实体和值对象等之间交互的应用程序服务。

通常,您会将缓存代码放在其中消除对数据库的昂贵调用?

我见过代码库只是到处缓存,很难监控内存使用情况,也很难为其他开发人员提供指导。

请理解,我知道您应该只在需要时缓存数据,我只是问一个一般性问题。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

星星的轨迹 2024-08-23 21:53:12

抽象存储库的美妙之处在于,您可以使用装饰器模式来实现此类横切关注点作为缓存。

例如,给定一个 IMyRepository 接口,您可以像下面的伪代码一样创建一个 MyCachingRepository:

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;
    }
}

在此示例中,GetFoo 由 IMyRepository 定义。请注意,仅当缓存未找到该项目时才调用装饰存储库。

这遵循单一责任原则,因为真正的缓存实现可以集中于检索和保存数据,而缓存装饰器可以专注于缓存。这使您可以彼此独立地改变两者。

在我们当前的项目中,我们使用了这种方法,更棒的是我们可以事后才这样做,甚至不需要触及原始存储库。这符合开放/封闭原则的精神。

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.

你列表最软的妹 2024-08-23 21:53:12

我会把它放入存储库中。存储库应该由合同定义,并且缓存的使用应该隐藏在该合同后面,因此对于存储库的使用者来说是透明的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文