使用给定的类和关联,您可以将其表达为约束:
约束是一个断言,指示包含该约束的模型的任何有效实现都必须满足的限制。
约束表示为大括号
{ ... }
之间的表达式,对应于预期为 true 的布尔表达式。它可以是:
{ only one player in a team have isSkipper true }
;{ self.fieldPlayers->select(isSkipper)->size() + self.goalKeepers->select(isSkipper)->size() = 1 }
。 和很多人一样,我不熟悉 OCL,这就是我推荐纯文本的原因,因为模型的想法是向读者更轻松地传达设计。我用
FootballTeam
上下文(即附加到该类的约束)表达了这些约束,因为它是整个团队的约束。
考虑到关注点分离,将
isSkipper
作为玩家属性的想法似乎不是最好的想法:队长角色取决于团队,因此在关联类中会更好地显示。
此外,将守门员和场上球员等角色作为专业化是很麻烦的,但将队长(另一个角色)作为布尔字段来实现任何健全的 OOP 多态设计可能会很麻烦。
最后但并非最不重要的一点是,请记住,一支足球队可能会发展,并且只有在完成时才可能满足所有条件(例如多重性),从而在模型和代码的实际情况之间造成一些脱节。
因此我强烈建议这样的设计:
+----------------+ * 1 +--------------+
| FootballPlayer |------------------------| FootballTeam |
+----------------+ : +--------------+
:
+------------+
| TeamPlayer |
+------------+
TeamPlayer
类是关于依赖于玩家和团队的一切。
然后我建议设计一个与
Role
相关的 TeamPlayer
类。 通常,一名玩家会扮演 1 个角色。 该角色将专门用于 GoalKeeper
与 FieldPlayer
,并且您可以将 Skipper
制作为 decorator,可以叠加到其他两个之一。
这并不能消除表达约束的需要,但模型会更强大。 最后但并非最不重要的一点是,如果满足当前所有约束(包括守门员、场上球员和队长角色的球员数量),我会看到一个
/isTeamValid
派生属性,该属性将为 true。优点是它可以让你建立一个团队并发展团队的组成和角色(