domain-driven-design - 域驱动设计缓存位置

标签 domain-driven-design

我有以下伪代码

    public class ClientService
    {
        private readonly IClientsRepository clientsRepository;
        private readonly IClientsCache clientsCache;

        public ClientService(IClientsRepository clientsRepository,
                                IClientsCache clientsCache)
        {
            this.clientsRepository = clientsRepository;
            this.clientsCache = clientsCache;
            this.clientsRepository.OnClientCreated += OnNewClient;       
        }

        public IList<ClientDto> GetAllClients()
        {
            var result = clientsCache.GetClients();
            if (result == null)
            {
                result = clientsRepository.GetClients();
                for (int i = 0; i < result.Count; i++)
                {
                    clientsCache.AddClient(result[i]);
                }
            }

            return mapped clients...
        }

        public void AddClient(Clients newClient)
        {
            clientsRepository.Insert(newClient);
        }

        private void OnNewClient(Clients newClient )
        {
            clientsCache.AddClient(newClient);
        }
    }

    public interface IClientsRepository
    {
        event ClientCreated OnClientCreated;

        IList<Client> GetClients();

        void Insert(ClientsCache client);
    }

    public class ClientsRepository : IClientsRepository
    {
        public event ClientCreated OnClientCreated;

        public IList<Client> GetClients()
        {
            Get clients from database...
        }

        public void Insert(ClientsCache client)
        {
            //code to save to database...
            OnClientCreated?.Invoke(client);
        }
    }

    public interface IClientsCache
    {
        IList<Client> GetClients();

        UpdateClients(IList<Client> clients);

        AddClient(Client client);

        DeleteClient(Client client)
    }

    public class ClientsCache : IClientsCache
    {
        private readonly List<Clients> clientsCache;

        public ClientsCache()
        {
            clientsCache = new List<Clients>();
        }

        public IList<Client> GetClients()
        {
            return clientsCache;
        }

        public void UpdateClients(IList<Client> clients)
        {
            clientsCache = clients;
        }

        public void AddClient(Client client)
        {
            clients.add(client);
        }

        public void DeleteClient(Client client)
        {
            clients.remove(client);
        }
    }

如您所见,有一个存储库可以从数据库中获取客户端。问题是我不想每次需要所有客户端时都去数据库,所以我缓存了它们。 我对此有几个问题:

  1. 缓存是否进入基础设施层?
  2. 我需要另一个存储库来从缓存中获取客户端吗?或者最好使用从缓存中获取客户端的服务。
  3. 如果我创建一个新客户端,我需要将他添加到数据库中,然后也将其添加到缓存中。我是否需要其他服务来实现此目的?

最佳答案

<强>1。缓存

通常它应该留在基础设施层。在这里,您可以“调整”您正在阅读的内容,并根据 UI 需要加快阅读速度。因此,您可以在不弄乱域的情况下执行此操作。因此,作为与域无关但与基础设施无关的存储库的实现,......

<强>2。存储库

...另一个存储库是个不错的选择(在这里您在 CQRS 区域中滑倒了)。因此,您可以选择更适合读取(缓存)和写入(使用 JPA 进行抽象)的内容。
但是,那么,您真的需要一个用于读取的存储库吗?当读取与写入分离,并且您使用两个存储库时,直接访问缓存的服务也是一种解决方案。最后,您仅在域中使用存储库,当您离开它(读取)时,您可以使用任何您想要的东西来满足您的需要。然后可以完美地支持该服务以满足 UI 的需求(或您需要列表的地方)。

<强>3。缓存处理

Id 取决于您处理缓存的方式。如果只是通过在请求上添加缓存来完成(列表是通过 ajax 请求加载的,可以缓存),那么它的超时就足够了,你什么都不用做。
另一方面,如果您以另一种方式缓存(每个新客户端都会更新的列表),那么您需要一个服务来响应 ClientCreated 事件并更新缓存。
第二种选择还需要处理其他事件,如 ClientDeleted 等。

CQRS 链接:

https://en.wikipedia.org/wiki/Command%E2%80%93query_separation#Command_query_responsibility_segregation

https://www.slideshare.net/Codemotion/ddd-cqrs-latif?next_slideshow=1

http://cqrs.nu/

https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92

https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf

http://www.h-online.com/developer/features/CQRS-an-architecture-precept-based-on-segregation-of-commands-and-queries-1803276.html

关于domain-driven-design - 域驱动设计缓存位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45797375/

相关文章:

architecture - 有界上下文/聚合的物理组织

c# - 域驱动设计中 IoC Autowiring 的选项

java - 从域模型中检索集合中的项目的最佳做法是什么?

domain-driven-design - 如何使用从其他有界上下文接收的数据创建域实体?

java - DDD : How to hide specific aggregate root constructors from integration layers in Kotlin

c# - 关于我们在具有多个客户端的分布式应用程序中进行验证的方法的思考

domain-driven-design - DDD 领域实体与持久化实体

mongodb - DDD 和 MongoDB : Is it okay to let Mongo create ObjectIDs?

c# - 如何选择DDD聚合?

java - 用领域驱动设计实现分页和排序