Note that there are some explanatory texts on larger screens.

plurals
  1. POState pattern and encapsulation
    text
    copied!<p>I've recently been developing a Java application and I've been attempting to follow the GoF's state pattern to attempt to tidy up the code. </p> <p>The program uses a multi-agent system's agents to evaluate instructions on the behalf of a "super agent" (example below).</p> <p>The super agent can exist in two states, and it's getting messy having if statements everywhere checking the state and then performing state specific behavior.</p> <p>Here is a (very) simplified version of the program. The actual implementation has alot more state specific behavior.</p> <pre><code>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&lt;String, SpecificInstructionData&gt; instructionData private LinkedBlockingQueue&lt;ExampleInstruction&gt; 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 } } } </code></pre> <p>The state pattern would be perfect for encapsulating the behavior of the specific states into different classes according to the GoF pattern (the superAgent class would be the context). However there are two problems, both of which (IMO) break encapsulation:</p> <ol> <li><p>Most state specific behavior needs to make changes to private members (in the above example, instructionData) of the super agent. The members contain data which probably shouldn't be accessible and <strong>definitely</strong> shouldn't be mutable to wrapping classes.</p></li> <li><p>The state specific behavior needs to be synchronized with behavior that isn't state specific. Without exposing the lock objects (in the above example instructionLock) by either making it public or using a getter the state and context are unable to share a lock. Exposing the lock violates OOP because it could potentially be used by wrapping/extending classes.</p></li> </ol> <p>Does anyone have any suggestions regarding how I could encapsulate this state specific behavior, bearing in mind the example and the two points above?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload