【问题标题】:Am I taking value objects too far (DDD) [closed]我是否将价值对象太过分了(DDD)[关闭]
【发布时间】:2012-10-15 12:45:11
【问题描述】:

编辑: 为了清楚起见,这个问题与 DDD 有关,它有一个称为值对象的概念,这些不是值类型,它们是一种以内容构成身份的方式构建对象的方式,我试图了解多远这些概念应该适用(从评论看来它们不应该渗入域外)。对于不熟悉 DDD 的人来说,这个问题可能看起来很奇怪,但要明确的是,它是关于创建对象而不是创建值类型的一种非常具体的机制。

考虑以下示例代码,它有两个值对象:

public class SqlServerConnectionSettings
{
    public string DatabaseName { get; set; }

    public string ServerName { get; set; }

    public SqlServerCredentials Credentials { get; private set; }

    public SqlServerConnectionSettings(SqlServerCredentials credentials)
    {
        Credentials = credentials;
    }

    public string AsConnectionString()
    {
        //Snip
    }
}

public class SqlServerCredentials
{
    public string Username { get; private set; }

    public string Password { get; private set; }

    public bool UseIntegratedSecurity { get; private set; }

    public SqlServerCredentials(string username = "", string password = "", bool useIntegratedSecurity = true)
    {
        Username = username;
        Password = password;
        UseIntegratedSecurity = useIntegratedSecurity;
    }

    public string AsConnectionStringCredentials()
    {
       //Snip
    }
}

我没有为用户名、密码、UseIntegratedSecurity 设置不同的参数,而是创建了一个值对象来保存它们。我的问题是,这个概念是否太过分了,我是否误解了点值对象的设计目的?

【问题讨论】:

  • 看起来是个不错的方法。凭据是与连接设置分开的实体,因此可以制成它们自己的类。这使您可以在将来向SqlServerCredentials 添加更多选项,而不会暴露该类的底层机制。
  • 你的问题很主观。但是,如果它对您来说是正确的,那么它可能是正确的。请更正integrated的拼写。
  • @KlausByskovHoffmann 这不是哪个“似乎”正确的问题。有很多人在做 DDD,我想知道值对象什么时候是必要的,什么时候是多余的。修正了拼写。
  • 我宁愿称其为基础设施,而不是域的一部分。
  • @jgauffin 我同意,我不会在特定于域的基础设施中投入太多,但我确实发现基础设施中有“迷你域”。

标签: c# domain-driven-design


【解决方案1】:

我觉得不错。您将属于一起的项目分组为有凝聚力的单元,这有什么问题?

【讨论】:

  • 我认为,我关心的是维护。但另一方面,我认为对 SqlServerCredentials 或其属性的任何验证都会很好地打包到它自己的 VO 中。
  • 清晰、有目的的代码比简洁更有助于维护。所以在我看来,你的方法是非常可维护的。
【解决方案2】:

这取决于你的上下文。

  • 如果您将SqlServerCredentials 定义为实体,是的,您走得太远了:

“一个实体是一个对象,它不是由它的属性定义的,而是由一个连续的线程和它的标识来定义的。”

  • 如果您将SqlServerCredentials 定义为值对象,那么您是对的(不要忘记它应该是不可变的!):

“值对象是一个包含属性但没有概念标识的对象。它们应该被视为不可变的。”

  • 如果您将SqlServerCredentials 定义为聚合,那么您也是对的:

聚合是由根实体绑定在一起的对象的集合,也称为聚合根。聚合根通过禁止外部对象持有对其成员的引用来保证聚合内所做更改的一致性。

总之,以 DDD 的方式,如果您不将 SqlServerCredentials 视为一个实体,那也没关系。但这完全取决于上下文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多