我最近一直在开发 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)都破坏了封装:
大多数特定于状态的行为都需要对超级代理的私有成员(在上面的示例中为指令数据)进行更改。成员包含的数据可能不应该被访问,并且绝对不应该对包装类是可变的。
特定于状态的行为需要与非特定于状态的行为同步。如果不通过公开或使用 getter 来公开锁对象(在上面的示例指令锁中),则状态和上下文无法共享锁。公开锁违反了 OOP,因为它可能被包装/扩展类使用。
考虑到示例和上述两点,是否有人对我如何封装这种特定于状态的行为有任何建议?