C# 设计模式-状态模式

状态模式-允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类。

状态模式分为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方法

修改的代码比只添加状态多一点

但是总体来说,不论是添加状态还是添加操作,在逻辑上都是非常清晰的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值