Core Java Design Pattern : Behavioral Pattern : State Design Pattern
State Design Pattern |
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
Also Known As : Objects for States
Use the State pattern in either of the following cases:
- An object’s behavior depends on its state, and it must change its behavior at run-time depending on that state.
- Operations have large, multipart conditional statements that depend on the object’s state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a separate class. This lets you treat the object’s state as an object in its own right that can vary independently from other objects.
Consider a class TCPConnection that represents a network connection. A TCPConnection object can be in one of several different states: Established, Listening, Closed. When a TCPConnection object receives requests from other objects, it responds differently depending on its current state. For example, the effect of an Open request depends on whether the connection is in its Closed state or its Established state. The State pattern describes how TCPConnection can exhibit different behavior in each state.
The State pattern allows an object to change its behavior when its internal state changes. This pattern can be observed in a vending machine. Vending machines have states based on the inventory, amount of currency deposited, the ability to make change, the item selected, etc. When currency is deposited and a selection is made, a vending machine will either deliver a product and no change, deliver a product and change, deliver no product due to insufficient currency on deposit, or deliver no product due to inventory depletion.
Examples |
State.java
package com.javaskool.state;
public interface State {
void grantPermission(StateContext stc);
void requestPermission(StateContext stc);
String getStatus();
}
AcceptedState.java
package com.javaskool.state;
public class AcceptedState implements State {
@Override
public String getStatus() {
// TODO Auto-generated method stub
return "Request received";
}
@Override
public void grantPermission(StateContext stc) {
// TODO Auto-generated method stub
System.out.println("Invalid state");
}
@Override
public void requestPermission(StateContext stc) {
// TODO Auto-generated method stub
System.out.println("Requesting Permission");
stc.setState(stc.getRequestedState());
}
}
GrantedState.java
package com.javaskool.state;
public class GrantedState implements State{
@Override
public String getStatus() {
// TODO Auto-generated method stub
return "Request received";
}
@Override
public void grantPermission(StateContext stc) {
// TODO Auto-generated method stub
System.out.println("Invalid State");
}
@Override
public void requestPermission(StateContext stc) {
// TODO Auto-generated method stub
System.out.println("Invalid State");
}
}
RequestedState.java
package com.javaskool.state;
public class RequestedState implements State {
@Override
public String getStatus() {
// TODO Auto-generated method stub
System.out.println("Requested Permission");
return null;
}
@Override
public void grantPermission(StateContext stc) {
// TODO Auto-generated method stub
System.out.println("Granting Permission");
stc.setState(stc.getGrantedState());
}
@Override
public void requestPermission(StateContext stc) {
// TODO Auto-generated method stub
System.out.println("Permission already requested");
}
}
StateContext.java
package com.javaskool.state;
public class StateContext {
private State accepted;
private State requested;
private State granted;
private State state;
public StateContext() {
super();
// TODO Auto-generated constructor stub
accepted=new AcceptedState();
requested=new RequestedState();
granted=new GrantedState();
}
public void acceptApplication(){
state=accepted;
}
public void requestPermission(){
state.requestPermission(this);
}
public void grantPermission(){
state.grantPermission(this);
}
public String getStatus(){
return state.getStatus();
}
public void setState(State s){
state=s;
}
public State getAcceptedState(){
return accepted;
}
public State getGrantedState(){
return granted;
}
public State getRequestedState(){
return requested;
}
}
TestDrive.java
package com.javaskool;
import com.javaskool.state.StateContext;
public class TestDrive {
public static void main(String arg[]){
StateContext ctx=new StateContext();
ctx.acceptApplication();
ctx.requestPermission();
ctx.grantPermission();
System.out.println(ctx.getStatus());
}
}
Output
c:\>javac -d . *.java
c:\>java com.javaskool.TestDrive
Requesting Permission
Granting Permission
Request received
Recent Comments