我最近一直在开发Java应用程序,并且一直在尝试遵循GoF的状态模式来整理代码。
程序使用多代理系统的代理代表“超级代理”评估指令(下面的示例)。>>
超级代理可以以两种状态存在,并且到处都有if语句检查状态,然后执行特定于状态的行为,这变得一团糟。
这里是程序的(非常)简化版本。实际的实现有很多特定于状态的行为。
public class superAgent { //the state of the super agent private States state; //Contains information related to the operation of exampleClass. This should not be exposed through mutator methods. private HashMap<String, SpecificInstructionData> instructionData private LinkedBlockingQueue<ExampleInstruction> exampleQueue private final Object instructionLock = new instructionLock public enum States { STATE1, STATE2; } public void setState(state s) { state = s } //Called by a thread that continuously takes from the queue private void runningThread() { while(isRunning) { synchronized(instructionLock) { ExampleInstruction ei = exampleQueue.take(); //Add some data about the instruction into instructionData //send the instruction to an available agent } } } public void instructionResponseRecievedFromAgent() { if(state == States.STATE1) { doState1Behavior(); } else if(state == States.STATE2) { doState2Behavior(); } } private void doState1Behavior() { synchronized(instructionLock) { //make state specific modifications to instructionData } } private void doState2Behavior() { synchronized(instructionLock) { //make state specific modifications to instructionData } } }
状态模式非常适合根据GoF模式将特定状态的行为封装到不同的类中(superAgent类是上下文)。但是,有两个问题,这两个问题都(IMO)破坏了封装:
大多数状态特定的行为都需要更改超级代理的私有成员(在上面的示例中,instructionData)。成员包含可能不应该访问的数据,并且definitely
不应对包装类是可变的。特定于状态的行为需要与非特定于状态的行为同步。在不通过公开或使用getter公开锁对象的情况下(在上述示例中,instructionLock),状态和上下文无法共享锁。公开锁违反OOP,因为包装/扩展类可能会使用它。
关于示例和以上两点,有没有人对我如何封装这种特定于状态的行为有任何建议?
我最近一直在开发Java应用程序,并且一直在尝试遵循GoF的状态模式来整理代码。该程序使用多代理系统的代理来评估...
您可以通过在状态实例和Double Dispatch实例之间使用superAgent
来解决这两个问题,以避免破坏封装。