【问题标题】:Mutable Value Objects / Sharing State (and beer brewing!)可变值对象/共享状态(和啤酒酿造!)
【发布时间】:2009-04-08 05:30:56
【问题描述】:

我是一个生疏的程序员,试图再次在该领域学习。我断断续续地发现,我的自学和正规教育都导致了一些坏习惯。因此,我试图让我的思想围绕良好的设计模式,以及——通过扩展——当它们是错误的。语言是 Java,这是我的问题:

我正在尝试编写软件来帮助酿造啤酒。在酿造过程中,有时您必须用特定种类的啤酒花代替配方中要求的啤酒花。例如,您可能有一个需要“阿马里洛”啤酒花的食谱,但您只能得到“Cascade”,它具有足够相似的香气,可以替代;啤酒花具有一定量的 Alpha 酸(每给定质量),两个啤酒花之间的比率是替代公式的一部分。我正在尝试在我的程序中(正确地)对此进行建模。

我最初的目标是拥有两个对象。一个是HopVariety,它包含有关各种啤酒花的一般描述信息,另一个是HopIngredient,它是HopVariety 的特定实例,还包括给定配方中使用的数量。 HopIngredient 应该知道它的多样性,HopVariety 应该知道什么可以用作它的替代品(并非所有替代品都是对称的)。这似乎是不错的 OOP。

问题是这样的:我正在尝试遵循良好的做法并使我的值对象不可变。 (在我的脑海中,我将HopVarietyHopIngredient 归类为值对象,而不是“参与者”。)但是,我需要用户能够使用新的可行替换来更新给定的 HopVariety。如果我遵循不变性,这些更改将不会传播到单个成分。如果选择可变性,我表现不佳可能会通过共享可变值对象来引入副作用。

所以,选项 B:引入各种类型的 VarietyCollection,并通过名称或唯一标识符松散地耦合成分和品种。然后是 VarietySubstitutionManager,这样品种就不会引用其他品种,而只会引用它们的 id。这与我想要做的事情背道而驰,因为持有对品种对象的引用具有直观意义,现在我要介绍感觉像是过度抽象的东西,并将函数与数据分开。

那么,我如何在特定实例之间正确共享状态?解决问题的正确或至少是最明智的方法是什么?

【问题讨论】:

    标签: reference mutable value-objects


    【解决方案1】:

    你确定HopVariety 应该是一个值对象吗?在我看来,这听起来像是一个实体——“阿马里洛”啤酒花品种是唯一的,所以它应该是一个唯一可识别的对象。就像“托尼·伍斯特”只是一个(不完全是,但你明白了;))

    我建议阅读Domain Driven Design 以及实体和值对象之间的区别。

    顺便说一句:DDD book 有很多像你这样的情况以及如何处理它们的例子。

    【讨论】:

      【解决方案2】:

      我认为你的选择是要么

      • 让“更新品种”功能遍历现有对象图并创建一个更新所有成分的新对象图,或者
      • 继续使用可变性

      根据手头的信息,我不清楚哪个更适合您的情况。

      【讨论】:

        【解决方案3】:

        您希望避免具有多个引用的对象突变有多严重?

        如果您希望配方集合反映用户对品种集的更新,并且希望避免对象中的可变字段,那么您将强迫自己使用功能对象更新来处理用户输入。

        路的尽头是 I/O monad。你想朝那个方向走多远?

        使用允许突变副作用的函数式语言,例如S/ML 等,您可能会选择保持品种和成分对象的纯净,并存储从存储在单个可变引用单元格中的最新品种集合返回当前品种对象的函数。这似乎是一种合理的分割差异的方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-08-03
          • 1970-01-01
          • 1970-01-01
          • 2011-12-09
          • 2016-11-15
          • 2013-10-12
          • 2012-03-11
          相关资源
          最近更新 更多