http://www.ibm.com/developerworks/cn/java/l-jdkdp/part1/
软件模式的概念现在比较的广泛,涉及到分析,设计,体系结构,编码,测试,重构等软件构造生命期中的各个部分。这儿主要讨论的是设计模式,指的是在软件设计过程中反复出现的一些问题的解决方法了。不过我们一般在提到设计模式的时候,一般都是指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.setVisible(true);
frame2.setVisible(true);
……………..
}
}
|
我认为在JDK中这个Observer模式的实现,对于一般的Observer模式的应用,已经是非常的足够了的。但是一方面它用一个类来实现了
Subject,另一方面它使用Vector来保存Subject对于Observer的引用,这虽然简化了编程的过程,但会限制它在一些需要更为灵活,
复杂的设计中的应用,有时候(虽然这种情况不多),我们还不得不重新编写新的Subject对象和额外的Manager对象来实现更为复杂的
Observer模式的应用。
回页首
小结:
这一部分主要的讨论了模式的概念。随着现代软件工业的不断进步,软件系统的规模的日益扩大,越来越需要对某些个不断出现的问题进行模式化思维,以成功的经
验或者失败的教训来减少软件开发失败的风险。模式代表了一种文档化的经验,它为某一类的问题提供了最好(或者说很好)的解决方案,使得即使不是经验丰富的
软件工程师,也能够根据模式来构建相对成功的系统。本节给出的一个Obverser模式的示例,比较好的说明了这一点。Obverser模式主要解决在对
象间的状态映射或者镜像的问题。
分享到:
相关推荐
这是最简单的一个MVC实例,通过它你可以了解MVC的基本工作原理。
我们说学习Java应该从Swing开始,那么学习Swing最重要的思想就是对于观察者模式的理解(Observer Pattern)。因为,该设计模式在Java Swing框架中贯穿了始终。对于C#的委托、代理概念所使用的Callback(回调模式--...
从生活中的例子可以看出,只要对订阅号... 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己的行为。
Observer(观察者模式)学习源码,该源码讲述并Observer(观察者模式)一些具体实现过程
结合微信公众号讲解观察者模式,生动形象,关键是上手快啊
可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。 2.Observer(观察者) 为那些在目标发生改变时需获得通知的对象定义一个更新接口。 3.ConcreteSubject(具体目标) 将有关状态存入...
Java 观察者模式的浅析 简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象。这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者...
android Observer(观察者模式)_案例祥解.pdf
观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化,这个例子是java内置观察者模式
C#面向对象设计模式 (行为型模式) Observer 观察者模式 视频讲座下载
C#面向对象设计模式纵横谈(19):(行为型模式) Observer 观察者模式 (Level 300)
observer观察者模式
Java内置的Observable类和Observer接口提供了基本的观察者模式功能,你可以通过继承Observable类和实现Observer接口来使用
撤销功能的实现——备忘录模式(三) 撤销功能的实现——备忘录模式(四) 撤销功能的实现——备忘录模式(五) 观察者模式-Observer Pattern 对象间的联动——观察者模式(一) 对象间的联动——观察者模式(二) ...
设计模式C++学习之观察者模式(Observer)
一个很简单但是明了的java观察者模式的demo。备注几乎每行都加了。
主要介绍了Java编程的Observer观察者设计模式,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象,需要的朋友可以参考下
观察者模式通常的叫法叫做订阅-发布模式,类似于报刊杂志的订阅,观察者和被观察者就是读者和邮局的关系,读者先要在邮局订阅想要的报刊,当报刊发行时,邮局会将报刊邮寄到读者家里。观察者(Observer)和被观察者...
观察者 Observer 模式定义:在对象之间定义了一对多的依赖关系 这样一来 当一个对象改变状态时 依赖它的对象都会收到通知并自动跟新 Java已经提供了对观察者Observer模式的默认实现 Java对观察者模式的支持主要体现...