【设计模式】——状态模式

【状态模式】

 

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类

 

【介绍】

  • 意图:允许对象在内部状态发生改变它的行为,对象看起来好像修改了它的类

  • 主要解决:当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化

  • 何时使用:代码中包含大量与对象状态有关的条件语句

  • 如何解决:将各种具体的状态类抽象出来

  • 关键代码:通常命令模式的接口中只有一个方法,而状态模式的接口中有一个或者多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和命令模式一样,也可以用于消除if…else等条件选择语句

  • 优点:1、封装了转换规则;2、枚举可能的状态;3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。5、可以让多个环节对象共享一个状态对象,从而减少系统中对象的个数

  • 缺点:1、状态模式的使用必然会增加系统类和对象的个数。2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。3、状态模式对“开闭原则”的支持并不友好,对于可以切换状态的状态模式,增加新的状态需要修改那些负责状态转换的遇到吗,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源代码

  • 使用场景:行为随状态改变而改变的场景;条件、分支语句的代替者

  • 注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过5个

 

【实现】

 

 

步骤一: state类,抽象状态类,定义一个接口以封装与context一个特定状态相关行为


  

  abstract class State

    {

        public abstract void Handle(Context context);

    }

步骤二:concretestate类,具体状态,每一个子类实现一个与context的一个状态相关的行为

 

 class ConcreteStateA:State

    {

        public override void Handle(Context context)

        {

            context.State = new ConcreteStateB();



       

        }

    }

    class ConcreteStateB : State

    {

        public override void Handle(Context context)

        {

            context.State = new ConcreteStateA();





        }

    }

步骤三:Context类,维护一个Concretestate子类的实例

 

class Context

    {

        private State state;

        public Context(State state)//定义context的初始状态

        {

            this.state = state;

        }

        public State State//可读写的状态属性,用于读取当前状态和设置新状态

        {

            get { return state; }

            set

            {

                state = value;

                Console.WriteLine("当前状态:"+ state.GetType().Name);

            }

        }

        public void Request()

        {

            state.Handle(this);//对请求做处理,并设置一下状态

        }

    }

步骤四:客户端代码


 

static void Main(string[] args)

        {

            Context C = new Context(new ConcreteStateA());//设置context的初始状态为concretestateA

            C.Request();

            C.Request();

            C.Request();

            C.Request();

            C.Request();

            C.Request();

            Console.Read();

        }

【总结】

 

将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所有通过定义新的子类可以很容易地增加新的状态和转换

状态模式通过把各种状态转换逻辑分不到state的子类之间,来减少相互间的依赖

当一个对象的行为取决于它的状态,并且他必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值