Intention
Allows an object to change its behavior when its internal state changes. The object appears to modify its class.
Scene
We are in the production of an online bookstore site, users in the bookstore bought a certain amount of books can be upgraded to Silver members, gold members, different levels of members buy books have different concessions. You might think that you can judge the amount of user history consumption in the Buybook method of the users to give users a different discount, and in the Getuserlevel method, the level of the user is exported based on the amount of user history consumed. There are three points to be posed:
L do not use the level of the user to give preferential rate is often changed, once the change is not going to modify the user class?
L site at the beginning may be the highest level of users are gold members, and with the cumulative amount of user consumption, we may want to increase the number of diamond, platinum and other types of membership, these members of the discount is different, such a change is not going to modify the user class it?
I put aside the change does not say that the user class assume the level of users to judge, purchase discount calculation and other complex logic, complex user code maintainability will be very good?
By separating the state of object and object, the transformation of object state and the behavior produced by different states to the specific State class are introduced to solve the problem.
Sample code
using System;
using System.Collections.Generic;
using System.Text;
namespace Stateexample
{
Class Program
{
static void Main (string[] args)
{
User user = New User ("Zhuye");
user. Buybook (2000);
user. Buybook (2000);
user. Buybook (2000);
user. Buybook (2000);
}
}
class User
{
private UserLevel UserLevel;
Public UserLevel UserLevel
{
get {return userLevel;}
set {userLevel = value;}
}
private String UserName;
private double Paidmoney;
public Double Paidmoney
{
get {return Paidmoney;}
}
public User (string userName)
{
this.username = userName;
This.paidmoney = 0;
this. UserLevel = new Normaluser (this);
}
public void Buybook (double amount)
{
Console.WriteLine (String. Format ("Hello {0}, have paid ${1}, you are {2}.", UserName, Paidmoney, UserLevel. GetType (). Name));
double realamount = userLevel. Calcrealamount (amount);
Console.WriteLine ("You are paid $" + Realamount + "for this book.");
Paidmoney + = Realamount;
UserLevel. Statecheck ();
}
}
Abstract class UserLevel
{
protected User User;
public UserLevel (user user)
{
this.user = user;
}
public abstract void Statecheck ();
public abstract double Calcrealamount (double amount);
}
class Diamonduser:userlevel
{
public diamonduser (user user)
: Base (user) {}
public override double Calcrealamount (double amount)
{
return amount * 0.7;
}
public override void Statecheck ()
{
}
}
class Golduser:userlevel
{
public golduser (user user)
: Base (user) {}
public override double Calcrealamount (double amount)
{
return amount * 0.8;
}
public override void Statecheck ()
{
if (user. Paidmoney > 5000)
user. UserLevel = new Diamonduser (user);
}
}
class Silveruser:userlevel
{
public silveruser (user user)
: Base (user) {}
public override double Calcrealamount (double amount)
{
return amount * 0.9;
}
public override void Statecheck ()
{
if (user. Paidmoney > 2000)
user. UserLevel = new Golduser (user);
}
}
class Normaluser:userlevel
{
public normaluser (user user)
: Base (user) {}
public override double Calcrealamount (double amount)
{
return amount * 0.95;
}
public override void Statecheck ()
{
if (user. Paidmoney > 1000)
user. UserLevel = new Silveruser (user);
}
}
}