状态模式和封装

问题描述 投票:5回答:1

我最近一直在开发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)破坏了封装:

  1. 大多数状态特定的行为都需要更改超级代理的私有成员(在上面的示例中,instructionData)。成员包含可能不应该访问的数据,并且definitely

    不应对包装类是可变的。
  2. 特定于状态的行为需要与非特定于状态的行为同步。在不通过公开或使用getter公开锁对象的情况下(在上述示例中,instructionLock),状态和上下文无法共享锁。公开锁违反OOP,因为包装/扩展类可能会使用它。

  3. 关于示例和以上两点,有没有人对我如何封装这种特定于状态的行为有任何建议?

我最近一直在开发Java应用程序,并且一直在尝试遵循GoF的状态模式来整理代码。该程序使用多代理系统的代理来评估...

java oop encapsulation agent state-pattern
1个回答
1
投票

您可以通过在状态实例和Double Dispatch实例之间使用superAgent来解决这两个问题,以避免破坏封装。

© www.soinside.com 2019 - 2024. All rights reserved.