域实体(可以是单独的或组合的)的继承/设计问题
我完全困惑于尝试设计必要的接口和抽象来完成域实体的加载,这些域实体可以由它们自己使用,也可以组合成一个聚合。哇。那是一个满口的流行语。本质上,我有两个对象,我希望它们具有基类型“加载”功能,但是当这两个对象合并为一个时,我遇到了多重继承。
所以,我有我的实体,就像这样(我画了
public class Account
public class Document
public class AccountDocument
{
public Account Account{get;set;}
public Document Document{get;set;}
}
然后,我有接口,像这样:
public interface IAccountRepository
{
Account Load(IDataContext context);
}
public interface IDocumentRepository
{
Document Load(IDataContext context);
}
public interface IAccountDocumentRepository
{
AccountDocument Load(IDataContext context);
}
由于帐户和文档都可以(并且正在)从其他实体派生,我想在 这对于单个 Account 和 Document 对象及其派生来说
public abstract class AccountRepositoryBase : IAccountRepository
{
Account Load(IDataContext context)
{
//implementation for loading the Account from the context
}
}
public abstract class DocumentRepositoryBase : IDocumentRepository
{
Document Load(IDataContext context)
{
//implementation for loading the Document from the context
}
}
效果很好,但我似乎无法解决的问题是如何处理 AccountDocument...
public class AccountDocumentRepository : AccountRepositoryBase, DocumentRepositoryBase
{
//This is not possible, of course, due to multiple inheritance.
}
我知道解决方案不能很难,但我完全困惑,无法理清如何仅提供一次基本“加载”功能。请
提前致谢!
I have completely confused myself trying to design the necessary interfaces and abstracts to accomplish loading of domain entities that can be used by themselves as well as combined into an aggregate. Wow. That was a buzzword mouthful. Essentially, I have two objects that I would like to have base-type "load" functionality, but when these two objects are combined into one, I run into multiple inheritance.
So, I have my entities, which are like this (I'd draw
public class Account
public class Document
public class AccountDocument
{
public Account Account{get;set;}
public Document Document{get;set;}
}
Then, I have interfaces, like this:
public interface IAccountRepository
{
Account Load(IDataContext context);
}
public interface IDocumentRepository
{
Document Load(IDataContext context);
}
public interface IAccountDocumentRepository
{
AccountDocument Load(IDataContext context);
}
Since both Account and Document can (and are) being derived from for other entities, I want to provide base functionality in the implementation so that I follow DRY.
public abstract class AccountRepositoryBase : IAccountRepository
{
Account Load(IDataContext context)
{
//implementation for loading the Account from the context
}
}
public abstract class DocumentRepositoryBase : IDocumentRepository
{
Document Load(IDataContext context)
{
//implementation for loading the Document from the context
}
}
This works fine for the individual Account and Document objects and their derivations, but the problem I can't seem to wrap my head around is how to handle the AccountDocument...
public class AccountDocumentRepository : AccountRepositoryBase, DocumentRepositoryBase
{
//This is not possible, of course, due to multiple inheritance.
}
I know the solution can't be that hard, but I am completely tangled up and can't straighten out how I can provide the base "Load" functionality only once. Please help!
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以通过使用组合而不是实现继承来解决此问题 - 只需让
AccountDocumentRepository
委托给您已经编写的存储库类:如果您希望灵活地替换不同的具体存储库,您可以提供一个构造函数或允许客户端代码注入
IAccountRepository
和IDocumentRepository
的属性。StackOverflow 有几个很棒的问题讨论了实现继承和组合的相对优点,并解释了为什么我们应该强烈推荐组合。这些只是搜索“组合继承”的一小部分结果。
You can solve this by using composition instead of implementation inheritance - just let
AccountDocumentRepository
delegate to the the repository classes you've already written:If you want the flexibility to substitute different concrete repositories, you can provide a constructor or properties that lets client code inject the
IAccountRepository
andIDocumentRepository
.There are several great StackOverflow questions that discuss the relative merits of implementation inheritance and composition and explain why we should strongly prefer composition. These are just a small selection of results from searching on "composition inheritance".
您是否不想让
AccountDocumentRepository
实现IAccountDocumentRepository
,而不是从AccountRepositoryBase
和DocumentRepositoryBase
继承?然后,您可以随时将
AccountRepositoryBase
和DocumentRepositoryBase
属性添加到IAccountDocumentRepository
接口,或将它们添加到AccountDocumentRepository
的构造函数中以确保您有两者的实例来完成工作。Wouldn't you want
AccountDocumentRepository
to implementIAccountDocumentRepository
, and not inherit fromAccountRepositoryBase
andDocumentRepositoryBase
?Then you can always add
AccountRepositoryBase
andDocumentRepositoryBase
properties to theIAccountDocumentRepository
interface, or add them to the constructor ofAccountDocumentRepository
to ensure you have instances of both to do the work.您可能想查看《企业应用程序架构模式》一书中的继承映射器模式。
然后基于它创建您自己的继承存储库模式。
请参阅:
http://martinfowler.com/eaaCatalog/
You might want to look into the Inheritance Mapper Pattern from the Patterns Of Enterprise Application Architecture book.
and then make your own kind of Inheritance Repository Pattern based on it.
See:
http://martinfowler.com/eaaCatalog/