Skip to content

Commit

Permalink
修改打包信息
Browse files Browse the repository at this point in the history
  • Loading branch information
ShimizuShiori committed Mar 17, 2020
1 parent 0f84931 commit 5b158f4
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 8 deletions.
175 changes: 174 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,174 @@
# Reface.StateMachine
# Reface.StateMachine

这是一个状态自动下推机的功能库。

依赖项
* Reface,这是一个基础库,由 .NetStandard2.0 开发

## 什么是状态自动下推机?

对某个目标事物,发生不动行为后,状态就会发生变化。
例如:

对一个文档 **保存** 后,它变成了 **草稿** 状态。
再对 **草稿** 状态的文档 **审核** 以后,会变成 **已审核** 状态,
若对 **草稿** 状态的文档 **删除** ,则会变成 **删除** 状态,
当文档已经是 **已审核** 状态时,不再允许进行 **删除** 操作。

状态机中的两个概念,一个是 **状态** 一个是 **行为**,从上面的例子来看

状态是
* 草稿
* 已审核
* 删除

行为是
* 保存
* 审核
* 删除

简单的来说,行为就是,在某个状态时,到某个状态去。

## 功能简介

使用 **Reface.StateMachine** 你可以简单的定义一个状态转移的整个过程。
当你要使用它时,只要使用 **Machine.Push(Action)** 就行了。

### 使用方法

#### 1. 引入包

使用 Nuget 搜索 Reface.StateMachine 即可,
由于 Reface.StateMachine 中有一些使用是使用 .NetStandard 开发的,所以请保证你的 .Net Framework 版本最低是 4.6.1

```shell
> Install-Package Reface.StateMachine -Version 1.0.2
```

#### 2. 定义一个 Machine

首先,你需要创建两个枚举类型,分别表示 States 和 Actions ,如:
```csharp
public enum DocumentStates
{
Default,
Draft,
Checked,
Deleted
}

public enum DocumentActions
{
Save,
Check,
Delete
}
```

再使用 **CodeStateMachineBuilder<TState, Code>** 构建一个 Machine ,
**CodeStateMachineBuilder** 被设计成了使用 链式 语句声明的风格,
可以参考下面的代码。

```csharp
var builder = new CodeStateMachineBuilder<DocumentStates, DocumentActions>();
builder
.StartWith(DocumentStates.Default) // 默认的状态
.From(DocumentStates.Default)
.When(DocumentActions.Save).To(DocumentStates.Draft)
.From(DocumentState.Draft)
.When(DocumentActions.Check).To(DocumentStates.Checked)
.When(DocumentActions.Delete).To(DocumentStates.Deleted);

var machine = builder.Build();
machine.Push(DocumentActions.Save);
machine.Push(DocumentActions.Check);

// 此时的状态会移动到 Checked 上
```

#### 3. 监听状态的变化

我们使用 **Machine.Push(Actions)** 的主要目的是要让状态发生变化。
我们可以使用 **Machine** 上的事件来监听状态发生的变化。

事件的监听有两种方法:

**Pushed 事件**
当任意 **Action** 完成了对状态的转移后,就会触发该事件,该事件会通知此时的 Push 是执行的哪个行为,从哪个状态移动到了哪个状态。
```csharp
machine.Pushed += (sender, e) =>
{
//sender is machine
//e.OldState
//e.NewState
//e.Action
};
```

**状态 事件**
Pushed 事件面向所有的状态移动,
因此我们设计了 状态 事件和监听,可以针对某个状态监听其离开和进入。
```csharp
var listener = machine.GetListener(DocumentStates.Draft);
listener.Entered += (sender, e) =>
{
// 刚进入这个状态时的事件
};
listener.Leaving += (sender, e) =>
{
// 正准备离开这个状态时的事件
};
```

---

## 通过配置文件产生 Machine 的定义

在代码设计阶段,我们往往不能一次性将复杂的状态转移写好。
虽然我们提供了 链式 定义的方法,但是面对一长段的状态转移定义,修改和维护往往比较困难。
因此,我们设计了通过配置文件,更直观的定义状态转移过程,而不需要使用链式声明法。

这是一种使用二维表格定义状态转移的方法,但是为了减少对第三方库的依赖,没有使用 Excel 格式,而使用了 Csv 文件格式。

以上述文件转移做为例子,配置文件应该像下面这个样子

| | Save | Check | Delete |
|---|---|---|---|
| Default | Draft | | |
| Draft | | Checked | Deleted |
| Deleted | | | |

**第一行第一列为空**
**第一行第一列为空**
**第一行第一列为空**
(重要的事情说三次!)

第一行是所有的行为,
第一列是所有的状态

在 行 与 列 的交接入,表示在这个状态下触发此行为时,进入的下一个状态。

**状态与行为的名称,必须与你的枚举类型中的项名称一致 !!!**

配置文件定义好后,就可以直接利用这个 csv 文件产生 machine 了。

```csharp
var machine = CsvStateMachineBuilder<DocumentTests, DocumentActions>.FromFile(".\1.csv").Build();
```

一行代码就OK了。
当然了,还有一个小细节需要注意一下:
我们需要设置状态机的默认状态,
使用 [StartState] 特征可以在枚举类型上设定默认的状态,这个特征,只有在使用 csv 生成的状态机时才会被使用到。

```csharp
public enum DocumentTest
{
[StartState]
Default,
Draft,
Checked,
Deleted
}
```
2 changes: 1 addition & 1 deletion src/Reface.StateMachine/Reface.StateMachine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="Reface, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\Reface.1.0.0\lib\netstandard2.0\Reface.dll</HintPath>
<HintPath>packages\Reface.1.0.1\lib\netstandard2.0\Reface.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
8 changes: 3 additions & 5 deletions src/Reface.StateMachine/Reface.StateMachine.nuspec
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<package >
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Reface.StateMachine</id>
<version>1.0.0</version>
<version>1.0.2</version>
<title>Reface.StateMachine</title>
<authors>ShimizuShiori</authors>
<owners>ShimizuShiori</owners>
<license type="expression">MIT</license>
<description>状态下推机</description>
<copyright>Copyright 2020</copyright>
<dependencies>
<dependency id="Reface" version="1.0.0"></dependency>
</dependencies>
<projectUrl>https://github.com/ShimizuShiori/Reface.StateMachine</projectUrl>
</metadata>
</package>
2 changes: 1 addition & 1 deletion src/Reface.StateMachine/packages.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Reface" version="1.0.0" targetFramework="net461" />
<package id="Reface" version="1.0.1" targetFramework="net461" />
</packages>

0 comments on commit 5b158f4

Please sign in to comment.