Domain driven design DDD通过父对象修改子对象

Domain driven design DDD通过父对象修改子对象,domain-driven-design,Domain Driven Design,我正在写一个月支出申请,你把“支出”加到一个月里,这些支出包含对支出的描述和金额。例如,您可能有2015年4月,在此期间您有以下支出项目: 汽车新轮胎200美元 水电费350美元 等等 我写了以下内容,因此允许您将项目添加到该月 class ExpenditureMonth { public function addExpenditureItem(String description, Money amount) { items.add(new Expendi

我正在写一个月支出申请,你把“支出”加到一个月里,这些支出包含对支出的描述和金额。例如,您可能有2015年4月,在此期间您有以下支出项目:

  • 汽车新轮胎200美元
  • 水电费350美元
等等

我写了以下内容,因此允许您将项目添加到该月

class ExpenditureMonth
{
    public function addExpenditureItem(String description, Money amount)
    {
        items.add(new ExpenditureItem(this, description, amount));
    }
}
因此,
expertitureItem
的对象创建发生在
expertiturementh
中。一个支出月可以包含许多项目

当账户持有人为某个项目付款时,需要将其标记为已付款

如何将项目设置为已付款

我唯一的想法是为
ExpenditureItem
设置一个标识符,并将此实例传递给
addExpenditureItem
方法,但我觉得这不对

我以前也有过类似的经历(请阅读答案)

在DDD中,父级或聚合根根据有界上下文而变化。因此,在您的情况下,这是您的上下文:

当账户持有人为某个项目付款时,需要将其标记为已付款

对于该特定上下文,支出项目现在是聚合根,现在它需要自己标识ID。设置ID或GUID是普遍接受的解决方案,我认为在没有正确密钥的情况下唯一标识对象是不可靠的


但是,如果情况是“账户持有人支付了其所有月度未付支出(或所有未付支出)”,那么在这种情况下,合计根就是您的月度支出。

简短回答:如果您知道如何识别需要标记为已付的项目,那么将其git并标记为已付就足够了。如果数据库需要该项,则该项可以具有代理项。否则它应该被实现为值对象,以某种方式标识它。就是这样,我不知道如何标识该项?!我曾考虑可能给该项目一个id以便能够识别它,但正在寻找其他建议(如果有的话)。REST可以通过IRI识别资源,例如
/users/123/name
。我想你可以从实际的聚合根开始,对你的域对象做一些类似的事情,我想它已经有了一个id(但我可能不完全理解DDD)。当你将项目传递到月份时,它也会被支付吗?或者该项目是否为付款当月的现有子项?该项目是否为现有子项。在过去几天的调查中,我意识到这个项目需要是一个实体,因为它随着时间的推移会发生变化,所以它需要一个id;-)