从模板的泛型类派生的类,一些属性

时间:2017-02-03 14:48:48

标签: c# domain-driven-design

在我的项目中,我尝试使用DAO中的单独域模型,例如来自https://vaughnvernon.co/?p=879的示例。我使用的是我的域对象的后端状态的类,它是内部的,只在存储库中使用。接下来我有我的域对象,我想通用一些逻辑来使用它。有一个代码:

public abstract class GenericEntity<T> where T : class
{
    protected readonly T _state;

    internal GenericEntity(T state)
    {
        _state = state;
    }

    internal T State
    {
        get
        {
            return _state;
        }
    }
}

我希望从这个类派生,但我的域模型应该是公共的,我不能做内部DAOEntity的原因。

public class DomainModel : GenericEntity<DAOEntity>
{

}

internal class DAOEntity
{

}

这是一些走动吗?或者我需要实现此代码来管理我所有类中的状态。我不想要制作一些基础DAOEntity因为我需要在所有域模型中投射它。

编辑: 也许你不明白我的问题。现在我的代码看起来像Marcos Jonatan Suriani的回答:

public class Product 
{
  public Product()
  {
    State = new ProductState();
  }

  internal Product(ProductState state)
  {
    State = state;
  }
}

public class ProductState
{

}

public class AgilePMContext : DbContext
{
  public DbSet<ProductState> Products { get; set; }
}

但是我正在寻找一些设计模式,我可以用我的内部状态实现减少复制粘贴代码,所以我想去解决这个解决方案,因为当我有很多域模型这是一个代码,我需要重温。

2 个答案:

答案 0 :(得分:0)

本文的目的略有不同。该模式的主要目的是专注于Domain Core并避免使用变通方法,特别是在将域对象映射到关系时(ORM,用于ie)。

  

采用这种方法将有助于我们专注于真正的目标   最重要的,我们的核心领域和无所不在的语言。

方法是通过提供状态对象来使域无处不在 - 这将由ORM(EF)使用。因此,业务规则保留在Domain对象上,ORM与State对象相关。

  

一种方法使用带有实现类的Separated Interface,另一种方法使用由状态对象支持的域对象。

您的实现应该由代表域的接口(例如 IProduct )组成:

  

我们创建了一个我们希望客户端看到的接口,并将实现细节隐藏在实现类中。

还由两个接口实现组成;一个用于Domain对象( Product ),另一个用于state对象( ProductState )。域实现应该有两个构造函数:

  

普通客户端的公共业务构造函数和仅由内部实现组件使用的第二个内部构造函数。

interface IProduct
{
}

public class Product : IProduct
{
  public Product()
  {
    State = new ProductState();
  }

  internal Product(ProductState state)
  {
    State = state;
  }
}

public class ProductState: IProduct
{

}

public class AgilePMContext : DbContext
{
  public DbSet<ProductState> Products { get; set; }
}

答案 1 :(得分:0)

public class DomainModel : GenericEntity<DAOEntity>
{

}

这是倒退 - 您编写了一个依赖于数据模型的域模型。您希望此依赖关系反过来:数据模型应该依赖于域模型。

从某种意义上说,Vaughn告诉你的是域模型定义了数据服务提供者的接口,数据模型实现了这些提供者。

例如,考虑一个简化的银行业务模式

class DepositModel : BankingApi.Deposit {
    void depositFunds(Account account, Deposit deposit, Clock clock) {

        AccountId currentAccount = account.id();
        AccountId depositInto = deposit.accountId();

        assert depositInto.equals(currentAccount);

        Money amount = deposit.amount();
        account.deposit(amount);

        Time processedAt = clock.now();
        TransactionId transactionId = deposit.transactionId();

        account.updateTransactionHistory(transactionId, processedAt)
    }
}

观察模型不接触原始数据。所有状态操作都被值类型隐藏。

这意味着您的数据模型可以按照您喜欢的方式实现数据结构,并以满足规范的任何方式对其进行操作。