模式十三: 状态模式

 

13.1状态模式定义:

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

13.2状态模式UML类图:

13.3应用场景:

1、当一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。

2、一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

 

  

   

13.4状态模式分析与实现(c#描述):

 

public interface IState

    {

        //动作  状态

        //买票:等待进场验票

        //进场:等待电影开始

        //看电影:等待电影结束

        //出场:等待下一场电影

       

        //引起状态变化的4个动作,这4个动作均是同一Context发出。

        void BuyTicket();

        void Enter();

        void See();

        void Exit();

    }

 

    //Context对象,不同的行为切换不同的状态。

    public class Person

    {

        //将状态对象组合进来

        private IState _waitingForCheckin;

        private IState _waitingForMovieStart;

        private IState _waitingForMovieEnd;

        private IState _waitingForNextMovie;

 

        public IState WaitingForCheckin

        {

            get { return _waitingForCheckin; }

            set { _waitingForCheckin = value; }

        }

       

        public IState WaitingForMovieStart

        {

            get { return _waitingForMovieStart; }

            set { _waitingForMovieStart = value; }

        }

 

        public IState WaitingForMovieEnd

        {

            get { return _waitingForMovieEnd; }

            set { _waitingForMovieEnd = value; }

        }

 

        public IState WaitingForNextMovie

        {

            get { return _waitingForNextMovie; }

            set { _waitingForNextMovie = value; }

        }

 

        private IState CurrentState;//当前状态

 

        public Person()

        {

            //为每个状态初始化一个状态对象,并把当前Context对象传给每一个状态对象。

            this._waitingForCheckin = new WaitingForCheckin(this);

            this._waitingForMovieStart = new WaitingForMovieStart(this);

            this._waitingForMovieEnd = new WaitingForMovieEnd(this);

            this._waitingForNextMovie = new WaitingForNextMovie(this);

 

            this.CurrentState = this._waitingForNextMovie;//设置一开始的当前状态为等待下一场电影状态。

        }

 

        public void BuyTicket()//买票

        {

            this.CurrentState.BuyTicket();       

        }

 

        public void Enter()//进场

        {

            this.CurrentState.Enter();

        }

 

        public void See()//看电影

        {

            this.CurrentState.See();

        }

 

        public void Exit()//出场

        {

            this.CurrentState.Exit();

        }

 

        public void SetState(IState aobj_State)//设置当前状态

        {

            this.CurrentState = aobj_State;

        }

    }

 

 

    public class WaitingForCheckin:IState

    {

        private Person iobj_Person;

        public WaitingForCheckin(Person aobj_Person)

        {

            this.iobj_Person = aobj_Person;

        }

 

        public void BuyTicket()

        {

            Console.WriteLine("这个操作不允许:已经买过票了。");

        }

 

        public void Enter()

        {

            Console.WriteLine("进场吧,呵呵。");

            this.iobj_Person.SetState(this.iobj_Person.WaitingForMovieStart);//状态转换

        }

 

        public void See()

        {

            Console.WriteLine("这个操作不允许:还没进场呢。");

 

        }

 

        public void Exit()

        {

            Console.WriteLine("这个操作不允许:电影都没看呢。");

        }

   

    }

 

    public class WaitingForMovieStart : IState

    {

        private Person iobj_Person;

        public WaitingForMovieStart(Person aobj_Person)

        {

            this.iobj_Person = aobj_Person;

        }

 

        public void BuyTicket()

        {

            Console.WriteLine("这个操作不允许:已经买过票了。");

        }

 

        public void Enter()

        {

            Console.WriteLine("这个操作不允许:已经进场了。");

        }

 

        public void See()

        {

            Console.WriteLine("开始看电影吧。");

            this.iobj_Person.SetState(this.iobj_Person.WaitingForMovieEnd);//状态转换

        }

 

        public void Exit()

        {

 

            Console.WriteLine("这个操作不允许:电影还没看完呢。");

        }

    }

 

    public class WaitingForMovieEnd : IState

    {

 

        private Person iobj_Person;

        public WaitingForMovieEnd(Person aobj_Person)

        {

            this.iobj_Person = aobj_Person;

        }

 

        public void BuyTicket()

        {

            Console.WriteLine("这个操作不允许:已经买过票了。");

        }

 

        public void Enter()

        {

            Console.WriteLine("这个操作不允许:已经进场了。");

        }

 

        public void See()

        {

            Console.WriteLine("这个操作不允许:已经看完电影了。");

 

        }

 

        public void Exit()

        {

            Console.WriteLine("出场吧,呵呵。");

            this.iobj_Person.SetState(this.iobj_Person.WaitingForNextMovie);//状态转换

 

        }

    }

 

 

    public class WaitingForNextMovie : IState

    {

        private Person iobj_Person;

        public WaitingForNextMovie(Person aobj_Person)

        {

            this.iobj_Person = aobj_Person;

        }

 

        public void BuyTicket()

        {

            Console.WriteLine("现在可以买票了。");

            this.iobj_Person.SetState(this.iobj_Person.WaitingForCheckin);//状态转换

        }

 

        public void Enter()

        {

            Console.WriteLine("这个操作不允许:还没买票呢。");

        }

 

        public void See()

        {

            Console.WriteLine("这个操作不允许:还没进场呢。");

        }

 

        public void Exit()

        {

            Console.WriteLine("这个操作不允许:已经出场了。");

        }

    }

 

    //调用类

    public class State_Test

    {

        public static void Do()

        {

            //测试1,输出:现在可以买票了。  进场吧,呵呵。  开始看电影吧。  出场吧,呵呵。

            Person lobj_Person = new Person();

            lobj_Person.BuyTicket();

            lobj_Person.Enter();

            lobj_Person.See();

            lobj_Person.Exit();

 

            //测试2,输出:这个操作不允许:还没买票呢。  现在可以买票了。 这个操作不允许:电影都没看呢。这个操作不允许:还没进场呢。

            lobj_Person.Enter();

            lobj_Person.BuyTicket();

            lobj_Person.Exit();

            lobj_Person.See();          

        }

 }

 

状态模式和策略模式的区别:

状态模式和策略模式的类图是一样的,但这两个模式的差别在于他们的意图。一般来说,我们把策略模式想成是一种除了继承之外的弹性替代方案。如果使用继承定义一个类的行为,你将被这个行为困住,甚至要修改他都很难。有了策略模式,就可以组合不同的对象来改变行为。而状态模式是不用在Context中放置许多条件判断的替代方案。通过将行为包装进状态对象中,你可以通过Context中简单地改变状态对象来改变Context的行为。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值