我正在确定一种可以与其他类型的其他对象建立关系的对象的最佳设计方法。但是一次只能属于一种类型。我可以想到的一种互斥的一对多关系是描述这种情况的最佳方式。
示例:
我既有项目,也有程序。每个任务都可以包含多个任务。一个任务可以属于一个项目或一个过程,但不能同时属于一个或多个。可以将任务从项目移至过程,反之亦然。
因此,在任何时候Task都与项目具有一对多的关系,或者与过程之间具有一对多的关系。
此刻,我正在考虑一个这样的任务:
class Task(id, name, project_id, procedure_id):
if project_id and procedure_id:
throw Exception("A Task can not be assigned to a Project and a Procedure at the same time")
self.id = id
self.name = name
self.project_id = project_id
self.procedure_id = procedure_id
def move_to_project(project_id):
self.procedure_id = None
self.project_id = project_id
...
任务将保护它只能属于单个项目或过程的不变性。项目和过程中的工厂方法可以创建具有相关关系ID的任务。
一个任务都不是两者中的一个,所以我想通过身份对关系进行建模。
在我看来,保护这种不变性的唯一方法是以此方式对Task建模。否则,我最终将获得庞大的“过程/项目/任务”集合。
这似乎是一个理智的方法,还是有人对可能值得探索的替代设计方法有任何建议?
答案 0 :(得分:1)
如果一个任务不能同时关联到一个项目和一个过程,那么我就不会有两个ID的构造函数。我会有一个用于项目ID,另一个用于过程ID。我将使用根据UL命名的工厂方法来执行此操作。这样,您就可以构造与项目或过程相关联的任务,但不能同时与两者都有。
答案 1 :(得分:1)
您应该在TaskService应用程序层上具有TaskService.AssignToProject()和TaskService.AssigneToProcedure()方法。如果Task是一个单独的集合,则意味着它可以没有程序或项目地过自己的生活。它们可以在一段时间内为空。在调用TaskService.AssignToProject()或TaskService.AssigneToProcedure()时,应分配ProcedureId或ProjectId。因此,在TaskService.AssignToProject()中,从db获取Task和Project,然后调用task.AssignTo(project)。然后,您验证ProcedureId是否为null并执行所需的操作(引发异常或UnassignFromProcedure())。分配完成后,引发TaskAssignedToProject域事件,捕获该事件并在另一个交易中调用ProjectService.CommitTask()。谁可以将该任务添加到Project聚合的内部CommittedTasks集合中。