已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
专栏作品设计模式:利用C#的Delegate来改进Observer模式卢彦Observer模式简介为了让更多的人能够看明白本文,所以在此之前,我们先来了解一下Observer模式的基本概念。模式名称:Observer 结构图: 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。适用性:当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。 应用实例在 编写多层应用程序时,我们通常将表示层和数据逻辑层分隔开,比如很常见的View/Document结构,这种设计方式的好处带来的结果通常是使用多视图 同时表示单一数据源,比如一个Web网站可以方便的同时拥有针对电脑的Html页面和针对手机的WAP页面。使用这种结构时,为了保持数据显示的一致性, 必须要求数据源在数据发生改变时能及时的逐一通知每一个和它绑定的表示层进行更新。但是问题在于数据层本身并不知道到底有多少个不同的表示层正在反映着它 的数据内容。因此需要设计一套有效的机制来完成这个目标。模式实现我们先看看来自设计模式迷你手册的常规的C#实现代码。Subject(抽象目标):目标知道它的观察者。可以有任意多个观察者观察同一个目标。/实现代码class Subject/由于不知道有多少个观察者,所以建立了一个观察者链表 private ArrayList list = new ArrayList();private string strImportantSubjectData = Initial;public string ImportantSubjectData get return strImportantSubjectData;set strImportantSubjectData = value;public void Attach(Observer o)list.Add(o);o.ObservedSubject = this;public void Detach(Observer o)public void Notify()/在数据发生改变后遍历列表通知观察者foreach (Observer o in list) o.Update();Observer(抽象观察者):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。abstract class Observer /内置一个需要观察的对象 protected Subject s;public Subject ObservedSubject get return s; set s = value; abstract public void Update();ConcreteSubject(实体目标,在这里相当于数据逻辑层):将有关状态存入各ConcreteSubject对象。当它的状态发生改变时,向它的各个观察者发出通知。/在这里基本上什么都没有做,数据的获取可以放到GetState()里面class ConcreteSubject : Subjectpublic void GetState()public void SetState() ConcreteObserver(实体观察者,在这里就相当于表示层):维护一个指向ConcreteSubject的引用。储存有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标状态保持一致。class ConcreteObserver : Observer private string observerName;public ConcreteObserver(string name)observerName = name;override public void Update()/将数据显示出来 Console.WriteLine(In Observer 0: data from subject = 1, observerName, s.ImportantSubjectData); 主函数:public class Client public static int Main(string args) ConcreteSubject s = new ConcreteSubject();ConcreteObserver o1 = new ConcreteObserver(first observer);ConcreteObserver o2 = new ConcreteObserver(second observer);/注册观察者s.Attach(o1);s.Attach(o2);s. ImportantSubjectData = This is important subject data;s.Notify(); return 0;模式分析Observer模式的优点是实现了表 示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制,类别清晰,并抽象了更新接口,使得可以有各种各样不同的表示层(观察者)。但是其缺点是每个外 观对象必须继承这个抽像出来的接口类,这样就造成了一些不方便,比如有一个别人写的外观对象,并没有继承该抽象类,或者接口不对,我们又希望不修改该类直 接使用它。虽然可以再应用Adapter模式来一定程度上解决这个问题,但是会造成更加复杂烦琐的设计,增加出错几率。C#作为一种先进的现代面向对象语言,不但吸收了许多语言的精华,并创造了一些非常有用的新特性。在学习了C#语言之后,我发现利用C#独有的Delegate可以来较好的解决这个问题。改进后的Observer模式实现先定义一个Delegate:delegate void UpdateDelegate(string SubjectData); Subject(抽象目标):class Subjectprivate string strImportantSubjectData = Initial;/定义一个事件容器,代替前面的观察者对象列表public event UpdateDelegate UpdateHandle;public string ImportantSubjectData get return strImportantSubjectData;set strImportantSubjectData = value;public void Notify()/发出事件 if(UpdateHandle != null) UpdateHandle(strImportantSubjectData);Observer(抽象观察者):无,因为不需要抽象接口类了,所以可以省去抽象观察者类。ConcreteSubject(实体目标):/没有任何改变 class ConcreteSubject : Subjectpublic void GetState()public void SetState() ConcreteObserver(实体观察者):/为了能更加清楚的说明问题,这里定义了两个实体观察者,注意,它们之间并没有任何关系class Observer1private string observerName;public Observer1(string name)observerName = name;public void Update1(string ImportantSubjectData)Console.WriteLine(In Observer 0: data from subject = 1, observerName, ImportantSubjectData); class Observer2private string observerName;public Observer2(string name)observerName = name;public void Update2(string ImportantSubjectData)Console.WriteLine(In Observer 0: data from subject = 1, observerName, ImportantSubjectData); 主函数:public class Client public static int Main(string args) ConcreteSubject s = new ConcreteSubject();Observer1 o1 = new Observer1(first observer);Observer2 o2 = new Observer2(second observer);/向目标注册对象两个观察者,请注意,这里仅仅只是添加了两个方法,/不需要关心方法从何而来,也不需要关心目标类如何去调用他们。s.UpdateHandle += new UpdateDelegate(o1.Update1);s.UpdateHandle += new UpdateDelegate(o2.Update2);s.ImportantSubjectData = This is important subject data;s.Notify();return 0;在这段代码里,没有看到链表,没有看到遍历操作,没有看到更新的方法是如何被调用,甚至没有 看到那些被联系到一起的类的抽象类和抽象接口,但是目标对象却能将数据更新信息逐一发送到每个观察者对象,并且还能更加容易的增加新的不同的观察者对象, 根本不需要知道它从何处继承而来,也不需要统一他们的接口调用方法。这一切都归功于灵活强大的C#。完整的源码以下是完整的源码:namespace Observer_DesignPatternusing System;delegate void UpdateDelegate(string SubjectData);class Subjectprivate string strImportantSubjectData = Initial;public event UpdateDelegate UpdateHandle;public string ImportantSubjectData get return strImportantSubjectData;set strImportantSubjectData = value;public void Notify()if(UpdateHandle != null) UpdateHandle(strImportantSubjectData);class ConcreteSubject : Subjectpublic void GetState()public void SetState() class Observer1private string observerName;public Observer1(string name)observerName = name;public void Update1(string ImportantSubjectData)Console.WriteLine(In Observer 0: data from subject = 1, observerName, ImportantSubjectData); class Observer2private string observerName;public Observer2(string name)observerName = name;public void Update2(string ImportantSubjectData)Console.WriteLine(In Observer 0: data from subject = 1, observerName, ImportantSubjectData); public class Client public static int Main(string args) ConcreteSubject s = new ConcreteSub
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 妇女联合会教育岗巾帼志愿者培训管理工作手册
- 学生心理健康教育与辅导手册
- 绿色无公害畜禽产品认证申报手册
- 健康管理师实务操作手册
- 《码头货物装卸应急演练组织实施手册》
- 图书馆图书分类与借阅手册
- 高层建筑消防管理规范手册
- 环保评估与环境影响评价手册
- 城市电力电缆敷设施工手册 (标准版)
- 期末模拟测试(试题)-五年级上册数学苏教版 (二)
- 成都市万年场街道办事处公开招聘2名编外人员考试参考题库及答案详解
- 2026内蒙古呼和浩特市教育系统所属事业单位第三批人才引进823人笔试模拟试题及答案详解
- (2026年)水利工程建设监理工作总结报告
- 2026年安庆经开区老峰镇村(社区)专职工作人员公开招聘9名笔试备考题库及答案详解
- 2026年中国第三方算力中心服务商发展研究报告
- 2026年本溪市平山区事业编单位人员招聘笔试参考试题及答案详解
- 《物流成本管理实务(第2版)》(王科)教案 第25课 构建物流成本绩效评价指标体系
- 2021化工设备安装工程施工质量验收标准
- 手术室护理实践指南侧卧位的摆放
- 新生儿院内感染
- GB/T 11363-2008钎焊接头强度试验方法
评论
0/150
提交评论