[State mode] State Pattern, statepattern

Source: Internet
Author: User

[State mode] State Pattern, statepattern

Let's first design a scenario where the beverage vending machine will design its sales process.

In the flowchart, we can regard this process as several states: coin status, select the beverage status, sales status, and sales completion status.

With these four statuses, we can design the interface (very rough ):

 

Here we only define three drinks and one coin port. Before designing interfaces and classes, let's take a look at the UML diagram of the state mode:

 

 

 

The State interface defines a common interface for all specific States. All States implement the same interface, so that States can be replaced by each other.

ConcreteState (specific State) Processes requests from Context. Each ConcreteState provides its own implementation of the request. Therefore, the behavior also changes when the Context changes.

Context is a class that can have some internal states.

 

Based on the mature state mode UML diagram, we design our own UML class diagram:

 

Code directly (it may be a little different from the UML diagram. With some more parameters, the diagram mainly uses an architecture)

 

Entity class:

Public class SoftDrink {public string Name {get; set;} public int Price {get; set;} public int Count {get; set ;} private SoftdrinkMachineContext _ context = new SoftdrinkMachineContext (); public SoftdrinkMachineContext Context {get {return _ context ;}}}View Code

 

Create a factory for obtaining a certain beverage:

Public class SoftDrinkFactory {public static SoftDrink GetSoftDrink (string softDrinkName) {SoftDrink softDrink = SoftDrinkRepository. softDrinks. singleOrDefault (s => s. name. equals (softDrinkName); if (softDrink = null) throw new ArgumentException (string. format ("this beverage is not available: {0}", softDrinkName); return softDrink ;}}View Code

 

Beverage Repository

Public class SoftDrinkRepository {static SoftDrinkRepository () {SoftDrinks = new List <SoftDrink> (); AddSoftDrink (new SoftDrink {Name = "Cola", Count = 5, Price = 3 }); addSoftDrink (new SoftDrink {Name = "Fruit orange", Count = 1, Price = 3}); AddSoftDrink (new SoftDrink {Name = "coffee", Count = 5, price = 3});} public static List <SoftDrink> SoftDrinks {get; private set;} public static void AddSoftDrink (SoftDrink softDrink) {if (SoftDrinks. any (s => s. name. equals (softDrink. name) {SoftDrink needtobeAddedSoftdrink = SoftDrinks. single (s => s. name. equals (softDrink. name); needtobeAddedSoftdrink. price = softDrink. price; needtobeAddedSoftdrink. count = softDrink. count;} SoftDrinks. add (softDrink );}}View Code

 

The deposit here is equivalent to a bank, which uses static

Public class Constants {public static int StoredMoney {get; set ;}}View Code

 

Interface:

Public interface ISoftdrinkState {void InsertQuarter (); void SelectSoftdrink (SoftDrink softDrink); void Dispense (SoftDrink softDrink); void SoldOut ();}View Code

 

The four implementation classes here represent four states. The entire state switch is automatically completed internally.

Public abstract class partition: protected {protected SoftdrinkMachineContext _ softdrinkMachineContext; protected partition (SoftdrinkMachineContext softdrinkMachineContext) {_ partition = softdrinkMachineContext;} public abstract void InsertQuarter (); public abstract void SelectSoftdrink (SoftDrink softDrink); public abstract void Dispense (S OftDrink softDrink); public abstract void SoldOut ();} public class NoQuarterState: writable {public NoQuarterState (writable SoftdrinkMachineContext): base (softdrinkMachineContext) {} public override void InsertQuarter () {_ softdrinkMachineContext. setState (_ softdrinkMachineContext. hasQuarterState);} public override void SelectSoftdrink (SoftDrink softDrink ){ Throw new InvalidOperationException ("you need to pay first");} public override void Dispense (SoftDrink softDrink) {throw new InvalidOperationException ("you need to pay first ");} public override void SoldOut () {throw new InvalidOperationException ("you need to pay first") ;}} public class HasQuarterState: nation {public HasQuarterState (SoftdrinkMachineContext softdrinkMachineContext): base (region) {} Public override void InsertQuarter () {} public override void SelectSoftdrink (SoftDrink softDrink) {if (softDrink. price> Constants. storedMoney) throw new InvalidOperationException ("not enough money, please reselect or supplement"); _ softdrinkMachineContext. setState (_ softdrinkMachineContext. soldState);} public override void Dispense (SoftDrink softDrink) {throw new InvalidOperationException ("You need to select a drink first");} public override void SoldOut () {throw new InvalidOperationException ("You need to select a drink first");} public class SoldState: AbstractSoftdrinkMacheState {public SoldState (SoftdrinkMachineContext softdrinkMachineContext): base) {} public override void InsertQuarter () {throw new InvalidOperationException ("click to finish selecting");} public override void SelectSoftdrink (SoftDrink softDrink) {throw new InvalidOperationE Xception ("click to finish selecting");} public override void Dispense (SoftDrink softDrink) {softDrink. count --; Constants. storedMoney-= softDrink. price; _ softdrinkMachineContext. setState (softDrink. count> 0? _ SoftdrinkMachineContext. noQuarterState: _ softdrinkMachineContext. soldOutState);} public override void SoldOut () {throw new InvalidOperationException ("click to finish selecting") ;}} public class SoldOutState: writable {public SoldOutState (SoftdrinkMachineContext softdrinkMachineContext ): base (softdrinkMachineContext) {} public override void InsertQuarter () {} public override void SelectSoftdrink (SoftDrink softDrink) {throw new InvalidOperationException ("sold out ");} public override void Dispense (SoftDrink softDrink) {throw new InvalidOperationException ("sold out");} public override void SoldOut () {throw new InvalidOperationException ("sold out ");}}View Code

 

Context

Public class SoftdrinkMachineContext {private partition _ state; public SoftdrinkMachineContext () {NoQuarterState = new NoQuarterState (this); SoldOutState = new SoldOutState (this); HasQuarterState = new HasQuarterState (this ); soldState = new SoldState (this); _ state = NoQuarterState;} public ISoftdrinkState SoldOutState {get; private set;} public ISoftdrinkState NoQuarterState {get; private set;} public writable HasQuarterState {get; private set;} public ISoftdrinkState SoldState {get; private set;} public void InsertQuarter () {_ state. insertQuarter ();} public void SelectSoftdrink (SoftDrink softDrink) {_ state. selectSoftdrink (softDrink);} public void Dispense (SoftDrink softDrink) {_ state. dispense (softDrink);} public void SoldOut () {_ state. soldOut ();} public void SetState (ISoftdrinkState state) {_ state = state ;}}View Code

 

Form window class

Public partial class Form1: Form {private SoftDrink _ currSoftDrink; public Form1 () {InitializeComponent ();} private void button#click (object sender, EventArgs e) {ActionWithAlertingErrorInfo (() =>{ _ currSoftDrink. context. dispense (_ currSoftDrink); MessageBox. show (string. format ("exit {0} money", Constants. storedMoney); Constants. storedMoney = 0 ;});} private void btnInputMoney_Click (object sender, EventArgs e) {var money = 0; if (int. tryParse (txtMoneyInput. text, out money) {Constants. storedMoney + = money; ActionWithAlertingErrorInfo () => SoftDrinkRepository. softDrinks. forEach (c => c. context. insertQuarter ();} private void btnCoke_Click (object sender, EventArgs e) {var btn = sender as Button; var index = btn. text. indexOf ("(", StringComparison. ordinal); var softDrinkName = btn. text. substring (0, index); _ currSoftDrink = SoftDrinkFactory. getSoftDrink (softDrinkName); ActionWithAlertingErrorInfo () => _ currSoftDrink. context. selectSoftdrink (_ currSoftDrink);} public void ActionWithAlertingErrorInfo (Action action) {try {action. invoke ();} catch (Exception ex) {MessageBox. show (ex. message );}}View Code

A Softdrink class is added here. Because each beverage has its own status, a context class is required for each beverage.

 

Postscript:

A friend recently told me how she thought the rule mode and the state mode were the same. Since the names are different, the functions are definitely different. How should we differentiate them.

The rule mode and the state mode can be said to be sibling, but there are some differences in nature.

Policy mode-> define algorithm families, encapsulate them separately, so that they can be replaced with each other (manually). This mode allows algorithm changes to be independent of algorithm customers.

State mode-> allows an object to change its behavior when its internal state changes (automatically). The object seems to have modified its class.

That is to say, the State mode uses many different State objects. When the Context object changes over time, any state changes are well defined. In other words, "changing behavior" is based on my state mode scheme, and the policy mode does not have a set of state tags, which are mostly used by callers.


What is the use of State Pattern?

It is one of the object-oriented design patterns: State Mode
See the following:
1. Introduction to status mode (Brief Introduction)
State Pattern allows an object to change its behavior when its internal State changes. This object looks like it has changed its class.

2. What To Solve)
The State mode mainly solves the problem when the conditional expressions that control the status of an object are too complex. Transferring the status judgment logic to a series of classes that indicate different states can simplify the complicated judgment logic.

When an object's behavior depends on its state, and it must change its behavior according to its state at runtime, you can consider using the state mode.

Iii. Analysis)
1. Status mode structure

Context class: maintains an instance of the ConcreteState subclass, which defines the current state.

State Class: abstract State class, which defines an interface to encapsulate a behavior related to a specific State of Context.

ConcreteStateA, ConcreteStateB, and ConcreteStateC classes: a specific state class. each subclass implements a state-related behavior related to the Context.

Java 23 design modes

There are three types of design patterns: creation, structure, and behavior.
The creation types include:
I. Singleton, Singleton mode: ensure that a class has only one instance and provide a global access point to it.
2. Abstract Factory: provides an interface for creating a series of related or mutually dependent objects without specifying their specific classes.
3. Factory Method: Define an interface used to create objects, and let the subclass decide which class to instantiate. Factory Method delays the instantiation of a class to the subclass.
4. Builder: separates the construction of a complex object from its representation, so that different representations can be created during the same construction process.
5. Prototype: Use a Prototype instance to specify the type of the object to be created, and copy the Prototype to create a new object.
Behavior types:
6. Iterator: provides a method to access each element of an aggregate object sequentially without exposing the internal representation of the object.
7. Observer: Observer mode: defines one-to-many dependencies between objects. When the status of an object changes, all objects dependent on it will be automatically updated by notification.
8. Template Method: defines the skeleton of an algorithm in an operation, and delays some steps to the subclass, templateMethod allows the subclass to redefine a specific step without changing the structure of an algorithm.
9. Command: encapsulate a request as an object so that you can parameterize the customer with different requests, queue requests and record request logs, and supports unrecoverable operations.
10. State: allows an object to change its behavior when its internal State changes. The object seems to have changed its class.
11. Strategy: Define a series of algorithms, encapsulate them one by one, and enable them to replace each other. This mode allows algorithms to be independent of customers who use them.
12. China of Responsibility, Responsibility chain mode: Enables multiple objects to process requests to avoid coupling between the request sender and receiver.
13. Mediator: uses an intermediary object to encapsulate object interaction of some columns.
14. Visitor, Visitor mode: indicates an operation that acts on each element in an object structure. It allows you to define new operations that act on this element without changing the element classes.
15th, Interpreter, Interpreter mode: a language is defined to define a representation of its grammar and an Interpreter. This Interpreter uses this representation to explain sentences in the language.
16. Memento: capture the internal state of an object without interrupting the object, and save the state outside the object.
There are:
17. Composite: Composite combines objects into a tree structure to represent the relationship between parts of the whole. Composite makes the use of a single object and a Composite object consistent.
18. Facade, appearance mode: provides a consistent interface for a group of interfaces in the subsystem. fa? Ade provides a high-level interface, which makes the subsystem easier to use.
19. Proxy: provides a Proxy for other objects to control access to this object.
20. Adapter: the Adapter mode converts a class of interfaces into another interface that the customer wants. The Adapter mode makes those classes unable to work together due to interface incompatibility.
21. Decrator: the Decorator mode dynamically adds some additional responsibilities to an object. In terms of the added functions, the Decorator mode is more flexible than the subclass generation mode.
22. Bridge: link the abstract Part with its implementation... the remaining full text>

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.