论坛登陆 用户名:  密 码:
设为首页  加入收藏
08年北京名校秋季招生
名牌院校免试入学宽进严出,突破考分限制,名校与你零距离,以下院校按报名先后顺序录取,24小时网上报名覆盖全国
  您现在的位置: 中国教育招生在线 >> IT >> JAVA认证 >> IT正文
使用Observer模式
 作者:佚名     2007-3-14 16:51:20        来源:不详  浏览次数:

 

 

 

 

 

 

 

 

使用Observer模式

A:我想在自己的Java程序中使用Observer模式。基于此,能否提供某些示例代码来演示如何去做?


Q:正如面向对象编程有助于代码复用一样,设计模式可以促进设计复用。确实,设计模式可以让你复用那些正确的、成熟的设计。但近来,批评设计模式的声音越来越多。批评者指出,缺乏经验的开发者会很容易地掉进 "模式陷阱" 之中。


模式陷阱让缺乏经验的开发者迷失了方向。因而,他们在处理问题时不是去寻找可能存在的最好方案,而把最终目标集中在尽可能地实现更多的设计模式之上。在一些人看来,使用设计模式好象必然会带来良好的设计。按照这个逻辑,只要大量使用设计模式,就必然为你产生一个优秀的设计!然而现实中,这一观点却导致出许多毫无意义的设计--即使这个设计采用了多个设计模式。看来很遗憾,设计模式并不能保证良好的设计。


要想在设计中正确地运用一个设计模式,必须确保三个条件:


1. 弄清你的问题


2. 了解这个模式


3. 理解这个模式如何解决你的问题


首先,最重要的是条件1。如果不能完全地弄清你要解决的问题,何谈运用模式?


还要知道条件2:必须完全了解你想运用的模式。不了解它怎么能运用它?更重要的是,连一个模式做什么都不知道,又如何想到去用它?


最后一点,如果你不能清楚地说出模式将怎样解决你的问题(为什么这个模式合适),那还是放弃它。仅仅为了用模式本身而去用它,就会掉进模式陷阱之中。


我并不是在说提这个问题的读者也一定会掉进模式陷阱。但从提问的表达上来看,它很容易误导一些开发者去理解设计模式。我对这个提问的理解是,这位读者应该清楚自己需要解决的问题,也了解Observer模式,他/她只是不知道如何用Java来实现。


在给出一个Java示例之前,为了有助于其他读者也能理解,先简要介绍一下Observer模式。


简单来说,Observer模式让一个对象(观察者,Observer)去监视另一个对象(目标,Subject);它使得目标和观察者之间建立一种 "发布--订阅"(publish-subscribe )的关系。通过Observer模式,观察者可以向目标登记,表明自己要从目标接收事件。目标需要向观察者通知事件时,只是简单地将事件发给每一个观察者。


例如,有一个基于某种数据模型的电子表格。只要数据模型发生变化,电子表格就需要更新表格单元以及内嵌的图表。这个例子中,目标是数据模型,观察者是表格单元和图表。当观察者接收到数据模型已经变化的通知时,它们就更新自己。


Observer模式的好处是:它解除了观察者和目标之间的耦合关系。目标不需要知道它的观察者的任何信息。相反,目标只是允许观察者订阅事件。当目标产生一个事件时,它简单地将事件传给每一个观察者。


看看下面的Java示例:


public interface Subject {

public void addObserver( Observer o );

public void removeObserver( Observer o );

}


上面的代码中,Subject接口定义了两个方法(method),每个Subject都必须实现它们,以使Observer可以在Subject中增加或删除自身。


public interface Observer {

public void update( Subject o );

}


Observer接口(如上)列出了一个方法(method),每个Observer都必须实现它,以使Subject可以发送更新消息给Observer。


下面看看Subject的一个简单的实现--IntegerDataBag:


import java.util.ArrayList;

import java.util.Iterator;


public class IntegerDataBag implements Subject {


private ArrayList list = new ArrayList();

private ArrayList observers = new ArrayList();


public void add( Integer i ) {

list.add( i );

notifyObservers();

}


public Iterator iterator() {

return list.iterator();

}


public Integer remove( int index ) {

if( index < list.size() ) {

Integer i = (Integer) list.remove( index );

notifyObservers();

return i;

}

return null;

}


public void addObserver( Observer o ) {

observers.add( o );

}


public void removeObserver( Observer o ) {

observers.remove( o );

}


private void notifyObservers() {

// loop through and notify each observer

Iterator i = observers.iterator();

while( i.hasNext() ) {

Observer o = ( Observer ) i.next();

o.update( this );

}

}

}


IntegerDataBag适用于使用Integer的场合。IntegerDataBag也允许Observer增加和删除它们自身。


再看看两个Observer的实现--IntegerAdder和IntegERPrinter:


import java.util.Iterator;


public class IntegerAdder implements Observer {


private IntegerDataBag bag;


public IntegerAdder( IntegerDataBag bag ) {

this.bag = bag;

bag.addObserver( this );

}


public void update( Subject o ) {

if( o == bag ) {

System.out.println( "The contents of the IntegerDataBag have changed." );

int counter = 0;

Iterator i = bag.iterator();

while( i.hasNext() ) {

Integer integer = ( Integer ) i.next();

counter+=integer.intValue();

}

System.out.println( "The new sum of the integers is: " + counter );

}

}


}


