State Pattern (11)
状态模式:
当一个对象的状态改变时,允许其行为也进行相应的变化。
示例代码:
using System;
using
System.Text;
using
System.IO;
using
System.Collections.Generic;
namespace Hello
{
//GumballMachine class
public class GumballMachine
{
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State state;
int count = 0;
public GumballMachine(int
gumballsNumber)
{
state =
soldOutState;
soldOutState
= new SoldOutState(this);
noQuarterState
= new NoQuarterState(this);
hasQuarterState
= new HasQuarterState(this);
soldState = new SoldState(this);
count =
gumballsNumber;
if (gumballsNumber > 0)
{
state =
noQuarterState;
}
}
public void
InserQuarter()
{
state.InsertQuarter();
}
public void
EjectQuarter()
{
state.InsertQuarter();
}
public void
TurnCrank()
{
state.TurnCrank();
state.Dispense();
}
public State
GetHasQuarterState()
{
return hasQuarterState;
}
public State
GetNoQuarterState()
{
return noQuarterState;
}
public State
GetSoldState()
{
return soldState;
}
public State
GetSoldOutState()
{
return soldOutState;
}
public void SetState(State state)
{
this.state = state;
}
public void
ReleaseBall()
{
Console.WriteLine("A
gumball comes rolling out the slot...");
if (count != 0)
{
count -=
1;
}
}
public int GetCount()
{
return count;
}
}
//State Interface
public interface State
{
void InsertQuarter();
void EjectQuarter();
void TurnCrank();
void Dispense();
}
//NoQuarterState
public class NoQuarterState : State
{
GumballMachine gumballMachine;
public NoQuarterState(GumballMachine
gumballMachine)
{
this.gumballMachine = gumballMachine;
}
public void
InsertQuarter()
{
Console.WriteLine("You
insert a quarter.");
gumballMachine.SetState(gumballMachine.GetHasQuarterState());
}
public void
EjectQuarter()
{
Console.WriteLine("You
haven't insert a quarter!");
}
public void
TurnCrank()
{
Console.WriteLine("You
turned, but there is no quarter");
}
public void
Dispense()
{
Console.WriteLine("You
need to pay first.");
}
}
//SoldOutState
public class SoldOutState : State
{
GumballMachine gumballMachine;
public SoldOutState(GumballMachine
gumballMachine)
{
this.gumballMachine = gumballMachine;
}
public void
InsertQuarter()
{
Console.WriteLine("You
can not insert a quarter, the machine is sold out.");
}
public void
EjectQuarter()
{
Console.WriteLine("You
can not eject, you haven't inserted a quarter yet.");
}
public void
TurnCrank()
{
Console.WriteLine("You
turned, but there are no gumballs.");
}
public void
Dispense()
{
Console.WriteLine("No
gumball dispensed.");
}
}
//HasQuarterState
public class HasQuarterState : State
{
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine
gumballMachine)
{
this.gumballMachine = gumballMachine;
}
public void
InsertQuarter()
{
Console.WriteLine("You
can not insert another quarter.");
}
public void
EjectQuarter()
{
Console.WriteLine("Quarter
returned.");
gumballMachine.SetState(gumballMachine.GetNoQuarterState());
}
public void
TurnCrank()
{
Console.WriteLine("You
turned.");
gumballMachine.SetState(gumballMachine.GetSoldState());
}
public void
Dispense()
{
Console.WriteLine("No
gumball dispensed.");
}
}
//SoldState
public class SoldState : State
{
GumballMachine gumballMachine;
public SoldState(GumballMachine
gumballMachine)
{
this.gumballMachine = gumballMachine;
}
public void
InsertQuarter()
{
Console.WriteLine("Please
wait, we are already geving you a gumball.");
}
public void
EjectQuarter()
{
Console.WriteLine("Sorry,
you already turned the crank.");
}
public void
TurnCrank()
{
Console.WriteLine("Turn
twice doesn't give you another gumball!");
}
public void
Dispense()
{
gumballMachine.ReleaseBall();
if (gumballMachine.GetCount() > 0)
{
gumballMachine.SetState(gumballMachine.GetNoQuarterState());
}
else
{
Console.WriteLine("Oops,
out of gumballs!");
gumballMachine.SetState(gumballMachine.GetSoldOutState());
}
}
}
class Program
{
static void Main(string[] args)
{
GumballMachine gumballMachine = new GumballMachine(2);
gumballMachine.InserQuarter();
gumballMachine.TurnCrank();
gumballMachine.InserQuarter();
gumballMachine.TurnCrank();
gumballMachine.InserQuarter();
gumballMachine.TurnCrank();
}
}
}