【问题标题】:How should I structure my domain model我应该如何构建我的域模型
【发布时间】:2012-07-27 20:53:49
【问题描述】:

我尝试将我的特定域问题抽象为银行账户,假设以下情况:

  • 我有某个客户的银行登录信息。
  • 每个客户可以拥有多个属于同一登录名的银行账户。
  • 每个银行账户可以有数千笔交易。

我将类结构设计如下(简化):

public class Login
{
    private List<Account> _bankingAccounts;
    ....more fields, ctor, getters, setters...
}

public class Account
{
   private List<Transaction> _transactions;
    ....more fields, ctor, getters, setters...
}

public class Transaction
{
   String _comment;
    ....more fields, ctor, getters, setters...
}

好吧,但是如果我有 20 个帐户,每个帐户有 10000 个事务,并且我从数据库加载整个模型,则会有大量内存,即使我不知道客户是否需要所有这些事务。

我想像这样构建一个更简化的模型:

public class Login
{
    private List<SimpleAccount> _bankingAccounts;
    ....more fields, ctor, getters, setters...
}

public class SimpleAccount
{
    ....more fields, ctor, getters, setters...
}

public class Account
{
   private List<Transaction> _transactions;
    ....more fields, ctor, getters, setters...
}

public class Transaction
{
   String _comment;
    ....more fields, ctor, getters, setters...
}

然后我将加载一个带有简化帐户的帐户模型(其中不包含所有交易),并且只有在用户请求查看特定帐户的交易时,我才会加载这个单个完整的帐户对象。

这样可以吗?有更好的方法吗?

【问题讨论】:

  • 对于一长串交易,您可以进行服务器端分页

标签: c# java architecture domain-driven-design domain-model


【解决方案1】:

从您的问题中,我发现您的基本需求是 ORM,因为(如果我没记错的话)您想要两件事
领域模型映射
但是
使用延迟加载
通过延迟加载我们的意思是关系对象仅在我们尝试访问它们时才加载。简单地说,当您想查看您永远不想自动加载学生的所有课程的特定学生数据时(这可能是收藏)除非不想看到他/她的课程(如果学生和课程有关系)。
因此,对于您的问题,您应该使用 ORM,它将为您提供两种解决方案:)
这里是.Net提供的list of some ORM

【讨论】:

    【解决方案2】:

    当您构建 模型时,您不应该考虑性能影响,因为域模型是您的域,而不一定是您实现的。

    此外,如果您使用任何不错的 ORM 框架(例如,),您可以只从数据库加载您需要的数据,而不是整个对象图。

    【讨论】:

      【解决方案3】:

      正如 Serg 所说,性能思想属于实现,而不是领域模型。

      如果你想避免加载整个帐户,你应该实现某种延迟加载,例如:

      public class Account
      {
         private List<Transaction> _transactions;
      
         public List<Transaction> getTransactions() {
              if(_transactions == null) {
                   loadTransactions();
              }
              return _transactions;
         }
      }
      

      【讨论】:

      • 但在这种情况下,我会将 DataAccess 放入域模型中。
      • @john84 使用支持透明(用于域模型)外部加载的 DAL。
      • 您可以通过分离接口和实现来将域模型与数据访问分离,例如Account实现IAccount,或者通过引入ServiceLayer,例如:_transactions = serviceFactory.makeTransactionService().loadTransactions();
      【解决方案4】:

      有一种称为事件溯源的模式听起来可能对您有所帮助。它依赖于事件的存储(在您的情况下,这些是事务)而不是运行总计,因此您可以对数据做更多的事情。

      此模式遇到了您遇到的相同问题。所以这个模式有一个补充,叫做快照。拍摄快照,比如在每个月末拍摄,可以让您及时获取一个时间点并将交易记录加载回最近的快照。快照将在快照点显示帐户的原样(可能是上次快照或帐户开立事件的产物,其中所有交易均已重播)。

      如果您在 Google 上搜索“事件溯源快照”,就会有大量文章讨论这种模式。希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2013-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-27
        • 2021-09-11
        • 1970-01-01
        • 2011-10-02
        • 1970-01-01
        相关资源
        最近更新 更多