import java.util.Iterator;


public class IntegerPrinter implements Observer {


private IntegerDataBag bag;


public IntegerPrinter( IntegerDataBag bag ) {

this.bag = bag;

bag.addObserver( this );

}


public void update( Subject o ) {

if( o == bag ) {

System.out.println( "The contents of the IntegerDataBag have changed." );

System.out.println( "The new contents of the IntegerDataBag contains:" );

Iterator i = bag.iterator();

while( i.hasNext() ) {

System.out.println( i.next() );

}

}

}


}


IntegerAdder和IntegerPrinter将自己作为观察者增加到IntegerDataBag。当IntegerAdder接收到一条更新消息时,它先统计bag中的总数,然后显示结果。同样,当IntegerPrinter接收到一条更新消息时,它打印出bag中的Interger。


下面是一个简单的main(),它使用了上面的几个类:


public class Driver {

public static void main( String [] args ) {

Integer i1 = new Integer( 1 ); Integer i2 = new Integer( 2 );

Integer i3 = new Integer( 3 ); Integer i4 = new Integer( 4 );

Integer i5 = new Integer( 5 ); Integer i6 = new Integer( 6 );

Integer i7 = new Integer( 7 ); Integer i8 = new Integer( 8 );

Integer i9 = new Integer( 9 );


IntegerDataBag bag = new IntegerDataBag();

bag.add( i1 ); bag.add( i2 ); bag.add( i3 ); bag.add( i4 );

bag.add( i5 ); bag.add( i6 ); bag.add( i7 ); bag.add( i8 );


IntegerAdder adder = new IntegerAdder( bag );

IntegerPrinter printer = new IntegerPrinter( bag );


// adder and printer add themselves to the bag


System.out.println( "About to add another integer to the bag:" );

bag.add( i9 );

System.out.println("");

System.out.println("About to remove an integer from the bag:");

bag.remove( 0 );

}

}


运行main,你将看到:


c:\javaworld\java Driver

About to add another integer to the bag:

The contents of the IntegerDataBag have changed.

The new sum of the intergers is: 45

The contents of the IntegerDataBag have changed.

The new contents of the IntegerDataBag contains:

1

2

3

4

5

6

7

8

9


About to remove an integer from the bag:

The contents of the IntegerDataBag have changed.

The new sum of the intergers is: 44

The contents of the IntegerDataBag have changed.

The new contents of the IntegerDataBag contains:

2

3

4

5

6

7

8

9


IntegerDataBag/IntegerAdder/IntegerPrinter是应用Observer模式的一个很简单的例子。Java本身有大量使用Observer模式的例子:AWT/Swing事件模型,还有java.util.Observer和java.util.Observable接口等,都是很好的例子。


责任编辑:lss
  相关新闻
WebWork拦截器(Interceptor)使用方法
使用AppFuse框架进行开发的总结
快速上手Spring--4.安装和使用IDE
Oracle诊断工具-RDA使用概述
允许内部用户使用Outlook Web Access
在Struts框架下使用时间类型
JAVA测试:使用JMock来实现孤立测试
使用ExMerge升级到Exchange 2000
【J2EE综合】——使用JMS队列
JAVA基础:在javascript中应用Object
用Oracle的异构服务连接异种数据源
教你用Oracle解析函数快速检查序列间隙
Oracle诊断工具-RDA使用概述
在Struts框架下使用时间类型
快速上手Spring--4.安装和使用IDE
使用Spring更好地处理Struts动作
使用Buffalo集成Spring写的一个登录实例
使用AppFuse框架进行开发的总结
使用xmlhttp为网站增加域名查询功能
使用 Velocity 模板引擎开发网站
  评论
现在有100人对本文发表评论
查看所有评论
 
推  荐
 
100本成功必读热销书
热门招生
  北京文理研修学院   前进大学
  北京明园大学   北京建设大学
  北京邮电大学世纪学院   北方工商管理学院
  联想软件定向委培班   香港数码动画学院
  青年企业管理研修学院   北京华夏管理学院
热门培训
网络化办公专家培训认证 电子科技大学软件学院
软件测试工程师培训认证 北大青鸟十大授权培训
IT硬件工程师培训认证班 北京环球雅思荷兰预科
JAVA开发工程师培训 潜能时代IT服务管理培训
网络信息化工程师培训 清华大学继续教育学院
论坛精选
 
有些细节是男人也该注意的风度!最容易读错的字
某强人手机里保存的30条短信 中国十大高薪职业
最感人的十大韩剧经典台词 嫁给工程师的N个理由
爆强!只有一句话的鬼故事 转贴教你如何做妖精
 女人一定要記住的話 女人最好别嫁给最爱的男人
城市联盟
 大连 上海 天津 广州 西安 深圳  天津  青岛  大连  福州  沈阳  青海  连云港  南京  吉林  厦门  威海  辽宁  呼和浩特
Copyright © 2006   www.edu999.com   All rights reserved. 中国教育招生在线  版权所有
北京市通信管理局[2004]字第552号函    京ICP证040442号