C# 设计模式———状态模式

状态模式简介

当一个对象内在状态改变时允许其改变行为,这个对象看起来像时改变了其类。状态模式可实现:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

状态模式解决了代码中包含大量与对象状态有关的条件语句。
在这里插入图片描述

优点: 缺点:
1. 封装了转换规则 1. 状态模式的使用必然会增加系统类和对象的个数
2. 枚举可能的状态,在枚举状态之前需要确定状态种类 2. 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱
3. 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为 3. 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码
4. 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块 /
5. 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。 /

C# 状态模式Demo模板

在这里插入图片描述

using System;
namespace StatePattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Context context = new Context();
            context.State = new ConcreteState1();

            context.Request();
            context.Request();
            context.Request();
            context.Request();
            context.Request();
            context.Request();
            context.Request();
            context.Request();
            context.Request();

        }
    }

    public abstract class AbstractState
    {
        public abstract void Handler(Context context);
    }

    public class ConcreteState1 : AbstractState
    {
        public override void Handler(Context context)
        {
            context.State = new ConcreteState2();
        }
    }

    public class ConcreteState2 : AbstractState
    {
        public override void Handler(Context context)
        {
            context.State = new ConcreteState3();
        }
    }

    public class ConcreteState3 : AbstractState
    {
        public override void Handler(Context context)
        {
            context.State = new ConcreteState1();
        }
    }

    public class Context
    {
        private AbstractState state;
        public AbstractState State
        {
            get { return state; }
            set { state = value; Console.WriteLine("当前状态:{0}", State.GetType().Name ); }
        }

        public void Request()
        {
            this.State.Handler(this);
        }
    }    
}

测试结果:
在这里插入图片描述

C# 实现qq邮箱日历问候语

在这里插入图片描述

using System;
namespace StatePattern
{
    /// <summary>
    /// 状态模式   实现qq邮箱  时间问候语显示
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Context context = new Context(20);                 // 设置时间 Hour=20;
            context.State = new MorningState();
              
            context.Request();
            Console.WriteLine("----------------------");

            context.Hour = 15;
            context.Request();
            Console.WriteLine("----------------------");

            context.Hour = 10;
            context.Request();
            Console.WriteLine("----------------------");

        }
    }

    public abstract class AbstractState
    {
        public abstract void Handler(Context context);
    }

    public class MorningState : AbstractState
    {
        public override void Handler(Context context)
        {
            if( context.Hour%24 > 9 && context.Hour%24 <= 12)
            {
                Console.WriteLine("早上好");
            }
            else
            {
                context.State = new AfternoonState();
                context.Request();
            }           
        }
    }

    public class AfternoonState : AbstractState
    {
        public override void Handler(Context context)
        {
            if (context.Hour % 24 > 12 && context.Hour % 24 <= 18)
            {
                Console.WriteLine("下午好");
            }
            else
            {
                context.State = new EveningState();
                context.Request();
            }
        }
    }

    public class EveningState : AbstractState
    {
        public override void Handler(Context context)
        {
            if (context.Hour % 24 > 18 && context.Hour % 24 < 24)
            {
                Console.WriteLine("晚上好");
            }
            else
            {
                context.State = new MorningState();
                context.Request();
            }
        }
    }

    public class Context
    {
        private int hour;
        public int Hour
        {
            get; set;
        }

        public Context(int nowHour)
        {
            this.Hour = nowHour;
        }

        
        private AbstractState state;
        public AbstractState State
        {
            get { return state; }
            set { state = value; Console.WriteLine("当前状态:{0}", State.GetType().Name ); }
        }

        public void Request()
        {
            this.State.Handler(this);
        }
    }    
}

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

参考资料

https://m.runoob.com/design-pattern/state-pattern.html
https://www.bilibili.com/video/av78515440?p=16

发布了22 篇原创文章 · 获赞 20 · 访问量 2950

猜你喜欢

转载自blog.csdn.net/chasinghope/article/details/104262441