一、问题来源

目前时兴这样的应用:用户采用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     public interface IMsgState
  2     {
  3         void MaskReaded(IMessage msg);  // 标为已读
  4         void MaskSaved(IMessage msg);   // 标为同步
  5         Boolean NeedInsert { get; }     // 是否Insert
  6         Boolean NeedUpdate { get;}      // 是否Update
  7         Boolean Readed { get;}          // 是否已读
  8     }
  9 
 10     public interface IMessage
 11     {
 12         void MaskReaded();
 13 
 14         void MaskSaved();
 15 
 16         Boolean NeedInsert { get; }
 17 
 18         Boolean NeedUpdate { get;}
 19 
 20         Boolean Readed { get;} 
 21 
 22         void ChangeState(IMsgState newState);
 23     }
 24 
 25     public class Message : IMessage
 26     {
 27         private IMsgState state;
 28 
 29         public Message(IMsgState initState)
 30         {
 31             state = initState;
 32         }
 33 
 34         #region IMessage 成员
 35 
 36         public void MaskReaded()
 37         {
 38             state.MaskReaded(this);
 39         }
 40 
 41         public void MaskSaved()
 42         {
 43             state.MaskSaved(this);
 44         }
 45 
 46         public bool NeedInsert
 47         {
 48             get { return state.NeedInsert; }
 49         }
 50 
 51         public bool NeedUpdate
 52         {
 53             get { return state.NeedUpdate; }
 54         }
 55 
 56         public bool Readed
 57         {
 58             get { return state.Readed; }
 59         }
 60 
 61         public void ChangeState(IMsgState newState)
 62         {
 63             this.state = newState;
 64         }
 65 
 66         #endregion
 67     }
 68 
 69     public class SReadedCReadedState : IMsgState
 70     {
 71         private static SReadedCReadedState instance = new SReadedCReadedState();
 72         public static SReadedCReadedState Instance
 73         {
 74             get { return instance; }
 75         }
 76 
 77         #region IMsgState 成员
 78 
 79         public void MaskReaded(IMessage msg)
 80         {
 81             msg.ChangeState(SReadedCReadedState.Instance);
 82         }
 83 
 84         public void MaskSaved(IMessage msg)
 85         {
 86             msg.ChangeState(SReadedCReadedState.Instance);
 87         }
 88 
 89         public bool NeedInsert
 90         {
 91             get { return false; }
 92         }
 93 
 94         public bool NeedUpdate
 95         {
 96             get { return false; }
 97         }
 98 
 99         public bool Readed
100         {
101             get { return true; }
102         }
103 
104         #endregion
105     }
106 
107     public class SUnreadCUnreadState : IMsgState
108     {
109         private static SUnreadCUnreadState instance = new SUnreadCUnreadState();
110         public static SUnreadCUnreadState Instance
111         {
112             get { return instance; }
113         }
114 
115         #region IMsgState 成员
116 
117         public void MaskReaded(IMessage msg)
118         {
119             msg.ChangeState(SUnreadCReadState.Instance);
120         }
121 
122         public void MaskSaved(IMessage msg)
123         {
124             msg.ChangeState(SUnreadCUnreadState.Instance);
125         }
126 
127         public bool NeedInsert
128         {
129             get { return false; }
130         }
131 
132         public bool NeedUpdate
133         {
134             get { return false; }
135         }
136 
137         public bool Readed
138         {
139             get { return false; }
140         }
141         #endregion
142     }
143 
144     public class SUnreadCReadState : IMsgState
145     {
146         private static SUnreadCReadState instance = new SUnreadCReadState();
147         public static SUnreadCReadState Instance
148         {
149             get { return instance; }
150         }
151 
152         #region IMsgState 成员
153 
154         public void MaskReaded(IMessage msg)
155         {
156             msg.ChangeState(SUnreadCReadState.Instance);
157         }
158 
159         public void MaskSaved(IMessage msg)
160         {
161             msg.ChangeState(SReadedCReadedState.Instance);
162         }
163 
164         public bool NeedInsert
165         {
166             get { return false; }
167         }
168 
169         public bool NeedUpdate
170         {
171             get { return true; }
172         }
173 
174         public bool Readed
175         {
176             get { return true; }
177         }
178 
179         #endregion
180     }
181 
182     public class SUnsavedCUnreadState : IMsgState
183     {
184         private static SUnsavedCUnreadState instance = new SUnsavedCUnreadState();
185         public static SUnsavedCUnreadState Instance
186         {
187             get { return instance; }
188         }
189 
190         #region IMsgState 成员
191 
192         public void MaskReaded(IMessage msg)
193         {
194             msg.ChangeState(SUnsavedCReadedState.Instance);
195         }
196 
197         public void MaskSaved(IMessage msg)
198         {
199             msg.ChangeState(SUnreadCUnreadState.Instance);
200         }
201 
202         public bool NeedInsert
203         {
204             get { return true; }
205         }
206 
207         public bool NeedUpdate
208         {
209             get { return false; }
210         }
211 
212         public bool Readed
213         {
214             get { return false; }
215         }
216 
217         #endregion
218     }
219 
220     public class SUnsavedCReadedState : IMsgState
221     {
222         private static SUnsavedCReadedState instance = new SUnsavedCReadedState();
223         public static SUnsavedCReadedState Instance
224         {
225             get { return instance; }
226         }
227 
228         #region IMsgState 成员
229 
230         public void MaskReaded(IMessage msg)
231         {
232             msg.ChangeState(SUnsavedCReadedState.Instance);
233         }
234 
235         public void MaskSaved(IMessage msg)
236         {
237             msg.ChangeState(SReadedCReadedState.Instance);
238         }
239 
240         public bool NeedInsert
241         {
242             get { return true; }
243         }
244 
245         public bool NeedUpdate
246         {
247             get { return false; }
248         }
249 
250         public bool Readed
251         {
252             get { return true; }
253         }
254 
255         #endregion
256 

假定消息存储在 IList<IMessage> msgs 之中,用户阅读操作:

1         void Read(IMessage msg)
2         {
3             //  do read, then:
4             msg.MaskReaded();
5         }

同步操作:

 1         void Save()
 2         {
 3             foreach (IMessage msg in msgs)
 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     public interface IValueType<ValueType>
 2     {
 3         ValueType Value { get;}
 4     }
 5 
 6     public class TrueType : IValueType<bool>
 7     {
 8         public bool Value { get { return true; } }
 9     }
10 
11     public class FalseType : IValueType<bool>
12     {
13         public bool Value { get { return false; } }
14     }
15 

实现State模式:

  1     public interface IMsgState
  2     {
  3         void MaskReaded(IMessage msg);  // 标为已读
  4         void MaskSaved(IMessage msg);   // 标为同步
  5         Boolean NeedInsert { get; }     // 是否Insert
  6         Boolean NeedUpdate { get;}      // 是否Update
  7         Boolean Readed { get;}          // 是否已读
  8     }
  9 
 10     public interface IMessage
 11     {
 12         void MaskReaded();
 13 
 14         void MaskSaved();
 15 
 16         Boolean NeedInsert { get; }
 17 
 18         Boolean NeedUpdate { get;}
 19 
 20         Boolean Readed { get;}
 21 
 22         void ChangeState(IMsgState newState);
 23     }
 24 
 25     public class Message : IMessage
 26     {
 27         private IMsgState state;
 28 
 29         public Message(IMsgState initState)
 30         {
 31             state = initState;
 32         }
 33 
 34         #region IMessage 成员
 35 
 36         public void MaskReaded()
 37         {
 38             state.MaskReaded(this);
 39         }
 40 
 41         public void MaskSaved()
 42         {
 43             state.MaskSaved(this);
 44         }
 45 
 46         public bool NeedInsert
 47         {
 48             get { return state.NeedInsert; }
 49         }
 50 
 51         public bool NeedUpdate
 52         {
 53             get { return state.NeedUpdate; }
 54         }
 55 
 56         public bool Readed
 57         {
 58             get { return state.Readed; }
 59         }
 60 
 61         public void ChangeState(IMsgState newState)
 62         {
 63             this.state = newState;
 64         }
 65 
 66         #endregion
 67     }
 68 
 69     public class MsgState
 70         <MaskReadedToType, MaskSavedToType, 
 71         NeedInsertValueType, NeedUpdateValueType,
 72         ReadedValueType>
 73     : IMsgState
 74         where MaskReadedToType : IMsgState, new()
 75         where MaskSavedToType : IMsgState, new()
 76         where NeedInsertValueType : IValueType<bool>, new()
 77         where NeedUpdateValueType : IValueType<bool>, new()
 78         where ReadedValueType : IValueType<bool>, new()
 79     {
 80         #region IMsgState 成员
 81 
 82         public void MaskReaded(IMessage msg)
 83         {
 84             msg.ChangeState(new MaskReadedToType());
 85         }
 86 
 87         public void MaskSaved(IMessage msg)
 88         {
 89             msg.ChangeState(new MaskSavedToType());
 90         }
 91 
 92         #endregion
 93 
 94         #region IMsgState 成员
 95 
 96 
 97         public bool NeedInsert
 98         {
 99             get { return new NeedInsertValueType().Value; } 
100         }
101 
102         public bool NeedUpdate
103         {
104             get { return new NeedUpdateValueType().Value; } 
105         }
106 
107         public bool Readed
108         {
109             get { return new ReadedValueType().Value; } 
110         }
111 
112         #endregion
113     }
114 
115     public class SReadedCReadedState:
116         MsgState<SReadedCReadedState, SReadedCReadedState, 
117         FalseType, FalseType, TrueType> { }
118 
119     public class SUnreadCUnreadState:
120         MsgState<SUnreadCReadState, SUnreadCUnreadState, 
121         FalseType, TrueType, FalseType> { }
122 
123     public class SUnreadCReadState:
124         MsgState<SUnreadCReadState, SReadedCReadedState, 
125         FalseType, FalseType, TrueType> { }
126 
127     public class SUnsavedCUnreadState:
128         MsgState<SUnsavedCReadedState, SUnreadCUnreadState, 
129         TrueType, FalseType, FalseType> { }
130 
131     public class SUnsavedCReadedState:
132         MsgState<SUnsavedCReadedState, SReadedCReadedState,
133         TrueType, FalseType, TrueType> { }
134 

其余操作同上:

 1         void Read(IMessage msg)
 2         {
 3             //  do read, then:
 4             msg.MaskReaded();
 5         }
 6 
 7         void Save()
 8         {
 9             foreach (IMessage msg in msgs)
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模式代码量比不采用泛型实现的要少,更大的优点是,泛型实现中各种状态的定义比较短,这些定义可以放在一起,这样写起来也不容易写错,维护起来也比较简单。

(以上代码编译通过,逻辑上正确性与否我没验证----嘿嘿,事情讲清楚就可以了......)

作者:兽族的荣耀:xiaotie at gmail dot com; http://xiaotie.cnblogs.com

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2006/12/18/595209.html如需转载请自行联系原作者

xiaotie 集异璧实验室(GEBLAB)

采用C#泛型实现状态(State)模式相关推荐

  1. 设计模式:状态(State)模式

    设计模式之状态(State)模式 在软件开发过程中,应用程序中的有些对象可能会根据不同的情况做出不同的行为,我们把这种对象称为有状态的对象,而把影响对象行为的一个或多个动态变化的属性称为状态.当有状态 ...

  2. 设计模式学习笔记——状态(State)模式框架

    设计模式学习笔记--状态(State)模式框架 @(设计模式)[设计模式, 状态模式, State] 设计模式学习笔记状态State模式框架 基本介绍 状态案例 类图 实现代码 State接口 Day ...

  3. 设计模式--状态(State)模式

    模式定义 允许一个对象在其内部状态改变时改变它的行为,从而使对象看起来似乎修改了其行为 类图 要点总结 State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时, ...

  4. 状态(State)模式

    状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的 ...

  5. C++之状态(State)模式

    0. 简介 状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样.这其实就有点类似算法中的有限状态机的形式. 其主要思想是程序在任意时刻仅可 ...

  6. 状态转移表+State模式

    为了给用户提供更好的体验方式,多级联动,多种选择方式,半智能化的容错能力等是我们采用的手段,同时这对软件的开发带来了更多的复杂性.我们需要考虑在各种不同状态下,按钮的功能,以及转换. 在我做过的若干项 ...

  7. java state用法_Java状态模式(State模式)

    State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elsei ...

  8. 理解vuex -- vue的状态管理模式

    2019独角兽企业重金招聘Python工程师标准>>> vuex是什么? 先引用vuex官网的话: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管 ...

  9. Android学习 StateMachine与State模式

    2019独角兽企业重金招聘Python工程师标准>>> 一 State模式 意图: 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类.(Objects for ...

  10. [设计模式][c++]状态切换模式

    转自:http://blog.csdn.net/yongh701/article/details/49154439 状态模式也是设计模式的一种,这种设计模式思想不复杂,就是实现起来的代码有点复杂.主要 ...

最新文章

  1. 苗旺:因果推断,观察性研究和 2021 年诺贝尔经济学奖
  2. 被劝退的学渣,逆袭成高级语言之父,改变编程方式却说“不喜欢写代码”!...
  3. CentOS7下搭建Nextcloud13.0.5
  4. JavaScript中类型检测
  5. VTK修炼之道53:图形基本操作进阶_多分辨率策略(模型细化的三种方法)
  6. 自定义ViewGroup(1)
  7. 博客社会学图——使用python检索网页上的友情链接
  8. 关于导航按钮在其他尺寸下显示问题
  9. Beta版本测试报告
  10. linux nslookup命令安装,在CentOS中安装nslookup命令
  11. k-近邻算法-优化约会网站的配对效果
  12. 均值聚类散点图怎么画_用Excel制作一个漂亮的分类散点图
  13. UNI/TUBE2新配对上线,Eswap迎来新机遇
  14. 情商 智商 逆商,哪个最重要?
  15. U8glib学习使用(详细版)
  16. 2021年国产数据库名录和产品信息一览
  17. mysql5.7 1698 28000_MySqlError1698(28000)问题的解决方法
  18. 什么是 CDP 和 LLDP?
  19. 去除COD有机物树脂A-722MP
  20. C语言中的TRUE和FALSE

热门文章

  1. Android Multimedia框架总结(一)MediaPlayer介绍之状态图及生命周期
  2. python变量、运算符、要求从键盘输入用户名和密码,校验格式是否符合规则,如果不符合,打印出不符合的原因,并提示重新输入练习
  3. 长春理工大学计算机科学与技术学分,计算机科学与技术专业本科人才培养方案-长春理工大学教务处.PDF...
  4. 红旗Linux职称考试模块,计算机职称考试红旗Linux Desktop 6.0考试大纲
  5. java脚本计算器按钮无反应_2020年3月份最新计算机语言排行,20种语言争锋相对Java依旧飘逸...
  6. 自定义日历控android,android 一个简单的自定义日历控件,让你掌控时间
  7. 2层框架结构柱子间距_钢筋混凝土楼板层其施工方法有哪些不同
  8. python两数之和是多少_Python面试:两数之和
  9. ip代理服务器8需要云速捷_nginx获取真实ip,proxy_set_head怎么设置头部信息
  10. android activity根节点addview_Android嵌入到页面中的加载动画工具类