2011-04-18 157 views
0

例子:处理子对象状态当它影响双亲状态

class Person 
{   
    @OneToMany 
    List<Action> actionHistory; 

    @ManyToOne 
    Employer employer; 

    private StateEnum myCurrentState = StateEnum.INITIAL_STATE; 
} 

想象一下这样的情况,其中两件事情是真的:

  1. Person.myCurrentState需要对变化的反应的变化行动历史,雇主等。有一套业务规则,如“如果X行为显示在行动流中,且当前状态为Y,则将新状态设为Z”

  2. Pe rson需要能够根据当前状态阻止并允许对孩子进行一些操作。例如,在特定条件下可能无法更新雇主的职位,或者可能无法添加符合特定条件的操作。

最初我以为我只是试图通过Person中包含验证/反应逻辑的例程来通过所有的访问渠道。结果是Person对象变得太大而且到处都是,因为需要监视的孩子有多少次操作。 (即,而不是只是getAEmployer(),setNewEmployer()等类似的东西,它也是像updateJobTitleAtEmployer()等)

虽然逻辑分散给孩子似乎同样凌乱。在这种情况下,雇主(例如)必须包含大量的参考资料给其父母。此外,与这些东西有关的业务规则分散在各地。

这个问题有没有干净的通用解决方案?我想要一些通用的方法,我可以有一个Parent类的兽医,并且在某些情况下可以对其中许多孩子的某些状态变化做出反应。

更新: 我想我在这个问题中使用了术语“父母”和“孩子”。我使用它们是这样的:父母“有一个”由孩子组成的“孩子/父母”。在这个例子中,Person是父类,属性类是子类。

更好的例子:

class Employee 
{ 
    private Contract contract; 
    private List<Action> actions; 

    private EmployeeState currentState = EmployeeState.INITIAL; 
} 

试想在这种情况下currentState可能会改变某些东西在合同的变更(例如,如果利率上升)。如果员工处于某些州,那么也可能不能在合同上设置某些事项。在当前状态改变的情况下,合约属性只是一个更大计算的一个因素(即,状态可能由诸如“如果Contract.hourlyRate> 30并且动作包含具有这些属性的动作而不是状态为......”的规则来确定)。

此外,在这种情况下,添加操作可能会更改Employee的状态,或者根据当前状态被阻止。

如果我遇到这些问题,我的模型可能有问题吗?

+0

我只想确保术语清晰 - 当您在此处说“父母”和“孩子”时,您使用它来表示数据成员(“孩子”,(雇主))是“父母”('人'))? 我问,因为我习惯听继承层次意义上使用的“父”和“孩” - “Person”的孩子将是一个延伸Person的类。但这似乎并不是你在这里的意义。 – QuantumMechanic 2011-04-18 17:08:52

+0

是的,我认为我误用这些条款。在这种情况下,我使用“孩子”来表示父代中的一个类。 (所以父母与孩子有“有”或“有组合”的关系)。 – user426724 2011-04-18 17:55:01

+0

我仍然对你的例子感到困惑。我认为职位是一名雇员/一个人而不是雇主/公司的财产。如果职称取决于人的状态,那么setJobTitle函数应该检查该状态。 – Pace 2011-04-18 18:35:25

回答

1

从我的理解,你可以使用Observer pattern这种情况。在这种情况下,合同将订阅雇主,以便当雇主的状态发生变化时,合同将得到通知,并且可以根据当前状态自行决定。