17_状态模式

状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变其行为。状态模式将对象的行为封装在不同的状态类中,通过改变状态类来改变对象的行为。

状态模式有三个主要角色:

  1. 环境类(Context):定义了一个状态对象的引用,并在需要的时候调用状态对象的方法。环境类可以根据内部状态的改变来改变行为。

  2. 抽象状态类(State):定义了一个接口或抽象类,用于封装状态的共同行为。具体的状态类应该实现该接口或继承该抽象类,并实现其方法。

  3. 具体状态类(Concrete State):实现了抽象状态类的接口或抽象方法,提供了具体的行为实现。

状态模式的工作原理如下:

  1. 环境类持有一个状态对象的引用,并在需要的时候调用状态对象的方法。

  2. 客户端通过调用环境类的方法来改变对象的状态。

  3. 环境类根据当前的状态对象来调用相应的方法,实现不同状态下的行为。

状态模式的优点包括:

  1. 将对象的状态和行为进行了解耦,使得对象的状态可以独立于行为变化。

  2. 可以将复杂的条件判断语句转移到状态类中,提高了代码的可读性和可维护性。

  3. 可以方便地增加新的状态类,扩展新的行为。

状态模式适用于以下场景:

  1. 当一个对象的行为取决于其内部状态,并且需要在运行时根据状态改变行为时,可以使用状态模式。

  2. 当有大量的条件判断语句需要根据对象的状态来选择不同的行为时,可以使用状态模式。

总结而言,状态模式通过将对象的行为封装在不同的状态类中,使得对象的行为可以根据内部状态的改变而改变。它提供了一种简洁的方式来处理对象的状态转换,并将复杂的条件判断语句转移到状态类中,提高了代码的可读性和可维护性。

 

案例场景:

AOI行业中的PCB板缺陷检测,顺序是:进板,MARK点定位,检测整板,检测子板,退板

IContext

public interface IContext
    {
        string SubBoard { get; set; }
        void SetState(IState state);

        void Request();
    }

 

State

public interface IState
    {
        int Flag { get; }

        void Handle(IContext context);
    }

 

Context

 /// <summary>
    /// 主板
    /// </summary>
    public class Board : IContext
    {
        private IState _state;
        public IState State => _state;
        public string SubBoard { get ; set ; }

        public Board(IState state, string subBoard)
        {
            _state = state;
            SubBoard = subBoard;
        }

        public void Request()
        {
            _state.Handle(this);
        }

        public void SetState(IState state)
        {
            _state = state;
        }
    }

 

Concrete State

/// <summary>
    /// 进板
    /// </summary>
    public class EnterState : IState
    {
        public int Flag => 1;

        public void Handle(IContext context)
        {
            Console.WriteLine("主板已进入");

            context.SetState(new MarkState());
        }
    }
/// <summary>
    /// mark定位
    /// </summary>
    public class MarkState : IState
    {
        public int Flag => 2;

        public void Handle(IContext context)
        {
            Console.WriteLine("正在进行Mark点定位....");

            context.SetState(new WholeState());
        }
    }
/// <summary>
    /// 整板检测
    /// </summary>
    public class WholeState : IState
    {
        public int Flag => 3;

        public void Handle(IContext context)
        {
            Console.WriteLine("正在进行整板检测...");

            if (context.SubBoard != null)
            {
                context.SetState(new ChildState());
            }
            else
            {
                context.SetState(new ExitState());
            }
            
        }
    }
/// <summary>
    /// 子板检测
    /// </summary>
    public class ChildState : IState
    {
        public int Flag => 4;

        public void Handle(IContext context)
        {
            Console.WriteLine("正在进行子板检测...");

            context.SetState(new ExitState());
        }
    }
/// <summary>
    /// 退板
    /// </summary>
    public class ExitState : IState
    {
        public int Flag => 5;

        public void Handle(IContext context)
        {
            Console.WriteLine("检测完毕,正在退板...");
        }
    }

 

调用

internal class Client
    {
        public void Start()
        {
            Board board = new Board(new EnterState(),"有子板");

            while(true)
            {
                board.Request();

                if(board.State.Flag == 5)
                {
                    board.Request();

                    break;
                }
            }

            Console.WriteLine("----------------漂亮的分割线-------------------");

            board = new Board(new EnterState(), null);

            while (true)
            {
                board.Request();

                if (board.State.Flag == 5)
                {
                    board.Request();

                    break;
                }
            }
        }
    }
static void Main(string[] args)
        {
            new Client().Start();

            Console.ReadKey();
        }

 

posted @ 2024-03-14 09:44  野码  阅读(19)  评论(0编辑  收藏  举报