【发布时间】:2011-04-18 16:47:21
【问题描述】:
例子:
class Person
{
@OneToMany
List<Action> actionHistory;
@ManyToOne
Employer employer;
private StateEnum myCurrentState = StateEnum.INITIAL_STATE;
}
想象一下这样的情况,其中有两件事是正确的:
Person.myCurrentState 需要更改以响应 actionHistory、雇主等的变化。有一组业务规则,例如“如果类型 X 的动作出现在动作流中并且当前状态为 Y,则设置新的状态到 Z"
Person 需要能够根据当前状态阻止和允许对子项进行某些操作。例如,在某些条件下可能无法更新 Employer 的职位,或者可能无法添加满足某些条件的操作。
最初,我以为我会尝试通过 Person 中包含验证/反应逻辑的例程来汇集对孩子的所有访问。结果是 Person 对象变得太大而且到处都是,因为它需要监视多少个孩子的操作。 (即不只是 getAEmployer()、setNewEmployer() 之类的东西,还有 updateJobTitleAtEmployer() 等)
不过,将逻辑传播给孩子们似乎同样混乱。在这种情况下,雇主(例如)必须包含大量对其父级的引用。与这些东西相关的业务规则也分散在各处。
这个问题有什么干净的通用解决方案吗?我想要一些通用的方法,我可以让一个 Parent 类兽医,在某些情况下对它的许多孩子的某些状态变化做出反应。
更新: 我想我在这个问题中误用了“父母”和“孩子”这两个词。我像这样使用它们:父母“有一个”孩子/父母“由孩子组成”。在示例中,Person 是父类,属性类是子类。
更好的例子:
class Employee
{
private Contract contract;
private List<Action> actions;
private EmployeeState currentState = EmployeeState.INITIAL;
}
想象在这种情况下,如果 Contract 中的某些内容发生变化(例如,如果利率上升),currentState 可能会发生变化。如果员工处于某些状态,也可能无法在合同上设置某些内容。在 currentState 发生变化的情况下,Contract 属性只是更大计算中的一个因素(即状态可能由诸如“如果 Contract.hourlyRate > 30 并且操作包含具有这些属性的操作而不是状态...”之类的规则确定)。
此外,在这种情况下,添加操作可能会更改 Employee 的状态,或者根据当前状态被阻止。
如果我遇到这些问题,我的模型是否可能有问题?
【问题讨论】:
-
我只是想确保术语清楚——当你在这里说“父母”和“孩子”时,你用它来表示数据成员(一个“孩子”,(
Employer)是“父母”的成员(Person))?我问是因为我习惯于听到在继承层次结构意义上使用的“父”和“子”——Person的子将是扩展Person的类。但这似乎不是你的意思。 -
是的,我想我误用了这些术语。在这种情况下,我使用“child”来表示父级中的一个类。 (所以父母与孩子有“有”或“组成”类型的关系)。
-
我仍然对你的例子感到困惑。我认为职位是雇员/个人而不是雇主/公司的财产。如果职位取决于人的状态,那么 setJobTitle 函数应该只检查该状态。
-
你是对的。我真的应该多考虑一下这个例子。也许一个更好的例子是雇主的行业财产。当这种情况发生变化时,它可能会更新有关 Person 对象状态的某些内容,或者完全被阻止。
标签: java oop design-patterns