我正在考虑如何为一个新项目编写一个存储库。
我喜欢为基本CRUD操作创建这样一个通用存储库的想法:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity不过,我也读到这是违反DDD精神的。因此,作为妥协,我正在考虑创建一个通用存储库,然后再创建一些继承自它的存储库,例如CustomerRepository: Repository等。然而,我找不到任何文档来支持这个想法。
Q1)创建一个基本存储库是一个合理的想法吗?
另外,我试图为每个聚合根创建一个存储库,而不是每个实体创建一个存储库。假设我有两个类,即Order和OrderItem (Order是入侵根目录),那么:
Q2)对于OrderItem的所有数据访问是否合理进入订单存储库(聚合根)?即SELECT * FROM OrderItem WHERE OrderID=@OrderID (翻译为LINQ)。
发布于 2017-08-01 01:01:22
在领域驱动设计中,存储库是应用程序和领域模型之间的边界。它是程序用来访问聚合根的角色接口(它们本身就是角色接口,允许您访问域模型中的特定入口点)。
通常,您希望应用程序和域模型之间的接口尽可能明确,以便可以为每个特定的用例进行优化。
泛型存储库的基本问题是,由于没有关于哪个状态相关的信息,您必须生成所有这些信息。
Udi大汉提供了一个创建存储库的很好的示例,该存储库通知如何使用状态的实现。
也就是说,如果你想在幕后使用一个通用的实现,并且只有当你知道这样做的好处会影响成本时,你才会引入专门的实现.那完全没问题。
Udi的文章还提出了一个有趣的观点:显式接口在代码中更好地描述了正在发生的事情,其中泛型接口更易于学习。
这似乎是很大的麻烦。实际上并非如此,它只不过是打包您已经编写的代码的另一种方式而已。是的,有更多的接口,可能还有更多的类,但是业务逻辑代码的数量是一样的。我一直能够保持这个设计的高性能,但是增加了它的可维护性。我将可维护性度量为熟悉设计的程序员所需的时间和更改的数量。学习能力(?)通常被称为可维护性,但我认为这是另一回事。这个设计可能不那么容易学--这意味着一个给定的程序员要花更长的时间来学习这个设计。我认为,可维护性的增加大大超过了可学习性的提高。
发布于 2017-08-02 08:13:19
( A1)通常不会。考虑一个具体的CustomerRepository。它可以访问SQL数据库、文档数据库、直接内存中的数据等。用它所依赖的数据存储技术(例如MongoCustomerRepository )来命名它可能是有益的。为了抽象出具体的数据访问技术,实现更简单的测试,需要创建一个ICustomerRepository,由具体的CustomerRepository来实现。创建一个IRepository作为一个基本存储库接口,那么就是抽象一个抽象。因此,除了节省几行重复的界面代码之外,它不会有多大的好处,而且可能会使用户感到困惑。
一个类似的想法是构建一个通用的基本存储库,它公开了包含LINQ表达式或另一种查询形式的查询方法。除了抽象抽象之外,这些抽象几乎总是泄漏的,因为不能正确地抽象出具体实现可能使用的查询语言。我们不应该这样做,因为ORM框架和数据库驱动程序的查询功能齐全,而且无论如何都会隐藏在接口后面。
A2)存储接口应该根据业务用例对齐。此外,实体和值对象只能引用同一聚合根和其他聚合根中的对象。这是为了使聚合根能够确保聚合内部业务规则的一致性和正确的验证。因此,如果Order是包含OrderItem值对象的聚合的根,那么直接从存储库返回OrderItems是不合适的。相反,我们应该返回一个Order,它知道如何满足涉及其OrderItems的用例。
https://softwareengineering.stackexchange.com/questions/354852
复制相似问题