我有以下伪代码
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。缓存
通常它应该留在基础设施层。在这里,您可以“调整”您正在阅读的内容,并根据 UI 需要加快阅读速度。因此,您可以在不弄乱域的情况下执行此操作。因此,作为与域无关但与基础设施无关的存储库的实现,......
<强>2。存储库
...另一个存储库是个不错的选择(在这里您在 CQRS 区域中滑倒了)。因此,您可以选择更适合读取(缓存)和写入(使用 JPA 进行抽象)的内容。
但是,那么,您真的需要一个用于读取的存储库吗?当读取与写入分离,并且您使用两个存储库时,直接访问缓存的服务也是一种解决方案。最后,您仅在域中使用存储库,当您离开它(读取)时,您可以使用任何您想要的东西来满足您的需要。然后可以完美地支持该服务以满足 UI 的需求(或您需要列表的地方)。
<强>3。缓存处理
Id 取决于您处理缓存的方式。如果只是通过在请求上添加缓存来完成(列表是通过 ajax 请求加载的,可以缓存),那么它的超时就足够了,你什么都不用做。
另一方面,如果您以另一种方式缓存(每个新客户端都会更新的列表),那么您需要一个服务来响应 ClientCreated 事件并更新缓存。
第二种选择还需要处理其他事件,如 ClientDeleted 等。
CQRS 链接:
https://www.slideshare.net/Codemotion/ddd-cqrs-latif?next_slideshow=1
https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92
关于domain-driven-design - 域驱动设计缓存位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45797375/