Skip to content

Commit c44a6c2

Browse files
author
Jarry
committed
add state for c
1 parent 191ee59 commit c44a6c2

19 files changed

+451
-25
lines changed

state-pattern/README.md

Lines changed: 179 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 【状态设计模式详解】Java/JS/Go/Python/TS不同语言实现
1+
# 【状态设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
22

33
# 简介
44
状态模式(State Pattern)是一种行为型模式,类的行为是基于它的状态改变的,不同的状态下有不同的行为。状态模式和策略模式相似,但是状态模式中的行为是平行的,不可替换的,策略模式中的行为是彼此独立的,可以相互替换,且提前预置到某个具体对象类Context中。状态模式将对象的行为封装在不同的状态对象中,将对象的状态从对象中分离出来,客户端无需关心对象的当前状态和状态的转换。
@@ -23,11 +23,11 @@ ConcreteStateA,ConcreteStateB: 具体的实现类,实现了State中定义的
2323
# UML
2424
<img src="../docs/uml/state-pattern.png">
2525

26-
# 代码
26+
# Java代码
2727

2828
## 状态基础接口
2929
```java
30-
// 定义状态接口和状态方法,当前context只有一种状态
30+
// State.java 定义状态接口和状态方法,当前context只有一种状态
3131
public interface State {
3232
public void on(Context context);
3333
public void off(Context context);
@@ -73,7 +73,6 @@ public class ConcreteStateOn implements State {
7373
System.out.println(this.getClass().getSimpleName() + "::off() [turn OFF ok!]");
7474
context.setState(new ConcreteStateOff());
7575
}
76-
7776
}
7877
```
7978

