.NET/Js 状态模式

概念

描述: 在该模式中,类的行为基于它的状态改变。这种类型的设计模式属于行为型设计模式。

在状态模式中,我们创建表示各种状态的对象和一个随着状态改变而改变的上下文。

  • 意图 : 允许对象在内部状态改变时,改变它的行为,这个对象本身看起来好像修改了它的类。
  • 主要解决 : 对象行为依赖于它的状态,并且可以根据状态改变而改变其行为
  • 何时使用 : 在代码中包含大量对象状态有关的条件语句
  • 解决方案 : 将各种具体的状态抽象出来

JS状态模式

1.新建一个index.js

点击查看代码
/**
 * 状态类
 */
 class State {
	constructor(process) {
	  this.process = process
	}
	/**
	 * 处理状态的方法
	 * @param {*} context 状态上下文
	 */
	handle(context) {
	  //处理具体该流程的业务逻辑
	  console.log(`物品正处于【${this.process}】状态`)
	  //设置下一个状态
	  context.setState(this)
	}
  }
  /**
   * 状态上下文
   */
  class Context {
	/**
	 * 构造函数
	 */
	constructor() {
	  this.state = null
	}
	/**
	 * 获取状态
	 * @returns 返回当前状态
	 */
	getState() {
	  return this.state
	}
	/**
	 * 赋值状态
	 * @param{*} state 状态
	 */
	setState(state) {
	  this.state = state
	  // console.log(`当前上下文的状态为:${state}``);
	}
  }
  

2.调用代码如下:

index.html
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<script src="./StatePattern.js"></script>
	<title>Document</title>
</head>

<body>
	<script>
		var context = new Context();
		var order = new State("ordering");
		var send = new State("sending");
		order.handle(context)
		send.handle(context)
	</script>
</body>

</html>

C# 实现状态模式

1.创建状态机(Work)

点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace StatePattern.Console
{
	/// <summary>
	/// 状态机
	/// </summary>
	public class Work
	{
		private State _currentstate;
		private int _processId;
		private bool _finish = false;

		public bool Finish { get => _finish; set => _finish = value; }
		public int ProcessId { get => _processId; set => _processId = value; }

		public Work(State state)
		{
			this._currentstate = state;
			_processId = state.StateId;
		}
		/// <summary>
		/// 设置状态机中的状态
		/// </summary>
		/// <param name="state"></param>
		public void SetState(State state)
		{
			_currentstate = state;
			_processId = state.StateId;
		}
		/// <summary>
		/// 执行节点中的Do方法(代理模式)
		/// </summary>
		/// <param name="func"></param>
		public void Do(Func<int, bool> func)
		{
			_currentstate.Do(this, func);
		}
	}
}

主要目的获取当前状态,存储当前状态id(ProcessId),将当前的状态复制给私有字段,通过当前的状态触发不同的业务逻辑处理

2.创建状态抽象类(State)

点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace StatePattern.Console
{
	/// <summary>
	/// 状态
	/// </summary>
	public abstract class State
	{
		public abstract int StateId { get; }
		public abstract void Do(Work work, Func<int, bool> func);

	}
}

这个类的作用是保存当前状态id,Do方法(传委托的意义在于:判断当前属于哪个状态流程,触发不同的业务处理)

3.创建一个下单状态(OrderState)

OrderState
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace StatePattern.Console
{
	public class OrderState : State
	{
		public override int StateId => 1;

		public override void Do(Work work, Func<int, bool> func)
		{
			//判断状态机是否处于结束状态
			if (!work.Finish)
			{
				// 判断条件是否满足
				if (func(work.ProcessId))
				{
					// ...处理流程需要在该状态处理的逻辑
					System.Console.WriteLine("do order");
					// return work.ProcessId + 1; 
				}
				//设置下一个State
				work.SetState(new SendState());
				//执行下一个State的Do方法
				work.Do(func);
			}
			else
			{
				//否则执行finish
				work.SetState(new FinishState());
				work.Do(func);
			}
		}
	}
}

判断当前传入的状态机是否是完结状态,委托的作用:当前指定的状态id是否与传入的状态id一致,一致则处理对应的业务,不一致则处理下一个状态的业务,下面的处理逻辑基本和上面的一致,就不多介绍了
一个状态处理完毕,处理下一个状态,最后执行完结状态处理方法

4.发送货物的类(SendState)

SendState
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace StatePattern.Console
{
	public class SendState : State
	{
		public override int StateId => 2;

		public override void Do(Work work, Func<int, bool> func)
		{
			//判断状态机是否处于结束状态
			if (!work.Finish)
			{
				// 判断条件是否满足
				if (func(work.ProcessId))
				{
					// ...处理流程需要在该状态处理的逻辑
					System.Console.WriteLine("do sending");
				}
				//设置下一个State
				work.SetState(new FinishState());
				//执行下一个State的Do方法
				work.Do(func);
			}
			else
			{
				//否则执行finish
				work.SetState(new FinishState());
				work.Do(func);
			}
		}

	}
}

5.完成状态方法:

点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace StatePattern.Console
{
	public class FinishState : State
	{
		public override int StateId => 3;

		public override void Do(Work work, Func<int, bool> func)
		{
			work.Finish = true;
			System.Console.WriteLine("流程结束");

		}
	}
}
posted @ 2022-08-24 14:01  rookiexwang  阅读(25)  评论(0编辑  收藏  举报