最近我一直在阅读SOLID原则,决定看一下我所使用的代码库如何比较。我们的某些代码中有一个存储库(repository A)。当从存储库A删除记录时,我们还需要从存储库B中删除相关记录。原始编码者因此创建了对存储库B的具体实现的依赖。存储库A中的方法在事务内,并删除来自存储库A的记录,然后调用存储库B上的方法以删除关联数据。我对S原则的理解是每个对象应该只有一个变化的原因,但是对于我的存储库A来说,它有两个变化的原因吗?或者我完全错了?
代码库应该具有单一职责 - 持久化一种实体,例如员工。如果您必须从其他存储库中删除某些关联记录,则它看起来像业务逻辑。
当雇员被解雇时,我们应该删除他的工作日志。
通常业务逻辑的地方是领域服务。此服务将拥有两个存储库并完成所有工作:
staffService.Fire(employee)
实现将会看起来像这样
public class StaffService
{
private IEmployeeRepository employeeRepository;
private IWorkLogRepository workLogRepository;
private IUnitOfWorkFactory uowFactory;
// inject dependencies
public void Fire(Employee employee)
{
using(var uow = uowFactory.SartNew())
{
workLogRepository.DeleteByEmployee(employee.Id);
employeeRepository.Delete(employee.Id);
uow.Commit();
}
}
}
因此,基本建议:
您可能会想知道,如果您有一个员工对象,而它有一些嵌套对象存储在不同的数据库表中,该怎么办。如果您与员工分开使用该对象,则一切如上所述-您应该有单独的存储库和一些其他对象(服务),它们操作两个存储库。但是,如果您不与员工分开使用该嵌套对象,则员工是聚合根,您应该只有一个员工存储库,该存储库将查询两个表内的内容。
class RepositoryA {
private final Factory factory;
public RepositoryA(Factory factory) {
this.factory = factory;
}
public ClassA GetById(string id) {
ClassB objB = factory.GetObjBById(id);
return factory.CreateObjA(id, objB);
}
}
class Factory {
public ClassB GetObjBById(string id) {
// ...
}
public ClassA CreateObjA(string id, ClassB objB) {
// ...
}
}
dispatch repositoryA.deleted(RecordA)
这将保存已删除记录的信息。
然后,一个事件监听器将订阅此类事件,并且作为依赖项具有存储库B,然后调用删除操作。
让我们使用B作为实体名称,监听器声明应该如下所示:
Listen RepositoryA.delete and invoke onDelete(Event)
通过这种方法,您已经实现了repoA和repoB之间的松耦合(强制执行开放/关闭原则-在关闭方面),因此repoA现在又有了。
敬礼。
employee.fire() -> EmployeeFired(employeedId) -> EventSubscriber -> ...
. - plalxclass RepositoryA { public ClassA GetById(string id) { objB = repositoryB.GetById(idB); factory.CreateObjA(idA, objB); } }
如何处理以避免仓库之间的引用? - Jonathan