4

最近,我一直在努力弄清楚我的架构中的某些方法、功能是否合适;在正确的层。我想按照Martin Fowler 的存储库模式将我的服务层与数据库分离。

Martin Fowler 在他的网站上解释的定义说:

存储库在域和数据映射层之间进行调解,就像内存中的域对象集合一样。

问题是我有很多要求,例如所有发票的总和。如您所知,所有发票的总和是一个标量值。如果我遵循 Martin Fowler 的定义,我应该做的是创建一个函数,该函数从我的存储库层返回域对象列表,该列表由服务层接收,该服务层循环抛出对象以计算总数。也有可能我不明白这种模式意味着什么的本质......

我知道在设计应用程序时性能不应该是一个问题,因为可维护性更好,但在这种情况下,在我看来,不在存储库层中创建一个返回十进制值的函数完全浪费了开发和性能时间对应于发票总数,并从服务层返回相同的值。即使您可以使用 ORM 添加一些延迟加载策略,实现对象列表然后仅使用单个属性也是一种过度杀伤力。

从存储库层返回标量值是否正确,还是我应该抵制诱惑并始终从该层返回域对象并处理服务层中的所有业务逻辑?

我也有很多地方,我的演示者直接调用我的存储库,而不是调用服务层,然后再调用存储库层。它是正确的; 可以在服务层之外调用此存储库模式吗?

请注意,我不想从我的存储库层返回 IQueryable 结果,因为这将与Demeter 法则完全矛盾。

另外,我不想直接在我的服务层中设置查询,因为我希望能够对这一层进行完全的单元测试;不做集成测试。

4

2 回答 2

2

这个问题很容易用 CQRS(作为一个概念)解决。有一个专门用于查询的存储库,可供 UI 使用(或在使用 MVC 时由控制器使用)。该 repo 可以直接查询 db(它并不重要的 ORM 实体)并返回您需要的内容。

仅在更新模型时保留“重”域对象和相应的存储库。

于 2012-04-24T15:12:54.873 回答
1

I had similar issues and I ended up having a base and derived repository interfaces. The base would have standard methods: Fetch, Update, etc. while the derived interface would have specific methods (get the scalar value, in your case).

public interface IRepository { ... }

and

public interface IInvoiceRepository : IRepository 
{ 
  int GetTotal(); 
}

You then create an InvoiceRepository class which implements the interface. Is better to implement the business logic in a separate class, say InvoiceBusinessObject which gets a dependency injection of type IInvoiceRepository (use a parameter in the constructor). Never use the implementation in your business layer.

public class InvoiceBusinessObject
{
  private IInvoiceRepository rep;

  public InvoiceBusinessObject(IInvoiceRepository rep)
  {
    this.rep = rep;
  }

  public int GetTotal()
  {
    return rep.GetTotal();
  }
}

The service layer can instantiate the InvoiceRepository class and inject the instance into the business object class:

public int GetTotalFromService()
{
  IInvoiceRepository rep = new InvoiceRepository();
  InvoiceBusinessObject bizObj = new InvoiceBusinessObject(rep);
  return bizObj.GetTotal();
}
于 2012-04-24T06:05:01.517 回答