@@ -131,5 +130,180 @@ public class Context {
131130
context.turnOff();
132131
System.out.println("context.state: " + context.getState().getClass().getSimpleName());
133132
```
133+
134+
# Go代码
135+
136+
## 状态基础接口
137+
```go
138+
// State.go 定义状态接口和状态方法,当前context只有一种状态
139+
type State interface {
140+
GetName() string
141+
On(context *Context)
142+
Off(context *Context)
143+
}
144+
```
145+
146+
## 状态实现类
147+
```go
148+
// ConcreteStateOff.go 具体的状态实现者
149+
150+
type ConcreteStateOff struct {
151+
Name string
152+
}
153+
154+
func (c *ConcreteStateOff) GetName() string {
155+
if c.Name == "" {
156+
c.Name = "ConcreteStateOff"
157+
}
158+
return c.Name
159+
}
160+
161+
func (c *ConcreteStateOff) On(context *Context) {
162+
fmt.Println("ConcreteStateOff::On() [turn ON ok!]")
163+
// 状态变为on后,状态类切换到ConcreteStateOn
164+
context.SetState(&ConcreteStateOn{})
165+
}
166+
167+
func (c *ConcreteStateOff) Off(context *Context) {
168+
// 当前是off状态,再点击off只是提示,不切换状态类
169+
fmt.Println("ConcreteStateOff::Off() [needn't switch, state is OFF.]")
170+
}
171+
```
172+
173+
```go
174+
// ConcreteStateOn.go 具体的状态实现者
175+
type ConcreteStateOn struct {
176+
Name string
177+
}
178+
179+
func (c *ConcreteStateOn) GetName() string {
180+
if c.Name == "" {
181+
c.Name = "ConcreteStateOn"
182+
}
183+
return c.Name
184+
}
185+
186+
func (c *ConcreteStateOn) On(context *Context) {
187+
// 当前是on状态,再点击on只是提示,不切换状态类
188+
fmt.Println("ConcreteStateOn::On() [needn't switch, state is ON.]")
189+
}
190+
191+
func (c *ConcreteStateOn) Off(context *Context) {
192+
// 状态变为off后,状态类切换到ConcreteStateOff
193+
fmt.Println("ConcreteStateOn::Off() [turn OFF ok!]")
194+
// 此处状态对象可以每次是新实例,也可以外部传入
195+
context.SetState(&ConcreteStateOff{})
196+
}
197+
```
198+
199+
## 业务状态类
200+
```go
201+
// Context.go 执行实体类,内部关联状态
202+
type Context struct {
203+
state State
204+
}
205+
206+
func (c *Context) GetState() State {
207+
return c.state
208+
}
209+
210+
func (c *Context) SetState(state State) {
211+
fmt.Println("Context::SetState() [state = " + state.GetName() + "]")
212+
c.state = state
213+
}
214+
215+
func (c *Context) TurnOn() {
216+
c.state.On(c)
217+
}
218+
219+
func (c *Context) TurnOff() {
220+
c.state.Off(c)
221+
}
222+
```
223+
224+
## 测试调用
225+
```go
226+
func main() {
227+
fmt.Println("test start:")
228+
229+
/**
230+
* 状态模式就是对象Context在不同行为下有不同的状态,当前只有一种状态。
231+
* 通过行为的改变,状态也随之自动发生了改变。
232+
* 策略模式与状态模式类似,但策略模式是可以重新设置策略,而状态则通过行为来切换状态。
233+
*/
234+
235+
context := &src.Context{}
236+
// 初始状态是off
237+
context.SetState(&src.ConcreteStateOff{})
238+
// turn on
239+
context.TurnOn()
240+
// 再次turn on
241+
context.TurnOn()
242+
// turn off
243+
context.TurnOff()
244+
// 再次turn off
245+
context.TurnOff()
246+
fmt.Println("context.state: " + context.GetState().GetName())
247+
}
248+
```
249+
250+
# C语言简版
251+
```c
252+
#include <stdio.h>
253+
// 状态模式将对象的行为封装在不同的状态对象中
254+
// 将对象的状态从对象中分离出来,客户端无需关心对象的当前状态和状态的转换。
255+
typedef struct Context Context;
256+
257+
// 执行对象
258+
struct Context
259+
{
260+
// 设置状态
261+
char name[50];
262+
void (*change_state)(Context *context);
263+
};
264+
265+
// 定义不同状态函数
266+
void state_A_change_state(Context *context);
267+
void state_B_change_state(Context *context);
268+
void state_C_change_state(Context *context);
269+
270+
void state_A_change_state(Context *context)
271+
{
272+
printf("\r\n state_A_change_state() [context=%s change to=%s]", context->name, "state_B");
273+
// 切换到状态 B
274+
context->change_state = state_B_change_state;
275+
}
276+
277+
void state_B_change_state(Context *context)
278+
{
279+
printf("\r\n state_B_change_state() [context=%s change to=%s]", context->name, "state_C");
280+
// 切换到状态 C
281+
context->change_state = state_C_change_state;
282+
}
283+
284+
void state_C_change_state(Context *context)
285+
{
286+
printf("\r\n state_C_change_state() [context=%s change to=%s]", context->name, "state_A");
287+
// 切换到状态 A
288+
context->change_state = state_A_change_state;
289+
}
290+
291+
int main()
292+
{
293+
printf("test start:\r\n");
294+
Context context = {
295+
.name = "Context01",
296+
.change_state = state_A_change_state};
297+
298+
// 当前只有一种状态
299+
for (int i = 0; i < 5; i++)
300+
{
301+
context.change_state(&context);
302+
}
303+
304+
return 0;
305+
}
306+
```
307+
134308
## 更多语言版本
135-
不同语言实现设计模式[https://github.com/microwind/design-pattern](https://github.com/microwind/design-pattern)
309+
不同语言设计模式源码:[https://github.com/microwind/design-pattern](https://github.com/microwind/design-pattern)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "func.h"
2+
3+
/// 具体的状态实现者
4+
5+
void concrete_state_off_on(Context *context)
6+
{
7+
// 状态变为on后,状态类切换到ConcreteStateOn
8+
printf("\r\n ConcreteStateOff::on() [turn ON ok!]");
9+
context->set_state(context, (State *)concrete_state_on_constructor());
10+
}
11+
12+
void concrete_state_off_off(Context *context)
13+
{
14+
// 当前是off状态,再点击off只是提示,不切换状态类
15+
printf("\r\n ConcreteStateOff::off() [needn't switch, state is OFF.]");
16+
}
17+
18+
ConcreteStateOff *concrete_state_off_constructor()
19+
{
20+
// printf("\r\n proxy_off_constructor() [构建ConcreteStateOff]");
21+
State *state = (State *)malloc(sizeof(State));
22+
ConcreteStateOff *state_off = (ConcreteStateOff *)state;
23+
strcpy(state_off->name, "ConcreteStateOff");
24+
state_off->on = &concrete_state_off_on;
25+
state_off->off = &concrete_state_off_off;
26+
return state_off;
27+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "func.h"
2+
3+
// 具体的状态实现者
4+
// 策略模式与状态模式都是将策略/状态绑定到执行对象(Context)上
5+
// 不同的是策略模式是客户可设定策略,而状态则是通过状态动作来实现改变
6+
void concrete_state_on_on(Context *context)
7+
{
8+
// 当前是on状态,再点击on只是提示,不切换状态类
9+
printf("\r\n ConcreteStateOn::on() [needn't switch, state is ON.]");
10+
}
11+
12+
void concrete_state_on_off(Context *context)
13+
{
14+
// 状态变为off后,状态类切换到ConcreteStateOff
15+
printf("\r\n ConcreteStateOn::off() [turn OFF ok!]");
16+
context->set_state(context, (State *)concrete_state_off_constructor());
17+
}
18+
19+
ConcreteStateOn *concrete_state_on_constructor()
20+
{
21+
// printf("\r\n proxy_off_constructor() [构建ConcreteStateOff]");
22+
State *state = (State *)malloc(sizeof(State));
23+
ConcreteStateOn *state_on = (ConcreteStateOn *)state;
24+
strcpy(state_on->name, "ConcreteStateOn");
25+
state_on->on = &concrete_state_on_on;
26+
state_on->off = &concrete_state_on_off;
27+
return state_on;
28+
}

state-pattern/c/src/context.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include "func.h"
2+
3+
// 具体执行实体类,内部关联状态
4+
State *context_get_state(Context *context)
5+
{
6+
return context->state;
7+
}
8+
9+
void context_set_state(Context *context, State *state)
10+
{
11+
printf("\r\n Context::set_state() [state = %s]", state->name);
12+
context->state = state;
13+
}
14+
15+
void context_turn_on(Context *context)
16+
{
17+
context->state->on(context);
18+
}
19+
20+
void context_turn_off(Context *context)
21+
{
22+
context->state->off(context);
23+
}
24+
25+
Context *context_constructor()
26+
{
27+
printf("\r\n context_constructor() [构建Context]");
28+
Context *context = (Context *)malloc(sizeof(Context));
29+
context->get_state = &context_get_state;
30+
context->set_state = &context_set_state;
31+
context->turn_on = &context_turn_on;
32+
context->turn_off = &context_turn_off;
33+
return context;
34+
}

state-pattern/c/src/func.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <stdio.h>
2+
#include <ctype.h>
3+
#include <stdlib.h>
4+
#include <stdbool.h>
5+
#include <string.h>
6+
7+
typedef struct Context Context;
8+
typedef struct State State;
9+
10+
// 定义状态接口和状态方法,当前context只有一种状态
11+
typedef struct State
12+
{
13+
char name[50];
14+
void (*on)(Context *context);
15+
void (*off)(Context *context);
16+
} State;
17+
18+
// 具体执行实体类,内部关联状态
19+
typedef struct Context
20+
{
21+
State *state;
22+
void (*set_state)(Context *context, State *state);
23+
State *(*get_state)(Context *context);
24+
void (*turn_on)(Context *context);
25+
void (*turn_off)(Context *context);
26+
} Context;
27+
Context *context_constructor();
28+
29+
// 具体的状态实现者
30+
typedef struct ConcreteStateOff
31+
{
32+
char name[50];
33+
void (*on)(Context *context);
34+
void (*off)(Context *context);
35+
} ConcreteStateOff;
36+
ConcreteStateOff *concrete_state_off_constructor();
37+
38+
// 具体的状态实现者
39+
typedef struct ConcreteStateOn
40+
{
41+
char name[50];
42+
void (*on)(Context *context);
43+
void (*off)(Context *context);
44+
} ConcreteStateOn;
45+
ConcreteStateOn *concrete_state_on_constructor();

state-pattern/c/src/state.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "func.h"
2+
3+
// 状态struct,约束状态state,当前context只有一种状态

0 commit comments

Comments
 (0)