我最近正在开发一款Java应用程序,并尝试遵循GoF的状态模式来整理代码。
该程序使用多智能体系统的代理来代表“超级代理”执行指令(下面是示例)。
超级代理可以存在两种状态,到处都有if语句检查状态,然后执行特定于状态的行为,这使得代码变得混乱不堪。
以下是程序的(非常)简化版本。实际实现具有更多的状态特定行为。
状态模式非常适合根据 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 设计模式将特定状态的行为封装到不同类中(超级代理类将作为上下文)。但是,有两个问题(我认为)破坏了封装性:
大多数状态特定行为需要更改超级代理的私有成员(在上面的示例中,instructionData)。这些成员包含数据,可能不应该可访问,也绝对不应该对包装类进行更改。
状态特定行为需要与非状态特定行为同步。如果不通过将其公开或使用 getter 暴露锁对象(在上面的示例中 instructionLock),则状态和上下文无法共享锁。暴露锁违反了 OOP,因为它可能被包装/扩展类使用。