我正在尝试遵循“在课堂上使用getter / setter是邪恶的”这样的建议。所以,假设我的聚合类Invoice
具有以下签名:
public class Invoice{
ISet<Line> _lines;
public void ChangeLineAmount(int LineId, double newAmount){
//Your answer here
}
}
如果Line
类没有getter,我怎样才能找到更改的具体行?
答案 0 :(得分:2)
&#34; vanilla&#34; DDD,建议避免使用直接设置器(或可变集合的getter)并使域操作显式。使用意图揭示,无处不在的语言兼容,不变的强制执行行为(方法)来尽可能地改变您的实体。然而,在这种方法中,实体也是你从中读取数据的地方,它们必须为读者揭示它们的状态,所以我不知道如何在没有吸气剂的情况下做到这一点。
DDD的CQRS(+ ES)风格将具有读取模型,您可以使用get模型显然可以访问所需的所有内容,以及只能通过命令更改其状态的聚合。由于所有读取都是通过辅助读取模型对象完成的,所有读取都是通过命令完成的,因此您不需要在面向外部的聚合根上使用getter或setter ,但是根本身必须能够更改内部的实体他们自己的聚合,有时需要制定者。
无论如何,事情就像&#34一样简单;在课堂上使用getter / setter是邪恶的......#/ p>
答案 1 :(得分:1)
在DDD问题上“在你的课程中使用getter / setter是邪恶的”这句话背后的原因是,getter和setter通常不会代表你的UL(普遍存在的语言)并导致贫血的实体。但是如果在您的UL中有类似“我需要该行数量”的内容,那么您可以创建getter但根据UL命名,例如:invoice.lineAmount(lineId)
。
在方法内部,您可以简单地访问属性,因为CharlesNRice已经回答了。如果您觉得在读取/设置行时需要任何特殊处理,那么您可以创建私有getter以在域逻辑方法中使用它。
更新:
首先需要Getters和setter,因为在项目后期您可能希望在设置/获取属性之前添加一些额外的验证/转换,如果没有它,您将不得不找到正在访问的每一段代码财产并改变它。使用getter / setter,您可以在一个位置访问属性,因此您可以在一个位置更改代码 - 更容易维护。但是因为在DDD中你必须只使用域逻辑方法,所以你不能直接在给定实体之外的任何地方访问你的属性,所以你也不必使用getter和setter。像invoice.lineAmount(lineId)
这样的域方法实际上就像getter一样工作,但是与UL一起使用它们就可以了。如果您发现正在实体类中的少数几个位置访问属性,则可以考虑创建真正的getter / setter以供内部使用。
答案 2 :(得分:-1)
_line只是一个字段,如果它没有getter或setter。如果你添加它们,那么它就是一个属性。为了得到这条线,你会像使用它一样使用它。
public class Invoice{
ISet<Line> _lines;
public void ChangeLineAmount(int LineId, double newAmount)
{
var line = _lines.FirstOrDefault(l=>l.LineId == LineId);
if (line != null)
{
line.Amount = newAmount;
}
}
}
如果“在课堂上使用getter / setter是邪恶的”,我认为这是个人观点。我个人并不这么认为。