The body of the

A, definitions,

The state mode allows an object to change its behavior when its internal state changes, and the object appears to modify its class.

Key points:

  • The state pattern allows an object to have different behaviors based on its internal state.
  • The state pattern encapsulates the state as a separate class and delegates the action to an object that represents the current state.
  • By encapsulating each state into a class, we localize any changes we need to make later.

Two, implementation steps

1. Create a status interface

/** * public interface State {/** * public void handle(); }Copy the code

Delegate requests to the state class in the class that holds the state

/** * Public class Context {private State State; public State getState() { return state; } public void setState(State state) { this.state = state; } public void request() {state.handle(); }}Copy the code

3. Create a specific state and implement the state interface

(1) Specific state A

Public class ConcreteStateA implements State {ConcreteStateA implements State; public ConcreteStateA() { context = new Context(); } @override public void handle() {system.out.println ("Context is in A state, and start to do something..." ); context.setState(this); }}Copy the code

(2) Specific state B

Public class ConcreteStateB implements State {ConcreteStateB implements State; public ConcreteStateB() { context = new Context(); } @override public void handle() {system.out.println ("Context is in B state, and start to do something..." ); context.setState(this); }}Copy the code

4. Change the behavior of the context class by changing state

Public class Test {public static void main(String[] args) {// Context Context Context = new Context(); // State State stateA = new ConcreteStateA(); State stateB = new ConcreteStateB(); // Change behavior by state context.setState(stateA); context.request(); context.setState(stateB); context.request(); }}Copy the code

Three, for example

1, the background

Universal Candy intends to use Java to implement candy machine controllers. They wanted the design to be as flexible and maintainable as possible, as more behavior might be added to the candy machine in the future.

The working process of candy machine is as follows:

2, implementation,

(1) Create the status interface and define the corresponding candy machine behavior

Public void insertQuarter(); public void insertQuarter(); /** * return 25 cents */ public void ejectQuarter(); /** * public void crank (); Dispense () public void dispense(); }Copy the code

(2) Create a candy machine

Delegate the request to the candy machine to the status class.

Public class GumballMachine {State soldOutState; State noQuarterState; State hasQuarterState; State soldState; State state = soldOutState; int gumballCount = 0; public GumballMachine(int initGumballCount) { soldOutState = new SoldOutState(this); noQuarterState = new NoQuarterState(this); hasQuarterState = new HasQuarterState(this); soldState = new SoldState(this); // Initialize the number of candies this.gumballCount = initGumballCount; If (initGumballCount > 0) {state = noQuarterState; } else { state = soldOutState; Public void insertQuarter() {state.insertQuarter(); } public void ejectQuarter() {state.ejectQuarter(); } / / public void crank () {stat.crank (); state.dispense(); } public void releaseBall() {system.out.println ("A gumball comes rolling out the slot..." ); if (gumballCount > 0) { gumballCount = gumballCount -1; } } public void setState(State state) { this.state = state; } public int getGumballCount() { return gumballCount; } public State getSoldOutState() { return soldOutState; } public State getNoQuarterState() { return noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public State getSoldState() { return soldState; }}Copy the code

(3) Create a specific state and implement the state interface

*/ public class NoQuarterState implements State {GumballMachine GumballMachine; public NoQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @override public void insertQuarter() {system.out.println ("You inserted a quarter"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } @override public void ejectQuarter() {system.out. println("You haven't inserted a quarter"); } @override public void crank () {// } @override public void dispense() {system.out.println ("You need to pay first"); }}Copy the code
/** * public class quarterstate implements State {GumballMachine GumballMachine; public HasQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @override public void insertQuarter() { Println ("You can't insert another quarter"); } @override public void ejectQuarter() {system.out.println ("Quarter returned"); gumballMachine.setState(gumballMachine.getNoQuarterState()); } @override public void crank () {// turnCrank() {system.out.println ("You turned... ); gumballMachine.setState(gumballMachine.getSoldState()); Override public void dispense() {system.out.println ("No gumball dispensed"); }}Copy the code
/** * implements State {GumballMachine GumballMachine; public SoldState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @override public void insertQuarter() { System.out.println("Please wait, we're already giving you a gumball"); } @override public void ejectQuarter() {system.out.println ("Sorry, you already truned the crank"); } @override public void crank () { Println ("Turning twice doesn't get you another gumball!" ); } @ Override public void dispense () {/ / distributed candy gumballMachine releaseBall (); if (gumballMachine.getGumballCount() > 0) { gumballMachine.setState(gumballMachine.getNoQuarterState()); } else { System.out.println("Oops, out of gumballs!" ); gumballMachine.setState(gumballMachine.getSoldOutState()); }}}Copy the code
*/ public class SoldOutState implements State {GumballMachine GumballMachine; public SoldOutState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @override public void insertQuarter() { System.out.println("You can't insert a quarter, the machine is sold out"); } @override public void ejectQuarter() { Insert a quarter yet ("You can't eject, You haven't inserted a quarter yet"); } @override public void crank () {system.out.println ("You turned, but there are no gumballs"); } @override public void dispense() {system.out.println ("No gumball dispensed"); }}Copy the code

(4) Operate the candy machine

Public class Test {public static void main(String[] args) {GumballMachine GumballMachine = new GumballMachine(5); / / normal operating gumballMachine. InsertQuarter (); gumballMachine.turnCrank(); System.out.println("-----------------------"); / / abnormal operating gumballMachine. InsertQuarter (); gumballMachine.ejectQuarter(); gumballMachine.turnCrank(); }}Copy the code