查看ddd示例应用程序,我无法弄清楚为什么Cargo
Cargo.java对象需要单独引用RouteSpecification
。
拥有origin, destination and arrivalDeadline
货物类的一部分并完全跳过此RouteSpecification类并公开updateDestination
和satisfiedByItinerary
RouteSpecification用于验证行程是否能够满足货运路线等。但我认为没有任何理由说明货物类本身无法处理这样的任务,这种分离的重点是什么?
public class Cargo implements Entity<Cargo> {
...
private Location origin;
private Location destination;
private Date arrivalDeadline;
...
答案 0 :(得分:2)
进行文档演练,version 1 introduction中有一个有用的指针。
要求加快DDD速度的最需要的帮助之一就是一个运行的示例应用程序。从一组简单的函数和基于Eric Evans的书中使用的货物示例的模型开始
鉴于此,我们可以合理地假设该设计与the blue book第7章中的设计具有相似的动机。
交付规范定义了交付目标,该交付目标至少包括目的地和到达数据,但它可能更复杂。该类遵循规范模式。
Cargo对象可以承担这一责任,但交付规范的抽象至少有三个优势。
如果没有交货规格,货物对象将负责指定交货目标的所有这些属性和关联的详细含义。这会使Cardo变得混乱并使其更难改变。
这种抽象使得在整体解释模型时可以轻松,安全地抑制细节。例如,可以在交付规范中封装其他标准,但是在此详细级别的图表不必公开它。该图告诉读者有一个交付规范,其中的细节并不重要(事实上,以后可以很容易地改变)。
- 醇>
这个模型更具表现力。添加交货规范明确指出货物交付的确切方式尚未确定,但必须达到交货规范中规定的目标。
But then why isn't origin a part of RouteSpecification?
我没有深入挖掘整个项目历史,但我的猜测是Cargo.origin
和RouteSpecification.origin
实际上并不可以互换。 (origin是RouteSpecification的一部分,但RouteSpecification可以随时间变化)。
货物可以在运输过程中根据客户的要求重新布线,在这种情况下,为货物指定新的路线并要求新的路线。
也可能发生货物意外错误路由,应该通知适当的人员并触发重新路由程序。
第一版代码还表明货物可能误导(与错误路线不同)。
如果仔细查看different scenarios,您会看到他们以不同的方式处理误导;较新的版本通过替换路线规范然后搜索匹配的行程来实现。
答案 1 :(得分:1)
If you considered the consequences of completely refactoring out the RouteSpecification class from the solution, you would find that origin
, destination
and arrivalDeadline
seem to get passed around together much of the time. This is a strong sign that the values are closely related. "Cohesion" is a principle of object oriented programming in which closely related concepts are located close together in code, so to follow this principle, you can bring these three concepts together in a single class.
Many programmers would agree that it is simpler to pass around a single RouteSpecification object everywhere these values are used rather than origin
, destination
and arrivalDeadline
separately.