• 设计模式学习笔记-状态模式


    引言

    使用该设计模式的情况:如在场景中的主角甚至是敌人,有N个不同状态:走路,攻击,待机.....,游戏中,这些状态来回切换。有一个明确的状态划分的情况下,此时,是可以使用Switch...case...来整理不同的状态的切换和处理的,但处理不同状态,包括切换逻辑会比较冗杂,还有一个缺点就是不容易扩展; 这种情况下,利用状态模式是比较好的。

    2,解决的问题: 

    •         当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式来。
    •   当一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态。
    •   当控制一个对象状态转换的条件表达式过于复杂的情况。把状态的判断逻辑转移到表示不同的一系列类当中,可以把复杂的逻辑判断简单化。不仅仅是使用人物状态和AI 这块,如当游戏中有诸多场景要进行切换的时候,亦是可以使用该模式的。

    3,类图 

      声明一个接口,以封装状态的相关行为,对这个接口来说,会有实现类(有几个状态就实现几个);  

           若状态间进行切换只需要在Context(对象,状态拥有者),只需要在context中的State指向对应状态即可;

      

    4,优缺点 

    •     状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
    •     所有状态相关的代码都存在于某个ConcereteState中,所以通过定义新的子类很容易地增加新的状态和转换。
    •       状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。

        缺点是会有很多的状态子类。

    5,示例代码

      

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    /// <summary>
    /// 状态模式
    /// </summary>
    public class StateModel:MonoBehaviour
    {
        private void Start()
        {
            Context ct = new Context();
            ct.SetState(new ConcreteA(ct));
            //change
            ct.Handle(3);
            ct.Handle(5);
        }
    }
    //状态应用者 Context
    public class Context
    {
        private Istate mState;// 
        public void  SetState(Istate state)
        {
            mState = state;
        } 
        public void Handle(int args)
        {
            mState.Hanedle(args);
        }
    
    }
    public interface Istate
    {
        void Hanedle(int args); 
    } 
    public class ConcreteA : Istate
    {
        private Context mContext;
        public ConcreteA (Context context)
        {
            mContext = context;
        }
        public void Hanedle(int args)
        {
            Debug.Log("ConcreteA:" + args);      
            if (args > 4)
            {
                mContext.SetState(new ConcreteB(mContext));
            }
        }
    }
    public class ConcreteB : Istate
    {
        private Context mContext;
        public ConcreteB(Context context)
        {
            mContext = context;
        }
        public void Hanedle(int args)
        {
            Debug.Log("B:" + args);
            if (args < 4)
            {
                mContext.SetState(new ConcreteA(mContext));
            }
        }
    }
     

         控制台结果

        

  • 相关阅读:
    如何使用 @ OutputCache 指令的 VaryByCustom 属性来缓存不同版本的页面
    看不懂 ASP.NET 相册上传代码
    asp.net判断是1.1还是2.0主要由Code*属性来解决,判断规则如下:
    引号看不懂
    GridView的行删除事件 //取当前行的Id
    <Columns></Columns>中间的是列集合
    DropDownList1.SelectedIndex = 0 DropDownList1处于位选择任何选项的状态下
    是一个查询语句 查询ZhuanJia表里面id=输入id的数据
    验证码图片的解释
    get和post区别:
  • 原文地址:https://www.cnblogs.com/allyh/p/9396389.html
Copyright © 2020-2023  润新知