『设计模式』状态模式(不起花里胡哨的名字了)

『设计模式』状态模式(不起花里胡哨的名字了)

23 种设计模式+额外常用设计模式汇总 (持续更新)

状态模式

  • 允许一个对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它的类。
  • 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表系不同状态的一系列类当中,可以把复杂的逻辑简化。
  • 每个人、事务在不同的状态下会有不同表现动作,而一个状态又会在不同的表现下转移到写一个不同的状态。
  • 在State模式中我们将状态逻辑和动作实现进行分离。当一个操作中要维护大量的分支语句,并且这些分支依赖于对象的状态。State模式将每一个分支都封装到独立的类中。

State模式结构

在这里插入图片描述

优点

  • 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
  • 消除庞大的条件分支语句,把各种状态转移逻辑分布到State的子类之间,减少了相互间的依赖。
  • 显式化进行状态转换:为不同的状态引入独立的对象,使得状态的转换变得更如明确。而且状态对象可以保证上下文不会发生内部状态不一致的状况,因为上下文中只有一个变量来记录状态对象,只要为这一个变量赋值就可以了。

缺点

State模式问题主要是逻辑分散化,状态逻辑分布到了很多的State的子类中,很难看到整个的状态逻辑图,这也带来了代码的维护问题。

本质

  • 根据状态来分离和选择行为
  • 状态模式是状态驱动,由上下文负责。

State模式和Strategy模式简单对比

  • State模式和Strategy模式有很大程度上的相似:它们都有-一个Context类,都是通过委托(组合)给一个具有多个派生类的多态基类实现Context的算法逻辑。
  • 两者最大的差别就是State模式中派生类持有指向Context对象的引用,并通过这个引用调用Context中的方法,但在Strategy模式中就没有这种情况。

实现

1
2
3
4
5
6

public abstract class State {

public abstract void Handle(Context context);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 public class ConcreteStateA extends State{

@Override
public void Handle(Context context) {
context.setState(new ConcreteStateB()); //设置A的下一个状态是B

}

}
class ConcreteStateB extends State{

@Override
public void Handle(Context context) {
context.setState(new ConcreteStateC()); //设置B的下一个状态是C
}

}
class ConcreteStateC extends State{

@Override
public void Handle(Context context) {
context.setState(new ConcreteStateA()); //设置C的下一个状态是A
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Context {
State state;

public Context(State state) { //定义Context的初始状态
super();
this.state = state;
}

public State getState() {
return state;
}

public void setState(State state) {
this.state = state;
System.out.println("当前状态为"+state);
}
public void request(){
state.Handle(this); //对请求做处理并且指向下一个状态
}
}

实例

【问题】
工作流中的请假流程:

  • 某人提出请假申请,先由项目经理审批,如果项目经理不同意,审批就直接结束。
  • 如项目经理同意,再看是否超过3天,如果三天以内,审批直接结束。
  • 否则,交给部门经理,部门络理审核后,无论是否同意,审批直接结束。

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333


package 状态模式;

public class Context {

private State st;

private int days;

private String name;

private String pro;

private String dept;


private boolean ProjectManager,DepartmentManager,BossManager;

public Context(int days, String name, String pro, String dept, boolean projectManager, boolean departmentManager,

boolean boss) {

super();

this.days = days;

this.name = name;

this.pro = pro;

this.dept = dept;

ProjectManager = projectManager;

DepartmentManager = departmentManager;

this.BossManager = boss;

}



public boolean isBossManager() {

return BossManager;

}



public void setBossManager(boolean bossManager) {

BossManager = bossManager;

}



public Context( int days, String name, String pro, String dept, boolean projectManager,

boolean departmentManager) {

super();



this.days = days;

this.name = name;

this.pro = pro;

this.dept = dept;

ProjectManager = projectManager;

DepartmentManager = departmentManager;

}



public Context() {

super();

// TODO Auto-generated constructor stub

}



public int getDays() {

return days;

}



public void setDays(int days) {

this.days = days;

}



public String getName() {

return name;

}



public void setName(String name) {

this.name = name;

}



public boolean isProjectManager() {

return ProjectManager;

}



public void setProjectManager(boolean projectManager) {

ProjectManager = projectManager;

}



public boolean isDepartmentManager() {

return DepartmentManager;

}



public String getDept() {

return dept;

}



public void setDept(String dept) {

this.dept = dept;

}



public String getPro() {

return pro;

}



public void setPro(String pro) {

this.pro = pro;

}



public void setDepartmentManager(boolean departmentManager) {

DepartmentManager = departmentManager;

}



public void leave() {

st.leave(this);

}

}

package 状态模式;

public abstract class State {

public abstract void leave(Context con);

}

package 状态模式;

public class Accept extends State {

@Override

public void leave(Context con) {

if(con.isProjectManager()==false) {

System.out.println(con.getPro()+"经理不同意请假!"+con.getName()+"的请假");

}else {

Less3 tdl=new Less3();

tdl.leave(con);

}

}

}

package 状态模式;

public class Less3 extends State {

@Override

public void leave(Context con) {

if(con.getDays()<=3) {

System.out.println(con.getPro() +"项目经理同意!"+con.getName()+"的请假审批通过!共请假"+con.getDays()+"天!");

}else {

System.out.println("请假时间超过三天,请移至"+con.getDept()+"部门经理处!");

More3_Less7 tdo=new More3_Less7();

tdo.leave(con);

}



}

}

package 状态模式;

public class More3_Less7 extends State {

@Override

public void leave(Context con) {

if(con.getDays()<=7) {

System.out.println(con.getDept()+"部门经理同意!"+con.getName()+"的请假审批通过!共请假"+con.getDays()+"天!");

}else {

System.out.println("请假时间超过7天,请移至总经理!");

More7 tdo=new More7();

tdo.leave(con);

}



}

}

package 状态模式;

public class More7 extends State {

@Override

public void leave(Context con) {

if(con.isBossManager()==true) {

System.out.println(con.getPro()+"项目经理同意!"+con.getDept()+"部门经理同意!总经理同意!"+con.getName()+"的请假审批通过!共请假"+con.getDays()+"天!");

}else {

System.out.println(con.getPro()+"项目经理同意!"+con.getDept()+"部门经理同意!总经理不同意!"+con.getName()+"的请假审批不通过!");

}

}

}

package 状态模式;

public class Client {

public static void main(String[] args) {

Context con = new Context(8,"菜鸡","设计模式","设计",true,true,true);

con.setName("菜鸡");

con.setPro("设计模式");

con.setDept("设计");

con.setDays(8);

con.setProjectManager(true);

con.setDepartmentManager(true);

con.leave();

}

}



『设计模式』状态模式(不起花里胡哨的名字了)
https://chiamzhang.github.io/2024/06/29/『设计模式』状态模式(不起花里胡哨的名字了)/
Author
Chiam
Posted on
June 29, 2024
Licensed under