状态模式

一、定义

允许一个对象在其内部状态改变时改变它的行为,从而使对象看起来似乎修改了它的类。

二、UML类图

 

  • Context:上下文环境,定义客户程序需要的接口,并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的 ConcreteState对象来处理;

  • State:抽象状态,定义特定状态对应行为的接口;

  • ConcreteState:具体状态,实现抽象状态定义的接口。

三、示例

实现一个交通灯调度程序,灯的颜色需要在红灯->绿灯->黄灯->红灯之间循环转换,但是不允许绿灯->红灯或黄灯->绿灯等情况。

 代码:

1.TrafficLight.cs

public class TrafficLight
    {
        private TrafficLightState _currentState;

        public TrafficLight()
        {
            _currentState = new RedState();
        }

        public void Turn()
        {
            if (_currentState != null)
            {
                _currentState.Handle(this);
            }
        }

        public void SetState(TrafficLightState state)
        {
            _currentState = state;
        }
    }

2.TrafficLightState.cs

 public abstract class TrafficLightState
    {
        public abstract void Handle(TrafficLight light);
    }

3.GreenState.cs

public class GreenState : TrafficLightState
    {
        public override void Handle(TrafficLight light)
        {
            Console.WriteLine("绿灯行");
            light.SetState(new YellowState());
        }
    }

4.RedState.cs

public class RedState : TrafficLightState
    {
        public override void Handle(TrafficLight light)
        {
            Console.WriteLine("红灯停");
            light.SetState(new GreenState());
        }
    }

5.YellowState.cs

public class YellowState : TrafficLightState
    {
        public override void Handle(TrafficLight light)
        {
            Console.WriteLine("黄灯亮了等一等");
            light.SetState(new RedState());
        }
    }

6.Program.cs

internal class Program
    {
        static void Main(string[] args)
        {
            TrafficLight light = new TrafficLight();
            light.Turn();
            light.Turn();
            light.Turn();
            light.Turn();
        }
    }

运行结果:

四、优缺点

优点

  • 解决switch-caseif-else带来的难以维护的问题;
  • 结构清晰,提高了扩展性;
  • 通过单例或享元可使状态在多个上下文间共享。

缺点

  • 随着状态的扩展,状态类数量会增多;
  • 增加了系统复杂度,使用不当将会导致逻辑的混乱;
  • 不完全满足开闭原则。

五、与策略模式区别

策略模式

  • 强调可以互换的算法;
  • 用户直接与具体算法交互,决定算法的替换,需要了解算法本身;
  • 策略类不需要持有Context的引用。

状态模式

  • 强调改变对象内部的状态来帮助控制自己的行为;
  • 状态是对象内部流转,用户不会直接跟状态交互,不需要了解状态本身;
  • 状态类需要持有Context的引用,用来实现状态转移。

 

posted on 2023-06-05 10:39  一只向上爬的小蜗牛  阅读(1)  评论(0编辑  收藏  举报