【问题标题】:Should the implementation of value object be sealed?值对象的实现是否应该被密封?
【发布时间】:2018-05-08 14:27:04
【问题描述】:

遵循 DDD 实践,值对象的实现是否应该被密封? 想象一下有一些抽象的ValueObject<T> 和作为Money : ValueObject<Money> 给出的具体实现。我应该盖章Money 吗?

public class Money : ValueObject<Money>
{
    private Money()
    {
    }

    private Money(decimal value, string currency)
    {
        Requires.NotEmpty(currency, nameof(currency));
        Requires.That(value >= 0, $"{nameof(value)} must be greater or equals to 0.");

        Value = value;
        Currency = currency.ToUpper();
    }

    public decimal Value { get; private set; }

    /// <summary>
    /// <a href="http://currencysystem.com/codes/">ISO 4217</a> currency code 
    /// </summary>
    public string Currency { get; private set; }

    public static Money Dkk(decimal value) => new Money(value, "DKK");
    public static Money Usd(decimal value) => new Money(value, "USD");
}

【问题讨论】:

    标签: oop domain-driven-design value-objects


    【解决方案1】:

    一般来说,最好的做法是避免由于组合超过继承建议而导致的多态性。在 DDD 上下文中,在某些情况下允许未来的多态性很有用,但这通常包括实体。

    每个定义的值对象应该是不可变的,为了避免进一步的滥用,密封它。

    有用的链接:http://thepaulrayner.com/value-objects-and-immutability/

    【讨论】:

    • 那么按照设计,在这种情况下你应该省略继承吗?我认为有一些基类来重用值对象行为会非常好(我目前的摘要implementation)一定要密封Money,谢谢!
    • 你可以的。问题是:你真的需要抽象吗? Money 的潜在子类是什么?我更喜欢显式代码。这可能会导致一些小的代码重复,但通常会降低复杂性。
    • 对此的补充。如果你使用多态性,你会“打开一扇门”,这可能会导致影响不变性。
    • 我的意思是,引入基值对象类并将其用于创建密封派生类是否有意义?我真的明白在这种情况下留下扩展类的机会是不好的,但我现在想问的问题是我是否应该删除从 ValueObject 的继承并引入一些接口并让例如 Money 实现它。跨度>
    • 你是用这个抽象类来定义hashCode和equals的吧?我更喜欢这种关于我的实施的信息,但这可能更像是一个“品味问题”。从技术上讲,它应该可以工作。这个接口的主要行为是什么?
    【解决方案2】:

    在我看来,值对象与其他类型的对象在考虑密封时差别不大。多年来,无论是支持还是反对,都提出了无数的论据,考虑到足够复杂的因素,您不想在等式中添加另一个变量。

    我几乎看不到域模型中的所有 VO 都被密封,但所有其他类都没有密封。如果您要密封,主要是出于完全不同的原因(组织、性能),这些原因与 DDD 命名法中的对象类型没有太大关系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      相关资源
      最近更新 更多