




全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
引用 从Java类库看设计模式(1)gengwei138 的 从Java类库看设计模式(1)在这一部分的内容中,介绍的是一个相对简单但功能强大的模式:Observer模式。希望通过这部分地叙述,大家看了之后,能够对设计模式有一个比较全面地,感性的认识。 很 多时候,对于一个设计来说(软件上的,建筑上的,或者它他工业上的),经验是至关重要的。好的经验给我们以指导,并节约我们的时间;坏的经验则给我们以借 鉴,可以减少失败的风险。然而,从知识层面上来讲,经验只是作为一种工作的积累而存在于个人的大脑中的,很难被传授或者记录。为了解决这样的问题,人们提 出了所谓的模式的概念。所谓模式,是指在一个特定背景下,反复出现的问题解决方案。模式是经验的文档化。 软件模式的概念现在比较的广 泛,涉及到分析,设计,体系结构,编码,测试,重构等软件构造生命期中的各个部分。这儿主要讨论的是设计模式,指的是在软件设计过程中反复出现的一些问题 的解决方法了。不过我们一般在提到设计模式的时候,一般都是指GOF的经典书Design Pattern-Elements of Reusable Object-Oriented Software出现的23个模式,因而,它是具体的针对于面向对象软件设计过程的。 从 全局上看来,模式代表了一种语言,一种被文档化的经验,甚至是一种文化。往往很多不方便描叙,或者描叙起来很复杂的问题,用模式语言来叙说,会让听者产生 心领神会的感觉。当然,这需要交流双方都能够很好地把握模式语言的含义。然而,这并不是一件容易的事情。模式在各个人的理解上往往存在差异,这篇文章旨在 从一个具体的应用角度:Java类库,来阐叙设计模式。并结合具体的例子,希望能够加深大家对设计模式的理解。 这儿说的Java类 库,其实并没有局限于JDK本身,还包括了一些其他的类库中的例子,比如JAXP等(当然,下一个版本的JDK中也会包含JAXP了)。其实设计模式的思 想现在应用的如此广泛,无论在什么样的设计中,只要稍微大一点的设计,都可以找到很多很多设计模式的踪迹,或者说都不可避免的用到设计模式。下面所讲的设 计模式,大部分都是GOF的那部经典中出现过的23个模式,然而,还有一些,比如MVC,并不属于那里。一般的来讲,我们认为GOF的23个模式是一些中 级的模式,在它下面还可以抽象出一些更为一般的低层的模式,在其上也可以通过组合来得到一些高级的模式。当然,这儿的低中高的区别,如同区别不同的语言一 样,并没有优劣之分,仅仅是在应用层面上的区别。 Observer模式 Observer模式的功用,是希望两个 (或多个)对象,我们称之为Subject和Observer,当一方的状态发生改变的时候,另一方能够得到通知。也就是说,作为Observer的一 方,能够监视到Subject的某个特定的状态变化,并为之做出反应。一个简单的例子就是:当一个用户视图中的数据被用户改变后,后端的数据库能够得到更 新,而当数据库被其他方式更新后,用户视图中的数据显示也会随之改变。 图一:Obverser模式的类图 在 JDK中实际上有一个对Observer模式的简单的实现:就是类java.util.Observerable和接口 java.util.Observer。java.util.Observerable类对应于Subject,而java.util.Observer 就是观察者了。JDK中并没有把这两个部分都设计为接口,而是让类java.util.Observerable提供了部分的实现,简化了许多编程的工 作。当然,这也减少了一定的灵活性。 下面列出了Observer和Observeral的函数列表,及其简单的功能说明 java.util.Observer: public void update(Observable obs, Object obj) java.util.Observer 接口很简单,只定义了这一个方法,狭义的按照Observer模式的说法,Observer应该在这个方法中调用Subject的getXXX()方法来 取得最新的状态,而实际上,你可以只是在其中对Subject的某些事件进行响应。这便是Java中的代理事件模型的一个雏形-对事件进行响应。只不 过,在Observer模式中将事件特定化为某个状态/数据的改变了。 java.util.Observable public void addObserver(Observer obs) 向 Subject注册一个Observer。也就是把这个Observer对象添加到了一个java.util.Observable内部的列表中。在 JDK中对于这个列表是简单的通过一个java.util.Vector类来实现的,而实际上,在一些复杂的Observer模式的应用中,需要把这个部 分单另出来形成一个Manager类,来管理Subject和Observer之间的映射。这样,Subject和Observer进一步的被解藕,程序 也会具有更大的灵活性。 public void deleteObserver(Observer obs) 从Subject中删除一个已注册了Observer的引用。 public void deleteObservers() 从Subjec中删除所有注册的Observer的引用。 public int countObservers() 返回注册在Subject中的Observer个数。 protected void setChanged() 设置一个内部的标志以指明这个Ovserver的状态已经发生改变。注意这是一个protected方法,也就是说只能在Observer类和其子类中被调用,而在其它的类中是看不到这个方法的。 protected void clearChanged() 清除上叙的内部标志。它在notifyObservers()方法内部被自动的调用,以指明Subject的状态的改变已经传递到Ovserver中了。 public boolean hasChanged() 确定Subject的状态是否发生了改变。 public void notifyObservers(Object obj) 它 首先检查那个内部的标志,以判断状态是否改变,如果是的话,它会调用注册在Subject中的每个Observer的update()方法。在JDK中这 个方法内部是作为synchronized来实现的,也就是如果发生多个线程同时争用一个java.util.Observerable的 notifyObservers()方法的话,他们必须按调度的等待着顺序执行。在某些特殊的情况下,这会有一些潜在的问题:可能在等待的过程中,一个刚 刚被加入的Observer会被遗漏没有被通知到,而一个刚刚被删除了的Observer会仍然收到它已经不想要了的通知。 public void notifyObservers() 等价于调用了notifyObservers(null)。 因 而在Java中应用Observer就很简单了,需要做的是:让需要被观察的Subject对象继承java.util.Observerable,让需 要观察的对象实现java.util.Observer接口,然后用java.util.Observerable的 addObserver(Observer obj)方法把Observer注册到Subject对象中。这已经完成了大部分的工作了。然后调用java.util.Observerable的 notifyObservers(Object arg)等方法,就可以实现Observer模式的机理。我们来看一个简单使用了这个模式的例子。这个例子有三个 类:FrameSubject,DateSubject,FrameObject和EntryClass,FrameSubject中用户可以设置被观察 的值,然后自动的会在FrameObject中显示出来,DateSubject封装被观察的值,并且充当Observer模式中的Subject。 public class FrameSubject extends JFrame . /因为无法使用多重继承,这儿就只能使用对象组合的方式来引入一个 /java.util.Observerable对象了。 DateSubject subject=new DateSubject(); /这个方法转发添加Observer消息到DateSubject。 public void registerObserver(java.util.Observer o) subject.addObserver(o); /数据改变,事件被触发后调用notifyObservers()来通知Observer。 void jButton1_actionPerformed(ActionEvent e) subject.setWidthInfo(Integer.parseInt(jTextField1.getText(); subject.setHeightInfo(Integer.parseInt(jTextField2.getText(); subject.notifyObservers(); public class DateSubject extends Observable /封装被观察的数据 private int widthInfo; private int heightInfo; public int getWidthInfo() return widthInfo; public void setWidthInfo(int widthInfo) this.widthInfo = widthInfo; /数据改变后,setChanged()必须被调用,否则notifyObservers()方法会不起作用 this.setChanged(); public void setHeightInfo(int heightInfo) this.heightInfo = heightInfo; this.setChanged(); public int getHeightInfo() return heightInfo; public class FrameObserver extends JFrame implements java.util.Observer . /观察的数据 int widthInfo=0; int heightInfo=0; /在update()方法中实现对数据的更新和其它必要的反应。 public void update(Observable o, Object arg) DateSubject subject=(DateSubject) o; widthInfo=subject.getWidthInfo(); heightInfo=subject.getHeightInfo(); jLabel1.setText(The heightInfo from subject is: ); jLabel3.setText(String.valueOf(heightInfo); jLabel2.setText(The widthInfo from subject is: ); jLabel4.setText(String.valueOf(widthInfo); . public class EntryClass public static void main(String args) . FrameSubject frame = new FrameSubject(); FrameObserver frame2=new FrameObserver(); /在Subject中注册Observer,将两者联系在一起 frame.registerObserver(frame2); . frame.setVis
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 移动端健康医疗应用开发
- 职教数学复习 第7章简单几何体与立体几何 第34讲简单几何体的三视图 课件
- 甲状腺次全切除术课件
- 天津市河东区2024-2025学年高二下学期7月期末物理试题(含答案)
- 用电安全知识培训课件开场白
- 新解读《GB-T 36041-2018压水堆核电厂安全重要变量监测准则》
- 生药学课件-大黄
- 2024垃圾清理协议合同
- 2024建设用地使用权出租合同(8篇)
- 2025年考研英语(一)阅读理解模拟试卷 真题解析与训练
- 高端数控机床智能化控制系统研发项目可行性研究报告
- 2025年河南郑州航空港发展投资集团有限公司招聘笔试参考题库含答案解析
- 钢结构车棚建设服务方案投标文件(技术方案)
- 中国极地海洋装备的发展探索与技术需求
- GB 9706.283-2022医用电气设备第2-83部分:家用光治疗设备的基本安全和基本性能专用要求
- 2025市政排水管道非开挖修复工程计价定额
- UML2面向对象分析与设计(第2版)谭火彬全套教案课件
- 《血液肿瘤免疫及靶向药物治疗相关性感染预防及诊治中国专家共识(2025年版)》解读
- 药品不良反应培训课件
- 苏豪控股集团招聘笔试题库2025
- 2025年干部休养所服务项目合作计划书
评论
0/150
提交评论