State
Story
Behavior depends on its state.
Pregnancy is time of great physical and emotional change for women. Everything from the size of her belly to the speed at which her heart beats will change over the nine months leading up to childbirth. Partly the result of hormonal fluctuations and partly the physical strain of carrying extra body weight, pregnant women can expect to buy new bras, search for ways to alleviate swollen ankles, gasp for breath after climbing a few stairs, and marvel at how quickly their nails grow.
Image
Petteri Sulonen from Helsinki, Finland, Pregnant graffiti, CC BY 2.0
UML
Implementation
State.java
package com.hundredwordsgof.state;
/**
* The interface for encapsulating the behavior associated with a particular
* state of the Context.
*
*/
public interface State {
void handle();
}
ConcreteState1.java
package com.hundredwordsgof.state;
/**
* ConcreteState1 implements a behavior associated with a state of the Context.
*
*/
public class ConcreteState1 implements State {
private boolean handleInvoked = false;
public void handle() {
this.handleInvoked = true;
}
protected boolean isHandleInvoked() {
return handleInvoked;
}
}
ConcreteState2.java
package com.hundredwordsgof.state;
/**
* ConcreteState2 implements a behavior associated with a state of the Context.
*
*/
public class ConcreteState2 implements State {
private boolean handleInvoked = false;
public void handle() {
this.handleInvoked = true;
}
protected boolean isHandleInvoked() {
return handleInvoked;
}
}
Context.java
package com.hundredwordsgof.state;
/**
* Context maintains an instance of a ConcreteState subclass that defines the
* current state.
*
*/
public class Context {
private State state;
public void request() {
state.handle();
}
public void setState(State state) {
this.state = state;
}
}
Usage
StateTest.java
package com.hundredwordsgof.state;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* Test implementation of the State pattern.
*/
public class StateTest {
@Test
public void testState() {
State state1 = new ConcreteState1();
State state2 = new ConcreteState2();
assertEquals(false, ((ConcreteState1) state1).isHandleInvoked());
assertEquals(false, ((ConcreteState2) state2).isHandleInvoked());
Context context = new Context();
context.setState(state1);
context.request();
assertEquals(true, ((ConcreteState1) state1).isHandleInvoked());
context.setState(state2);
context.request();
assertEquals(true, ((ConcreteState2) state2).isHandleInvoked());
}
}