状态模式-允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类。
状态模式分为2个部分,一个部分是状态,一个部分是动作。
状态是唯一的,某一时刻只能处于一种状态。任何状态都可以执行相同的方法,当然处在不同的状态执行相同的动作结果可能一样也可能不一样。
先看一张图
状态:1,2,3,4
动作:上下左右
当处在状态1时,可以按上下左右4个键,但是只有右和下可以正确运行,并将状态转换成另外的状态。
下面用代码来表示:
先定义一个状态接口(这个接口表示的一种共有的约定,可以是Interface,也可以是基类),里面包含了上下左右四种行为。每一个状态都需要继承此接口
public abstract class State
{
public abstract void Up();
public abstract void Down();
public abstract void Left();
public abstract void Right();
}
先看其中一个状态 状态1
public class One:State
{
public override void Up()
{
Console.WriteLine("forbidden");
}
public override void Down()
{
Console.WriteLine("Three");
}
public override void Left()
{
Console.WriteLine("forbidden");
}
public override void Right()
{
Console.WriteLine("Two");
}
}
当处在状态1时,只能执行Down和Right,然后我们需要把状态改为另外的状态了,下面就需要实现此功能了。
先看一下调用类Game
public class Game
{
//当前状态
public State State {get; set; }
//所有可能的状态
public State One { get; set; }
public State Two { get; set; }
public State Three { get; set; }
public State Four { get; set; }
public Game()
{
//状态初始化
One = new One(this);
Two = new Two(this);
Three = new Three(this);
Four = new Four(this);
//设定初始状态为One
State = One;
}
//定义所有的方法
public void Up()
{
State.Up();
}
public void Down()
{
State.Down();
}
public void Left()
{
State.Left();
}
public void Right()
{
State.Right();
}
}
首先我定义了我所有可能处于的状态One,Two,Three,Four,然后需要定义一个当前的状态。
这个当前状态非常重要,我们每一次执行完操作,都需要改变这个当前状态。
然后修改状态类:
public class One:State
{
private readonly Game _game;
public One(Game game)
{
_game = game;
}
public override void Up()
{
Console.WriteLine("forbidden");
}
public override void Down()
{
_game.State = _game.Four;
Console.WriteLine("Three");
}
public override void Left()
{
Console.WriteLine("forbidden");
}
public override void Right()
{
_game.State = _game.Two;
Console.WriteLine("Two");
}
}
public class Two : State
{
private readonly Game _game;
public Two(Game game)
{
_game = game;
}
public override void Up()
{
Console.WriteLine("forbidden");
}
public override void Down()
{
_game.State = _game.Five;
Console.WriteLine("Four");
}
public override void Left()
{
_game.State = _game.One;
Console.WriteLine("One");
}
public override void Right()
{
Console.WriteLine("forbidden");
}
}
public class Three : State
{
private readonly Game _game;
public Three(Game game)
{
_game = game;
}
public override void Up()
{
_game.State = _game.One;
Console.WriteLine("One");
}
public override void Down()
{
Console.WriteLine("forbidden");
}
public override void Left()
{
Console.WriteLine("forbidden");
}
public override void Right()
{
_game.State = _game.Five;
Console.WriteLine("Four");
}
}
public class Four : State
{
private readonly Game _game;
public Four(Game game)
{
_game = game;
}
public override void Up()
{
_game.State = _game.Two;
Console.WriteLine("Two");
}
public override void Down()
{
Console.WriteLine("forbidden");
}
public override void Left()
{
_game.State = _game.Four;
Console.WriteLine("Three");
}
public override void Right()
{
Console.WriteLine("forbidden");
}
}
调用:
static void Main(string[] args)
{
//起始为状态 One
Game game = new Game();
//无法向上
game.Up();
//-> Three
game.Down();
//-> Four
game.Right();
//-> Two
game.Up();
//->无法向上
game.Up();
//-> One
game.Left();
Console.ReadLine();
}
添加一种状态
状态5只能向上
public class Five : State
{
private readonly Game _game;
public Five(Game game)
{
_game = game;
}
public override void Up()
{
_game.State = _game.Four;
Console.WriteLine("Four");
}
public override void Down()
{
Console.WriteLine("forbidden");
}
public override void Left()
{
Console.WriteLine("forbidden");
}
public override void Right()
{
Console.WriteLine("forbidden");
}
}
然后修改调用类
为忘了修改Four,原来不能向下,现在可以了
所以新添加一种状态非常简单
新添加一种操作
添加一个复位操作,每次一点击,都会回到状态 1
在接口中新建一个复位操作
在调用类中新增一个方法
然后在每个状态中重写Reset方法
修改的代码比只添加状态多一点
但是总体来说,不论是添加状态还是添加操作,在逻辑上都是非常清晰的