首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >域模型中的Setters

域模型中的Setters
EN

Stack Overflow用户
提问于 2010-09-15 18:32:06
回答 2查看 669关注 0票数 2

在DDD上下文中,域模型上的setter是一种代码味道。应该避免它们的原因很简单,因为它们实际上不是域的一部分。其中没有领域专家可以理解的名词,对数据的更改应该通过特定的方法。

示例:

代码语言:javascript
复制
customer.StreetName = ...
customer.City = ...

而这样做的正确方法是拥有一个customer.ChangeAddress方法,它可以发布事件等。至少从我的理解来看,这都是合理的理论,我可以完全理解为什么域模型中的setter并不是真正需要的。

但是:如果域模型上没有setter,那么这些方法就很难测试。

如果我既不能构造一个接受所有参数的大构造函数,也不能做一些反射魔法,我如何让一个Customer实例来运行我的测试呢?我在后端使用NHibernate,所以NHibernate已经做了一些反射魔术来填充这些字段。

但是有一个有10个参数的ctor真的很糟糕..(工厂方法也是如此)。

对此有什么建议吗?

问候大牛

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-09-16 13:41:22

在传统的(非CQRS) DDD中,将所有数据分解为值对象是一个很好的实践,这样您的实体就可以简化为它们的主要功能:维护身份。

在您的示例中,Customer应该引用一个Address ValueObject并拥有一个ChengeAddress方法,该方法应该像下面这样简单:

代码语言:javascript
复制
public void ChangeAddress(Address address)
{
   //Consistency rules are here
   _address = address;
}

尝试将尽可能多的逻辑从实体转移到值对象。它们本质上更易于测试,因为好的值对象很小,而且是不可变的。您可以使用构造函数在给定状态下实例化VO并执行它(通常通过调用返回另一个已转换的VO实例的方法)。

最后但同样重要的是,根据我的经验,我可以说,如果测试域模型需要额外的基础设施(如反射或任何其他工具),那么您就做错了(通过引入不必要的耦合)。

票数 3
EN

Stack Overflow用户

发布于 2010-09-15 22:41:05

你可能想试试AutoFixture

混合一点反映,爱情和领域变得非常容易测试:

代码语言:javascript
复制
namespace Unit{
  using System;
  using System.Linq.Expressions;
  public static class ObjectExtensions{
    public static T Set<T,TProp>(this T o,
      Expression<Func<T,TProp>> field,TProp value){

      var fn=((MemberExpression)field.Body).Member.Name;
      o.GetType().GetProperty(fn).SetValue(o,value,null);
      return o;
    }
  }
}

用法:

代码语言:javascript
复制
myUberComplexObject.Set(x=>x.PropertyOfIt, newValueOfIt);

你至少应该试着把那些“大块头”的东西分成小的。试着建立一个层次结构(只要确保它符合普遍存在的语言)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3716770

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档