【设计模式&C#】状态模式(用于解决解耦多种状态之间的交互)
一种行为设计模式。
特点是用类的方式去管理状态。
优点:
- 对每个状态进行了封装,提高了代码的可维护性;
- 减少了条件判断语句的使用,降低维护成本;
- 易于扩展,每次新增状态都无需大规模修改其他类,符合开闭原则;
缺点:
- 会导致类的增加,每个状态都会是一个单独的类;
- 增加了性能的开销,状态的实例化会导致性能消耗增加。
用途:
- 设计游戏中人物的状态
- 设计网络连接时的状态
- 设计订单的状态
主要组成部分:
状态的接口:它定义了每个状态的实现规则。
每个状态的具体实现类:定义了状态的具体的实现逻辑和切换逻辑。
上下文(或者叫控制器):维护一个具体状态的引用,通常是指调用状态对象。
实例:
//状态的接口using UnityEngine;/// /// 每个场景的状态接口类/// public abstract class ISceneState{ private string mSceneName;//场景名称 protected SceneStateController mController;//场景状态控制器 public ISceneState(string sceneName, SceneStateController controller) { mSceneName = sceneName; mController = controller; } public string SceneName { get { return mSceneName; } } /// /// 状态开始时调用 /// public virtual void StateStart() { } /// /// 状态结束时调用 /// public virtual void StateEnd() { } /// /// 状态更新时调用 /// public virtual void StateUpdate() { }}
//状态的实现类using UnityEngine;using UnityEngine.UI;public class StartState: ISceneState{ public StartState(SceneStateController controller) :base(\"01StartScene\", controller) { } private Image mLOGO; private float mSmoothingTime = 1f;//LOGO过渡时间 private float mWaitTime = 2f;//进入MainMenue前等待时间 public override void StateStart() { mLOGO = GameObject.Find(\"Canvas/LOGO\").GetComponent(); mLOGO.color = Color.black; } public override void StateUpdate() { //LOGO图片的缓冲过渡 mLOGO.color = Color.Lerp(mLOGO.color, Color.white, mSmoothingTime * Time.deltaTime); //等待时间 mWaitTime -= Time.deltaTime; //LOGO图片的缓冲过渡 if(mWaitTime <= 0) { mController.SetState(new MainMenuState(mController)); } }}
//状态的实现类using UnityEngine;using UnityEngine.UI;public class MainMenuState: ISceneState{ public MainMenuState(SceneStateController controller): base(\"02MainMenuScene\", controller) { } public override void StateStart() { GameObject.Find(\"Canvas/StartButton\").GetComponent
//状态的实现类public class BattleState: ISceneState{ public BattleState(SceneStateController controller): base(\"03BattleScene\", controller) { } public override void StateStart() { GameFacade.Instance.Init(); } public override void StateEnd() { GameFacade.Instance.Release(); } public override void StateUpdate() { if(GameFacade.Instance.isGameOver) { mController.SetState(new MainMenuState(mController)); } GameFacade.Instance.Update(); }}
//上下文(或者叫控制器):using UnityEngine;using UnityEngine.SceneManagement;public class SceneStateController{ private ISceneState mState;//当前场景状态 private AsyncOperation mAO;//异步加载场景 private bool mIsRunStart = false;//表示场景是否已经正在运行中 /// /// 设置场景状态 /// /// 状态 /// 是否加载场景 public void SetState(ISceneState state, bool isLoadScene = true) { //退出状态时的处理 if(mState != null) { mState.StateEnd(); } //设置新状态 mState = state; //加载场景 if(isLoadScene) { mAO = SceneManager.LoadSceneAsync(mState.SceneName); mIsRunStart = false; } else { mState.StateStart(); mIsRunStart = true; } } /// /// 更新场景状态 /// public void StateUpdate() { if (mAO != null && mAO.isDone == false) return; if(mIsRunStart == false && mAO != null && mAO.isDone == true) { mState.StateStart(); mIsRunStart = true; } if(mIsRunStart && mState != null) { mState.StateUpdate(); } }}