0

我完全困惑自己试图设计必要的接口和抽象来完成可以自己使用以及组合成聚合的域实体的加载。哇。那是一个满口的流行语。本质上,我有两个对象,我希望它们具有基本类型的“加载”功能,但是当这两个对象合并为一个时,我会遇到多重继承。

所以,我有我的实体,就像这样(我会画

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 都可以(并且正在)从其他实体派生,我想在实现中提供基本功能,以便我遵循 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
    }
}

这适用于单个 Account 和 Document 对象及其派生,但我似乎无法解决的问题是如何处理 AccountDocument ...

public class AccountDocumentRepository : AccountRepositoryBase, DocumentRepositoryBase
{
    //This is not possible, of course, due to multiple inheritance.
}

我知道解决方案不会那么难,但我完全纠结,无法理清如何只提供一次基本的“加载”功能。请帮忙!

提前致谢。

4

3 回答 3

2

您可以通过使用组合而不是实现继承来解决这个问题 - 只需让AccountDocumentRepository委托给您已经编写的存储库类:

public class AccountDocumentRepository : IAccountDocumentRepository
{
    IAccountRepository accountRepository = new AccountRepositoryBase();
    IDocumentRepository documentRepository  = new DocumentRepositoryBase();

    public AccountDocument Load(IDataContext context) {
        Document document = this.documentRepository.Load(context);
        Account  account  = this.accountRepository.Load(context);
        return new AccountDocument(account, document);
    }
}

如果您希望灵活地替换不同的具体存储库,您可以提供一个构造函数或属性,让客户端代码注入IAccountRepositoryand IDocumentRepository.

有几个很好的 StackOverflow 问题讨论了实现继承和组合的相对优点,并解释了为什么我们应该强烈推荐组合。这些只是搜索“组合继承”的一小部分结果。

于 2009-09-29T16:23:25.653 回答
1

你不想AccountDocumentRepository实现IAccountDocumentRepository,而不是继承自AccountRepositoryBaseandDocumentRepositoryBase吗?

然后,您可以随时将AccountRepositoryBaseDocumentRepositoryBase属性添加到IAccountDocumentRepository接口,或将它们添加到构造函数中,AccountDocumentRepository以确保您拥有两者的实例来完成工作。

public class AccountDocumentRepository : IAccountDocumentRepository
{
    public AccountDocumentRepository(AccountRepositoryBase account, DocumentRepositoryBase document)
    {
        this.account = account;
        this.document = document;
    }

    public AccountDocument Load(IDataContext context)
    {
        //use your account & document instances here to create an AccountDocument.
    }

}
于 2009-09-29T16:23:11.113 回答
0

您可能想查看企业应用程序架构模式一书中的继承映射器模式

然后基于它制作自己的继承存储库模式。

看:

  • 单表继承(278),
  • 类表继承(285),
  • 具体表继承(293),
  • 继承映射器 (302)。

http://martinfowler.com/eaaCatalog/

于 2010-01-24T08:38:38.670 回答