当前位置:
首页 > 编程开发 > Objective-C编程 >
-
C#泛型实现状态State模式
制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
一、问题来源
目前时兴这样的应用:用户采用Jabber(一种开源即时通讯协议)客户端登录Jabber服务器,然后再经过MSN中转站,就可以与MSN用户通讯了。系统结构如下:
其中中转服务器实现协议翻译。假设存在这样一种情况,就是客户端和中转服务器采用的不是那种双向通讯,而是如Html这样单向通讯手段(假设不用Ajax),客户端没有存储能力,因此需要把信息存储在中转服务器的数据库中。中转服务器的流量很大,当接收到信息或者用户阅读未读信息后,不能实时进行数据库的Insert和Update操作,而是定期轮询,进行批量处理。
中转服务器将消息存储在消息容器中。线程模型如下:
主要有三类线程:
(1)服务器监听线程监听来自第三方服务器的数据包,解析成消息对象,存储在消息容器中。
(2)用户服务线程根据用户的请求,取出消息,发送给用户,同时改变消息的状态,如果消息为“未读”,则改变为“已读”。
(3)数据库同步线程定期检查所有消息,根据消息状态,判断客户端的消息状态是否和数据库中储存的状态一致,如果不一致,则进行Update操作,如果数据库中不存在,则进行Insert操作。
消息一共有五种状态:
客户端是否已读 数据库中存储的状态 需要Update 需要Insert操作
状态1 已读 已读 否 否
状态2 已读 未读 是 否
状态3 未读 未读 否 否
状态4 未读 无 否 是
状态5 已读 无 否 是
用户阅读信息以及数据库同步操作可能导致用户状态改变。状态图如下:
二、实现
先给状态取名字:
状态1:SReadedCReadedState
状态2:SUnreadCReadState
状态3:SUnreadCUnreadState
状态4:SUnsavedCUnreadState
状态5:SUnsavedCReadedState
根据《设计模式》书中的State模式,实现如下:
1 publicinterfaceIMsgState
2 {
3 voidMaskReaded(IMessagemsg); //标为已读
4 voidMaskSaved(IMessagemsg); //标为同步
5 BooleanNeedInsert{get;} //是否Insert
6 BooleanNeedUpdate{get;} //是否Update
7 BooleanReaded{get;} //是否已读
8 }
9
10 publicinterfaceIMessage
11 {
12 voidMaskReaded();
13
14 voidMaskSaved();
15
16 BooleanNeedInsert{get;}
17
18 BooleanNeedUpdate{get;}
19
20 BooleanReaded{get;}
21
22 voidChangeState(IMsgStatenewState);
23 }
24
25 publicclassMessage:IMessage
26 {
27 privateIMsgStatestate;
28
29 publicMessage(IMsgStateinitState)
30 {
31 state=initState;
32 }
33
34 #regionIMessage成员
35
36 publicvoidMaskReaded()
37 {
38 state.MaskReaded(this);
39 }
40
41 publicvoidMaskSaved()
42 {
43 state.MaskSaved(this);
44 }
45
46 publicboolNeedInsert
47 {
48 get{returnstate.NeedInsert;}
49 }
50
51 publicboolNeedUpdate
52 {
53 get{returnstate.NeedUpdate;}
54 }
55
56 publicboolReaded
57 {
58 get{returnstate.Readed;}
59 }
60
61 publicvoidChangeState(IMsgStatenewState)
62 {
63 this.state=newState;
64 }
65
66 #endregion
67 }
68
69 publicclassSReadedCReadedState:IMsgState
70 {
71 privatestaticSReadedCReadedStateinstance=newSReadedCReadedState();
72 publicstaticSReadedCReadedStateInstance
73 {
74 get{returninstance;}
75 }
76
77 #regionIMsgState成员
78
79 publicvoidMaskReaded(IMessagemsg)
80 {
81 msg.ChangeState(SReadedCReadedState.Instance);
82 }
83
84 publicvoidMaskSaved(IMessagemsg)
85 {
86 msg.ChangeState(SReadedCReadedState.Instance);
87 }
88
89 publicboolNeedInsert
90 {
91 get{returnfalse;}
92 }
93
94 publicboolNeedUpdate
95 {
96 get{returnfalse;}
97 }
98
99 publicboolReaded
100 {
101 get{returntrue;}
102 }
103
104 #endregion
105 }
106
107 publicclassSUnreadCUnreadState:IMsgState
108 {
109 privatestaticSUnreadCUnreadStateinstance=newSUnreadCUnreadState();
110 publicstaticSUnreadCUnreadStateInstance
111 {
112 get{returninstance;}
113 }
114
115 #regionIMsgState成员
116
117 publicvoidMaskReaded(IMessagemsg)
118 {
119 msg.ChangeState(SUnreadCReadState.Instance);
120 }
121
122 publicvoidMaskSaved(IMessagemsg)
123 {
124 msg.ChangeState(SUnreadCUnreadState.Instance);
125 }
126
127 publicboolNeedInsert
128 {
129 get{returnfalse;}
130 }
131
132 publicboolNeedUpdate
133 {
134 get{returnfalse;}
135 }
136
137 publicboolReaded
138 {
139 get{returnfalse;}
140 }
141 #endregion
142 }
143
144 publicclassSUnreadCReadState:IMsgState
145 {
146 privatestaticSUnreadCReadStateinstance=newSUnreadCReadState();
147 publicstaticSUnreadCReadStateInstance
148 {
149 get{returninstance;}
150 }
151
152 #regionIMsgState成员
153
154 publicvoidMaskReaded(IMessagemsg)
155 {
156 msg.ChangeState(SUnreadCReadState.Instance);
157 }
158
159 publicvoidMaskSaved(IMessagemsg)
160 {
161 msg.ChangeState(SReadedCReadedState.Instance);
162 }
163
164 publicboolNeedInsert
165 {
166 get{returnfalse;}
167 }
168
169 publicboolNeedUpdate
170 {
171 get{returntrue;}
172 }
173
174 publicboolReaded
175 {
176 get{returntrue;}
177 }
178
179 #endregion
180 }
181
182 publicclassSUnsavedCUnreadState:IMsgState
183 {
184 privatestaticSUnsavedCUnreadStateinstance=newSUnsavedCUnreadState();
185 publicstaticSUnsavedCUnreadStateInstance
186 {
187 get{returninstance;}
188 }
189
190 #regionIMsgState成员
191
192 publicvoidMaskReaded(IMessagemsg)
193 {
194 msg.ChangeState(SUnsavedCReadedState.Instance);
195 }
196
197 publicvoidMaskSaved(IMessagemsg)
198 {
199 msg.ChangeState(SUnreadCUnreadState.Instance);
200 }
201
202 publicboolNeedInsert
203 {
204 get{returntrue;}
205 }
206
207 publicboolNeedUpdate
208 {
209 get{returnfalse;}
210 }
211
212 publicboolReaded
213 {
214 get{returnfalse;}
215 }
216
217 #endregion
218 }
219
220 publicclassSUnsavedCReadedState:IMsgState
221 {
222 privatestaticSUnsavedCReadedStateinstance=newSUnsavedCReadedState();
223 publicstaticSUnsavedCReadedStateInstance
224 {
225 get{returninstance;}
226 }
227
228 #regionIMsgState成员
229
230 publicvoidMaskReaded(IMessagemsg)
231 {
232 msg.ChangeState(SUnsavedCReadedState.Instance);
233 }
234
235 publicvoidMaskSaved(IMessagemsg)
236 {
237 msg.ChangeState(SReadedCReadedState.Instance);
238 }
239
240 publicboolNeedInsert
241 {
242 get{returntrue;}
243 }
244
245 publicboolNeedUpdate
246 {
247 get{returnfalse;}
248 }
249
250 publicboolReaded
251 {
252 get{returntrue;}
253 }
254
255 #endregion
256
假定消息存储在 IList<IMessage> msgs 之中,用户阅读操作:
1 voidRead(IMessagemsg)
2 {
3 //…doread,then:
4 msg.MaskReaded();
5 }
6
同步操作:
1 voidSave()
2 {
3 foreach(IMessagemsginmsgs)
4 {
5 if(msg.NeedInsert)
6 {
7 //insert…
8 }
9 if(msg.NeedUpdate)
10 {
11 //update
12 }
13
14 msg.MaskSaved();
15 }
16 }
17
三、泛型实现
上面的实现太长了,并且状态相关的逻辑分布在各个类之中,相隔太远,容易写错。下面试试用泛型实现。
鉴于 C#2.0泛型不能用值作为参数类型(郁闷!!!!!!!!),因此首先需要把bool和false构造成类型:
1 publicinterfaceIValueType<ValueType>
2 {
3 ValueTypeValue{get;}
4 }
5
6 publicclassTrueType:IValueType<bool>
7 {
8 publicboolValue{get{returntrue;}}
9 }
10
11 publicclassFalseType:IValueType<bool>
12 {
13 publicboolValue{get{returnfalse;}}
14 }
15
实现State模式:
1 publicinterfaceIMsgState
2 {
3 voidMaskReaded(IMessagemsg); //标为已读
4 voidMaskSaved(IMessagemsg); //标为同步
5 BooleanNeedInsert{get;} //是否Insert
6 BooleanNeedUpdate{get;} //是否Update
7 BooleanReaded{get;} //是否已读
8 }
9
10 publicinterfaceIMessage
11 {
12 voidMaskReaded();
13
14 voidMaskSaved();
15
16 BooleanNeedInsert{get;}
17
18 BooleanNeedUpdate{get;}
19
20 BooleanReaded{get;}
21
22 voidChangeState(IMsgStatenewState);
23 }
24
25 publicclassMessage:IMessage
26 {
27 privateIMsgStatestate;
28
29 publicMessage(IMsgStateinitState)
30 {
31 state=initState;
32 }
33
34 #regionIMessage成员
35
36 publicvoidMaskReaded()
37 {
38 state.MaskReaded(this);
39 }
40
41 publicvoidMaskSaved()
42 {
43 state.MaskSaved(this);
44 }
45
46 publicboolNeedInsert
47 {
48 get{returnstate.NeedInsert;}
49 }
50
51 publicboolNeedUpdate
52 {
53 get{returnstate.NeedUpdate;}
54 }
55
56 publicboolReaded
57 {
58 get{returnstate.Readed;}
59 }
60
61 publicvoidChangeState(IMsgStatenewState)
62 {
63 this.state=newState;
64 }
65
66 #endregion
67 }
68
69 publicclassMsgState
70 <MaskReadedToType,MaskSavedToType,
71 NeedInsertValueType,NeedUpdateValueType,
72 ReadedValueType>
73 :IMsgState
74 whereMaskReadedToType:IMsgState,new()
75 whereMaskSavedToType:IMsgState,new()
76 whereNeedInsertValueType:IValueType<bool>,new()
77 whereNeedUpdateValueType:IValueType<bool>,new()
78 whereReadedValueType:IValueType<bool>,new()
79 {
80 #regionIMsgState成员
81
82 publicvoidMaskReaded(IMessagemsg)
83 {
84 msg.ChangeState(newMaskReadedToType());
85 }
86
87 publicvoidMaskSaved(IMessagemsg)
88 {
89 msg.ChangeState(newMaskSavedToType());
90 }
91
92 #endregion
93
94 #regionIMsgState成员
95
96
97 publicboolNeedInsert
98 {
99 get{returnnewNeedInsertValueType().Value;}
100 }
101
102 publicboolNeedUpdate
103 {
104 get{returnnewNeedUpdateValueType().Value;}
105 }
106
107 publicboolReaded
108 {
109 get{returnnewReadedValueType().Value;}
110 }
111
112 #endregion
113 }
114
115 publicclassSReadedCReadedState:
116 MsgState<SReadedCReadedState,SReadedCReadedState,
117 FalseType,FalseType,TrueType>{}
118
119 publicclassSUnreadCUnreadState:
120 MsgState<SUnreadCReadState,SUnreadCUnreadState,
121 FalseType,TrueType,FalseType>{}
122
123 publicclassSUnreadCReadState:
124 MsgState<SUnreadCReadState,SReadedCReadedState,
125 FalseType,FalseType,TrueType>{}
126
127 publicclassSUnsavedCUnreadState:
128 MsgState<SUnsavedCReadedState,SUnreadCUnreadState,
129 TrueType,FalseType,FalseType>{}
130
131 publicclassSUnsavedCReadedState:
132 MsgState<SUnsavedCReadedState,SReadedCReadedState,
133 TrueType,FalseType,TrueType>{}
134
其余操作同上:
1 voidRead(IMessagemsg)
2 {
3 //…doread,then:
4 msg.MaskReaded();
5 }
6
7 voidSave()
8 {
9 foreach(IMessagemsginmsgs)
10 {
11 if(msg.NeedInsert)
12 {
13 //insert…
14 }
15 if(msg.NeedUpdate)
16 {
17 //update
18 }
19
20 msg.MaskSaved();
21 }
22 }
23
四、小结
由上可见,采用泛型实现的State模式代码量比不采用泛型实现的要少,更大的优点是,泛型实现中各种状态的定义比较短,这些定义可以放在一起,这样写起来也不容易写错,维护起来也比较简单。
(以上代码编译通过,逻辑上正确性与否我没验证----嘿嘿,事情讲清楚就可以了......)
状态2 已读 未读 是 否
状态3 未读 未读 否 否
状态4 未读 无 否 是
状态5 已读 无 否 是
用户阅读信息以及数据库同步操作可能导致用户状态改变。状态图如下:
二、实现
先给状态取名字:
状态1:SReadedCReadedState
状态2:SUnreadCReadState
状态3:SUnreadCUnreadState
状态4:SUnsavedCUnreadState
状态5:SUnsavedCReadedState
根据《设计模式》书中的State模式,实现如下:
1 publicinterfaceIMsgState
2 {
3 voidMaskReaded(IMessagemsg); //标为已读
4 voidMaskSaved(IMessagemsg); //标为同步
5 BooleanNeedInsert{get;} //是否Insert
6 BooleanNeedUpdate{get;} //是否Update
7 BooleanReaded{get;} //是否已读
8 }
9
10 publicinterfaceIMessage
11 {
12 voidMaskReaded();
13
14 voidMaskSaved();
15
16 BooleanNeedInsert{get;}
17
18 BooleanNeedUpdate{get;}
19
20 BooleanReaded{get;}
21
22 voidChangeState(IMsgStatenewState);
23 }
24
25 publicclassMessage:IMessage
26 {
27 privateIMsgStatestate;
28
29 publicMessage(IMsgStateinitState)
30 {
31 state=initState;
32 }
33
34 #regionIMessage成员
35
36 publicvoidMaskReaded()
37 {
38 state.MaskReaded(this);
39 }
40
41 publicvoidMaskSaved()
42 {
43 state.MaskSaved(this);
44 }
45
46 publicboolNeedInsert
47 {
48 get{returnstate.NeedInsert;}
49 }
50
51 publicboolNeedUpdate
52 {
53 get{returnstate.NeedUpdate;}
54 }
55
56 publicboolReaded
57 {
58 get{returnstate.Readed;}
59 }
60
61 publicvoidChangeState(IMsgStatenewState)
62 {
63 this.state=newState;
64 }
65
66 #endregion
67 }
68
69 publicclassSReadedCReadedState:IMsgState
70 {
71 privatestaticSReadedCReadedStateinstance=newSReadedCReadedState();
72 publicstaticSReadedCReadedStateInstance
73 {
74 get{returninstance;}
75 }
76
77 #regionIMsgState成员
78
79 publicvoidMaskReaded(IMessagemsg)
80 {
81 msg.ChangeState(SReadedCReadedState.Instance);
82 }
83
84 publicvoidMaskSaved(IMessagemsg)
85 {
86 msg.ChangeState(SReadedCReadedState.Instance);
87 }
88
89 publicboolNeedInsert
90 {
91 get{returnfalse;}
92 }
93
94 publicboolNeedUpdate
95 {
96 get{returnfalse;}
97 }
98
99 publicboolReaded
100 {
101 get{returntrue;}
102 }
103
104 #endregion
105 }
106
107 publicclassSUnreadCUnreadState:IMsgState
108 {
109 privatestaticSUnreadCUnreadStateinstance=newSUnreadCUnreadState();
110 publicstaticSUnreadCUnreadStateInstance
111 {
112 get{returninstance;}
113 }
114
115 #regionIMsgState成员
116
117 publicvoidMaskReaded(IMessagemsg)
118 {
119 msg.ChangeState(SUnreadCReadState.Instance);
120 }
121
122 publicvoidMaskSaved(IMessagemsg)
123 {
124 msg.ChangeState(SUnreadCUnreadState.Instance);
125 }
126
127 publicboolNeedInsert
128 {
129 get{returnfalse;}
130 }
131
132 publicboolNeedUpdate
133 {
134 get{returnfalse;}
135 }
136
137 publicboolReaded
138 {
139 get{returnfalse;}
140 }
141 #endregion
142 }
143
144 publicclassSUnreadCReadState:IMsgState
145 {
146 privatestaticSUnreadCReadStateinstance=newSUnreadCReadState();
147 publicstaticSUnreadCReadStateInstance
148 {
149 get{returninstance;}
150 }
151
152 #regionIMsgState成员
153
154 publicvoidMaskReaded(IMessagemsg)
155 {
156 msg.ChangeState(SUnreadCReadState.Instance);
157 }
158
159 publicvoidMaskSaved(IMessagemsg)
160 {
161 msg.ChangeState(SReadedCReadedState.Instance);
162 }
163
164 publicboolNeedInsert
165 {
166 get{returnfalse;}
167 }
168
169 publicboolNeedUpdate
170 {
171 get{returntrue;}
172 }
173
174 publicboolReaded
175 {
176 get{returntrue;}
177 }
178
179 #endregion
180 }
181
182 publicclassSUnsavedCUnreadState:IMsgState
183 {
184 privatestaticSUnsavedCUnreadStateinstance=newSUnsavedCUnreadState();
185 publicstaticSUnsavedCUnreadStateInstance
186 {
187 get{returninstance;}
188 }
189
190 #regionIMsgState成员
191
192 publicvoidMaskReaded(IMessagemsg)
193 {
194 msg.ChangeState(SUnsavedCReadedState.Instance);
195 }
196
197 publicvoidMaskSaved(IMessagemsg)
198 {
199 msg.ChangeState(SUnreadCUnreadState.Instance);
200 }
201
202 publicboolNeedInsert
203 {
204 get{returntrue;}
205 }
206
207 publicboolNeedUpdate
208 {
209 get{returnfalse;}
210 }
211
212 publicboolReaded
213 {
214 get{returnfalse;}
215 }
216
217 #endregion
218 }
219
220 publicclassSUnsavedCReadedState:IMsgState
221 {
222 privatestaticSUnsavedCReadedStateinstance=newSUnsavedCReadedState();
223 publicstaticSUnsavedCReadedStateInstance
224 {
225 get{returninstance;}
226 }
227
228 #regionIMsgState成员
229
230 publicvoidMaskReaded(IMessagemsg)
231 {
232 msg.ChangeState(SUnsavedCReadedState.Instance);
233 }
234
235 publicvoidMaskSaved(IMessagemsg)
236 {
237 msg.ChangeState(SReadedCReadedState.Instance);
238 }
239
240 publicboolNeedInsert
241 {
242 get{returntrue;}
243 }
244
245 publicboolNeedUpdate
246 {
247 get{returnfalse;}
248 }
249
250 publicboolReaded
251 {
252 get{returntrue;}
253 }
254
255 #endregion
256
一、问题来源
目前时兴这样的应用:用户采用Jabber(一种开源即时通讯协议)客户端登录Jabber服务器,然后再经过MSN中转站,就可以与MSN用户通讯了。系统结构如下:
其中中转服务器实现协议翻译。假设存在这样一种情况,就是客户端和中转服务器采用的不是那种双向通讯,而是如Html这样单向通讯手段(假设不用Ajax),客户端没有存储能力,因此需要把信息存储在中转服务器的数据库中。中转服务器的流量很大,当接收到信息或者用户阅读未读信息后,不能实时进行数据库的Insert和Update操作,而是定期轮询,进行批量处理。
中转服务器将消息存储在消息容器中。线程模型如下:
主要有三类线程:
(1)服务器监听线程监听来自第三方服务器的数据包,解析成消息对象,存储在消息容器中。
(2)用户服务线程根据用户的请求,取出消息,发送给用户,同时改变消息的状态,如果消息为“未读”,则改变为“已读”。
(3)数据库同步线程定期检查所有消息,根据消息状态,判断客户端的消息状态是否和数据库中储存的状态一致,如果不一致,则进行Update操作,如果数据库中不存在,则进行Insert操作。
消息一共有五种状态:
客户端是否已读 数据库中存储的状态 需要Update 需要Insert操作
状态1 已读 已读 否 否
状态2 已读 未读 是 否
状态3 未读 未读 否 否
状态4 未读 无 否 是
状态5 已读 无 否 是
用户阅读信息以及数据库同步操作可能导致用户状态改变。状态图如下:
二、实现
先给状态取名字:
状态1:SReadedCReadedState
状态2:SUnreadCReadState
状态3:SUnreadCUnreadState
状态4:SUnsavedCUnreadState
状态5:SUnsavedCReadedState
根据《设计模式》书中的State模式,实现如下:
1 publicinterfaceIMsgState
2 {
3 voidMaskReaded(IMessagemsg); //标为已读
4 voidMaskSaved(IMessagemsg); //标为同步
5 BooleanNeedInsert{get;} //是否Insert
6 BooleanNeedUpdate{get;} //是否Update
7 BooleanReaded{get;} //是否已读
8 }
9
10 publicinterfaceIMessage
11 {
12 voidMaskReaded();
13
14 voidMaskSaved();
15
16 BooleanNeedInsert{get;}
17
18 BooleanNeedUpdate{get;}
19
20 BooleanReaded{get;}
21
22 voidChangeState(IMsgStatenewState);
23 }
24
25 publicclassMessage:IMessage
26 {
27 privateIMsgStatestate;
28
29 publicMessage(IMsgStateinitState)
30 {
31 state=initState;
32 }
33
34 #regionIMessage成员
35
36 publicvoidMaskReaded()
37 {
38 state.MaskReaded(this);
39 }
40
41 publicvoidMaskSaved()
42 {
43 state.MaskSaved(this);
44 }
45
46 publicboolNeedInsert
47 {
48 get{returnstate.NeedInsert;}
49 }
50
51 publicboolNeedUpdate
52 {
53 get{returnstate.NeedUpdate;}
54 }
55
56 publicboolReaded
57 {
58 get{returnstate.Readed;}
59 }
60
61 publicvoidChangeState(IMsgStatenewState)
62 {
63 this.state=newState;
64 }
65
66 #endregion
67 }
68
69 publicclassSReadedCReadedState:IMsgState
70 {
71 privatestaticSReadedCReadedStateinstance=newSReadedCReadedState();
72 publicstaticSReadedCReadedStateInstance
73 {
74 get{returninstance;}
75 }
76
77 #regionIMsgState成员
78
79 publicvoidMaskReaded(IMessagemsg)
80 {
81 msg.ChangeState(SReadedCReadedState.Instance);
82 }
83
84 publicvoidMaskSaved(IMessagemsg)
85 {
86 msg.ChangeState(SReadedCReadedState.Instance);
87 }
88
89 publicboolNeedInsert
90 {
91 get{returnfalse;}
92 }
93
94 publicboolNeedUpdate
95 {
96 get{returnfalse;}
97 }
98
99 publicboolReaded
100 {
101 get{returntrue;}
102 }
103
104 #endregion
105 }
106
107 publicclassSUnreadCUnreadState:IMsgState
108 {
109 privatestaticSUnreadCUnreadStateinstance=newSUnreadCUnreadState();
110 publicstaticSUnreadCUnreadStateInstance
111 {
112 get{returninstance;}
113 }
114
115 #regionIMsgState成员
116
117 publicvoidMaskReaded(IMessagemsg)
118 {
119 msg.ChangeState(SUnreadCReadState.Instance);
120 }
121
122 publicvoidMaskSaved(IMessagemsg)
123 {
124 msg.ChangeState(SUnreadCUnreadState.Instance);
125 }
126
127 publicboolNeedInsert
128 {
129 get{returnfalse;}
130 }
131
132 publicboolNeedUpdate
133 {
134 get{returnfalse;}
135 }
136
137 publicboolReaded
138 {
139 get{returnfalse;}
140 }
141 #endregion
142 }
143
144 publicclassSUnreadCReadState:IMsgState
145 {
146 privatestaticSUnreadCReadStateinstance=newSUnreadCReadState();
147 publicstaticSUnreadCReadStateInstance
148 {
149 get{returninstance;}
150 }
151
152 #regionIMsgState成员
153
154 publicvoidMaskReaded(IMessagemsg)
155 {
156 msg.ChangeState(SUnreadCReadState.Instance);
157 }
158
159 publicvoidMaskSaved(IMessagemsg)
160 {
161 msg.ChangeState(SReadedCReadedState.Instance);
162 }
163
164 publicboolNeedInsert
165 {
166 get{returnfalse;}
167 }
168
169 publicboolNeedUpdate
170 {
171 get{returntrue;}
172 }
173
174 publicboolReaded
175 {
176 get{returntrue;}
177 }
178
179 #endregion
180 }
181
182 publicclassSUnsavedCUnreadState:IMsgState
183 {
184 privatestaticSUnsavedCUnreadStateinstance=newSUnsavedCUnreadState();
185 publicstaticSUnsavedCUnreadStateInstance
186 {
187 get{returninstance;}
188 }
189
190 #regionIMsgState成员
191
192 publicvoidMaskReaded(IMessagemsg)
193 {
194 msg.ChangeState(SUnsavedCReadedState.Instance);
195 }
196
197 publicvoidMaskSaved(IMessagemsg)
198 {
199 msg.ChangeState(SUnreadCUnreadState.Instance);
200 }
201
202 publicboolNeedInsert
203 {
204 get{returntrue;}
205 }
206
207 publicboolNeedUpdate
208 {
209 get{returnfalse;}
210 }
211
212 publicboolReaded
213 {
214 get{returnfalse;}
215 }
216
217 #endregion
218 }
219
220 publicclassSUnsavedCReadedState:IMsgState
221 {
222 privatestaticSUnsavedCReadedStateinstance=newSUnsavedCReadedState();
223 publicstaticSUnsavedCReadedStateInstance
224 {
225 get{returninstance;}
226 }
227
228 #regionIMsgState成员
229
230 publicvoidMaskReaded(IMessagemsg)
231 {
232 msg.ChangeState(SUnsavedCReadedState.Instance);
233 }
234
235 publicvoidMaskSaved(IMessagemsg)
236 {
237 msg.ChangeState(SReadedCReadedState.Instance);
238 }
239
240 publicboolNeedInsert
241 {
242 get{returntrue;}
243 }
244
245 publicboolNeedUpdate
246 {
247 get{returnfalse;}
248 }
249
250 publicboolReaded
251 {
252 get{returntrue;}
253 }
254
255 #endregion
256
假定消息存储在 IList<IMessage> msgs 之中,用户阅读操作:
1 voidRead(IMessagemsg)
2 {
3 //…doread,then:
4 msg.MaskReaded();
5 }
6
同步操作:
1 voidSave()
2 {
3 foreach(IMessagemsginmsgs)
4 {
5 if(msg.NeedInsert)
6 {
7 //insert…
8 }
9 if(msg.NeedUpdate)
10 {
11 //update
12 }
13
14 msg.MaskSaved();
15 }
16 }
17
三、泛型实现
上面的实现太长了,并且状态相关的逻辑分布在各个类之中,相隔太远,容易写错。下面试试用泛型实现。
鉴于 C#2.0泛型不能用值作为参数类型(郁闷!!!!!!!!),因此首先需要把bool和false构造成类型:
1 publicinterfaceIValueType<ValueType>
2 {
3 ValueTypeValue{get;}
4 }
5
6 publicclassTrueType:IValueType<bool>
7 {
8 publicboolValue{get{returntrue;}}
9 }
10
11 publicclassFalseType:IValueType<bool>
12 {
13 publicboolValue{get{returnfalse;}}
14 }
15
实现State模式:
1 publicinterfaceIMsgState
2 {
3 voidMaskReaded(IMessagemsg); //标为已读
4 voidMaskSaved(IMessagemsg); //标为同步
5 BooleanNeedInsert{get;} //是否Insert
6 BooleanNeedUpdate{get;} //是否Update
7 BooleanReaded{get;} //是否已读
8 }
9
10 publicinterfaceIMessage
11 {
12 voidMaskReaded();
13
14 voidMaskSaved();
15
16 BooleanNeedInsert{get;}
17
18 BooleanNeedUpdate{get;}
19
20 BooleanReaded{get;}
21
22 voidChangeState(IMsgStatenewState);
23 }
24
25 publicclassMessage:IMessage
26 {
27 privateIMsgStatestate;
28
29 publicMessage(IMsgStateinitState)
30 {
31 state=initState;
32 }
33
34 #regionIMessage成员
35
36 publicvoidMaskReaded()
37 {
38 state.MaskReaded(this);
39 }
40
41 publicvoidMaskSaved()
42 {
43 state.MaskSaved(this);
44 }
45
46 publicboolNeedInsert
47 {
48 get{returnstate.NeedInsert;}
49 }
50
51 publicboolNeedUpdate
52 {
53 get{returnstate.NeedUpdate;}
54 }
55
56 publicboolReaded
57 {
58 get{returnstate.Readed;}
59 }
60
61 publicvoidChangeState(IMsgStatenewState)
62 {
63 this.state=newState;
64 }
65
66 #endregion
67 }
68
69 publicclassMsgState
70 <MaskReadedToType,MaskSavedToType,
71 NeedInsertValueType,NeedUpdateValueType,
72 ReadedValueType>
73 :IMsgState
74 whereMaskReadedToType:IMsgState,new()
75 whereMaskSavedToType:IMsgState,new()
76 whereNeedInsertValueType:IValueType<bool>,new()
77 whereNeedUpdateValueType:IValueType<bool>,new()
78 whereReadedValueType:IValueType<bool>,new()
79 {
80 #regionIMsgState成员
81
82 publicvoidMaskReaded(IMessagemsg)
83 {
84 msg.ChangeState(newMaskReadedToType());
85 }
86
87 publicvoidMaskSaved(IMessagemsg)
88 {
89 msg.ChangeState(newMaskSavedToType());
90 }
91
92 #endregion
93
94 #regionIMsgState成员
95
96
97 publicboolNeedInsert
98 {
99 get{returnnewNeedInsertValueType().Value;}
100 }
101
102 publicboolNeedUpdate
103 {
104 get{returnnewNeedUpdateValueType().Value;}
105 }
106
107 publicboolReaded
108 {
109 get{returnnewReadedValueType().Value;}
110 }
111
112 #endregion
113 }
114
115 publicclassSReadedCReadedState:
116 MsgState<SReadedCReadedState,SReadedCReadedState,
117 FalseType,FalseType,TrueType>{}
118
119 publicclassSUnreadCUnreadState:
120 MsgState<SUnreadCReadState,SUnreadCUnreadState,
121 FalseType,TrueType,FalseType>{}
122
123 publicclassSUnreadCReadState:
124 MsgState<SUnreadCReadState,SReadedCReadedState,
125 FalseType,FalseType,TrueType>{}
126
127 publicclassSUnsavedCUnreadState:
128 MsgState<SUnsavedCReadedState,SUnreadCUnreadState,
129 TrueType,FalseType,FalseType>{}
130
131 publicclassSUnsavedCReadedState:
132 MsgState<SUnsavedCReadedState,SReadedCReadedState,
133 TrueType,FalseType,TrueType>{}
134
其余操作同上:
1 voidRead(IMessagemsg)
2 {
3 //…doread,then:
4 msg.MaskReaded();
5 }
6
7 voidSave()
8 {
9 foreach(IMessagemsginmsgs)
10 {
11 if(msg.NeedInsert)
12 {
13 //insert…
14 }
15 if(msg.NeedUpdate)
16 {
17 //update
18 }
19
20 msg.MaskSaved();
21 }
22 }
23
四、小结
由上可见,采用泛型实现的State模式代码量比不采用泛型实现的要少,更大的优点是,泛型实现中各种状态的定义比较短,这些定义可以放在一起,这样写起来也不容易写错,维护起来也比较简单。
(以上代码编译通过,逻辑上正确性与否我没验证----嘿嘿,事情讲清楚就可以了......)
状态2 已读 未读 是 否
状态3 未读 未读 否 否
状态4 未读 无 否 是
状态5 已读 无 否 是
用户阅读信息以及数据库同步操作可能导致用户状态改变。状态图如下:
二、实现
先给状态取名字:
状态1:SReadedCReadedState
状态2:SUnreadCReadState
状态3:SUnreadCUnreadState
状态4:SUnsavedCUnreadState
状态5:SUnsavedCReadedState
根据《设计模式》书中的State模式,实现如下:
1 publicinterfaceIMsgState
2 {
3 voidMaskReaded(IMessagemsg); //标为已读
4 voidMaskSaved(IMessagemsg); //标为同步
5 BooleanNeedInsert{get;} //是否Insert
6 BooleanNeedUpdate{get;} //是否Update
7 BooleanReaded{get;} //是否已读
8 }
9
10 publicinterfaceIMessage
11 {
12 voidMaskReaded();
13
14 voidMaskSaved();
15
16 BooleanNeedInsert{get;}
17
18 BooleanNeedUpdate{get;}
19
20 BooleanReaded{get;}
21
22 voidChangeState(IMsgStatenewState);
23 }
24
25 publicclassMessage:IMessage
26 {
27 privateIMsgStatestate;
28
29 publicMessage(IMsgStateinitState)
30 {
31 state=initState;
32 }
33
34 #regionIMessage成员
35
36 publicvoidMaskReaded()
37 {
38 state.MaskReaded(this);
39 }
40
41 publicvoidMaskSaved()
42 {
43 state.MaskSaved(this);
44 }
45
46 publicboolNeedInsert
47 {
48 get{returnstate.NeedInsert;}
49 }
50
51 publicboolNeedUpdate
52 {
53 get{returnstate.NeedUpdate;}
54 }
55
56 publicboolReaded
57 {
58 get{returnstate.Readed;}
59 }
60
61 publicvoidChangeState(IMsgStatenewState)
62 {
63 this.state=newState;
64 }
65
66 #endregion
67 }
68
69 publicclassSReadedCReadedState:IMsgState
70 {
71 privatestaticSReadedCReadedStateinstance=newSReadedCReadedState();
72 publicstaticSReadedCReadedStateInstance
73 {
74 get{returninstance;}
75 }
76
77 #regionIMsgState成员
78
79 publicvoidMaskReaded(IMessagemsg)
80 {
81 msg.ChangeState(SReadedCReadedState.Instance);
82 }
83
84 publicvoidMaskSaved(IMessagemsg)
85 {
86 msg.ChangeState(SReadedCReadedState.Instance);
87 }
88
89 publicboolNeedInsert
90 {
91 get{returnfalse;}
92 }
93
94 publicboolNeedUpdate
95 {
96 get{returnfalse;}
97 }
98
99 publicboolReaded
100 {
101 get{returntrue;}
102 }
103
104 #endregion
105 }
106
107 publicclassSUnreadCUnreadState:IMsgState
108 {
109 privatestaticSUnreadCUnreadStateinstance=newSUnreadCUnreadState();
110 publicstaticSUnreadCUnreadStateInstance
111 {
112 get{returninstance;}
113 }
114
115 #regionIMsgState成员
116
117 publicvoidMaskReaded(IMessagemsg)
118 {
119 msg.ChangeState(SUnreadCReadState.Instance);
120 }
121
122 publicvoidMaskSaved(IMessagemsg)
123 {
124 msg.ChangeState(SUnreadCUnreadState.Instance);
125 }
126
127 publicboolNeedInsert
128 {
129 get{returnfalse;}
130 }
131
132 publicboolNeedUpdate
133 {
134 get{returnfalse;}
135 }
136
137 publicboolReaded
138 {
139 get{returnfalse;}
140 }
141 #endregion
142 }
143
144 publicclassSUnreadCReadState:IMsgState
145 {
146 privatestaticSUnreadCReadStateinstance=newSUnreadCReadState();
147 publicstaticSUnreadCReadStateInstance
148 {
149 get{returninstance;}
150 }
151
152 #regionIMsgState成员
153
154 publicvoidMaskReaded(IMessagemsg)
155 {
156 msg.ChangeState(SUnreadCReadState.Instance);
157 }
158
159 publicvoidMaskSaved(IMessagemsg)
160 {
161 msg.ChangeState(SReadedCReadedState.Instance);
162 }
163
164 publicboolNeedInsert
165 {
166 get{returnfalse;}
167 }
168
169 publicboolNeedUpdate
170 {
171 get{returntrue;}
172 }
173
174 publicboolReaded
175 {
176 get{returntrue;}
177 }
178
179 #endregion
180 }
181
182 publicclassSUnsavedCUnreadState:IMsgState
183 {
184 privatestaticSUnsavedCUnreadStateinstance=newSUnsavedCUnreadState();
185 publicstaticSUnsavedCUnreadStateInstance
186 {
187 get{returninstance;}
188 }
189
190 #regionIMsgState成员
191
192 publicvoidMaskReaded(IMessagemsg)
193 {
194 msg.ChangeState(SUnsavedCReadedState.Instance);
195 }
196
197 publicvoidMaskSaved(IMessagemsg)
198 {
199 msg.ChangeState(SUnreadCUnreadState.Instance);
200 }
201
202 publicboolNeedInsert
203 {
204 get{returntrue;}
205 }
206
207 publicboolNeedUpdate
208 {
209 get{returnfalse;}
210 }
211
212 publicboolReaded
213 {
214 get{returnfalse;}
215 }
216
217 #endregion
218 }
219
220 publicclassSUnsavedCReadedState:IMsgState
221 {
222 privatestaticSUnsavedCReadedStateinstance=newSUnsavedCReadedState();
223 publicstaticSUnsavedCReadedStateInstance
224 {
225 get{returninstance;}
226 }
227
228 #regionIMsgState成员
229
230 publicvoidMaskReaded(IMessagemsg)
231 {
232 msg.ChangeState(SUnsavedCReadedState.Instance);
233 }
234
235 publicvoidMaskSaved(IMessagemsg)
236 {
237 msg.ChangeState(SReadedCReadedState.Instance);
238 }
239
240 publicboolNeedInsert
241 {
242 get{returntrue;}
243 }
244
245 publicboolNeedUpdate
246 {
247 get{returnfalse;}
248 }
249
250 publicboolReaded
251 {
252 get{returntrue;}
253 }
254
255 #endregion
256
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数