Usage examples: The State pattern is commonly used in C# to convert massive switch-base state machines into objects.
Identification: State pattern can be recognized by methods that change their behavior depending on the objects’ state, controlled externally.
Conceptual Example
This example illustrates the structure of the State design pattern. It focuses on answering these questions:
What classes does it consist of?
What roles do these classes play?
In what way the elements of the pattern are related?
Program.cs: Conceptual example
usingSystem;namespaceRefactoringGuru.DesignPatterns.State.Conceptual{ // The Context defines the interface of interest to clients. It also // maintains a reference to an instance of a State subclass, which // represents the current state of the Context.classContext { // A reference to the current state of the Context.privateState _state =null;publicContext(State state) {this.TransitionTo(state); } // The Context allows changing the State object at runtime.publicvoidTransitionTo(State state) {Console.WriteLine($"Context: Transition to {state.GetType().Name}.");this._state= state;this._state.SetContext(this); } // The Context delegates part of its behavior to the current State // object.publicvoidRequest1() {this._state.Handle1(); }publicvoidRequest2() {this._state.Handle2(); } } // The base State class declares methods that all Concrete State should // implement and also provides a backreference to the Context object, // associated with the State. This backreference can be used by States to // transition the Context to another State.abstractclassState {protectedContext _context;publicvoidSetContext(Context context) {this._context= context; }publicabstractvoidHandle1();publicabstractvoidHandle2(); } // Concrete States implement various behaviors, associated with a state of // the Context.classConcreteStateA:State {publicoverridevoidHandle1() {Console.WriteLine("ConcreteStateA handles request1.");Console.WriteLine("ConcreteStateA wants to change the state of the context.");this._context.TransitionTo(newConcreteStateB()); }publicoverridevoidHandle2() {Console.WriteLine("ConcreteStateA handles request2."); } }classConcreteStateB:State {publicoverridevoidHandle1() {Console.Write("ConcreteStateB handles request1."); }publicoverridevoidHandle2() {Console.WriteLine("ConcreteStateB handles request2.");Console.WriteLine("ConcreteStateB wants to change the state of the context.");this._context.TransitionTo(newConcreteStateA()); } }classProgram {staticvoidMain(string[] args) { // The client code.var context =newContext(newConcreteStateA());context.Request1();context.Request2(); } }}
Output.txt: Execution result
Context: Transition to ConcreteStateA.
ConcreteStateA handles request1.
ConcreteStateA wants to change the state of the context.
Context: Transition to ConcreteStateB.
ConcreteStateB handles request2.
ConcreteStateB wants to change the state of the context.
Context: Transition to ConcreteStateA.