在我的应用程序中,我有产品在生产线的工作站之间旅行。每一次产品在车站的通过记录结果:失败成功。 产品和工作站之间的关系很多。
如果我用程序语言编程,我会有以下功能:
get_last_pass_result($station_id, $product_id) {...}
返回此特定产品上次在此特定电台上传递的结果。
现在你如何用OOP术语模拟这个逻辑? 我肯定会有班级和班级产品。 但我应该这样做(PHP语法):
$station->get_last_product_pass_result($product_id)
或者
$product->get_last_pass_on_station_result($station_id)
情况似乎是对称的,我想知道在两者之间存在哪些考虑因素(或者甚至可能是第三种解决方案?)
我无法在此提供有关域名的所有现有信息,但可以随意添加以下注意事项:if [关于域名的假设]然后[您的设计解决方案],如果感觉合适
答案 0 :(得分:3)
我的观点,但基于DDD原则,所以我不知道这适合您的需求,但无论如何......
所以你有电台和产品。我会说它们都是可以互相引用的实体,但是你所谈论的逻辑包含这些实体,并且可能像 ProductPassingService 一样放在像这样的操作的域服务中> GetLastPassFor(产品,电台)。
此域服务有责任使用底层域实体Station和Product(以及存储库来查询它们)并执行不属于Station和Product的逻辑。它使实体工作站和产品免于承担太多责任。
此外,域实体不应使用存储库(DDD - the rule that Entities can't access Repositories directly),因此该逻辑属于域服务。
答案 1 :(得分:1)
我不完全清楚Product
是代表产品的类型(例如椅子)还是单个产品实例(例如chair-001,chair-002)。从你的例子来看,似乎后者就是这种情况,所以我会使用它,否则get_last_pass_result
没有多大意义。
我相信我会引入一个Path
类型(虽然不知道很多关于域的内容)。现在,根据其他用例,这可能是一个聚合根(在DDD术语中)或不是。
这意味着它可以通过Product
实例访问,也可以直接从DB / repository /中访问。使用路径实例,我可以做到:
var path = product.GetPath(); // if it is accessible only via product
var path = Path.GetPathForProduct(product); // or pathRepository.GetPathFor(), or ...
var result = path.LastResult;
这种方法将工厂流程与产品本身分离,并启用其他一些方案(例如查找平均持续时间等等)
答案 2 :(得分:1)
一如既往 - 这取决于你如何使用它。
但在Discovery频道 - 一家汽车工厂 - 有一个很好的“工作原理”样本。在旅途中的槽式输送机中,汽车接收到越来越多的附加部件。每辆汽车都附加了一种作业计划 - 要完成任务所需完成的作业列表。当它在线上移动时,负责工作的人会对完成工作做出标记。因此,当发现缺陷时 - 您肯定知道来源。
所以,回到程序方法。首先,使用结构+程序方法而不是纯粹的oop更自然。当然,这取决于你。
第二 - 我建议将“产品”与“生产线日志”对象分开,该对象与产品一对一关系,但在产品发布后可能不是必需的。 “生产线日志”存储与站点对象处理相关的事件。此外,您可以将其用作时间表,即包括如何处理特定产品的指令(作为汽车包括或不包括某些特征,如护发素或雾灯)。并且“计划”的行动应该由工人标记为“完整”。
在现今的术语中,它也可以用“事件采购”术语表达:在运动过程中,产品修改被写入日志;因此,可以通过逐个重放修改事件来重新构建产品。
答案 3 :(得分:0)
我建议把它放在产品中。我担心的是产品的数量很大,但是工作站应该是固定的,并且将特定产品的状态记录在该产品的对象中是很自然的。对于电台,它可能只需要记录一些统计数据。