观察者模式

情景描述:

有一家报社名为NewspaperOffice,有一位热爱阅读报纸的市民,名字叫Jone,他出于阅读的爱好,向NewspaperOffice订阅了报纸。他希望,当报社发布新闻的时候,他能获得新闻消息。简单的类图如下


          


这里,有两种具体的实现思路:


1、Jone每天茶饭不思,每隔几分钟就主动询问报社NewspaperOffice:“你们有发布新的新闻了没哪?”。如果得到的回复是“还没有呢,别急”,那么等会儿,他还是会揪心如焚的再次询问。如果得到的回复是“好啦”,那么,他就自己获取新闻消息阅读。如此循环,周而复始。这就很类似于,我们在Jane里面启动一个线程,时刻不间断的询问NewspaperOffice的实例,“有新消息了没?”,等到有新消息发布的时候,Jane就自己读取消息。很显然,如果这样的话,Jane因为好读书,而蹉跎了太多时光,相当不合理。


2、报社承诺,只要他们有新消息,那么就会通知他,并把消息发送到他手上。所以Jone,每天都在做自己喜欢做的事情,忙着工作,照顾孩子,写文章,完全不用担心,自己是否会错过最近的新闻。我们现在要讨论的就是这个模型,类图如下:



Jane在NewspaperOffice注册,留下联系方式,方便NewspaperOffice发布新闻

的时候,可以以最快的速度告知发送给他。NewspaperOffice发布消息的时候,

会调用release()方法,release()方法里面会调用notifyObservers()方法,

notifyObservers()方法,则会调用Jane的update()方法,传递新闻消息给

Jane



java 代码如下:

package observer.com.cn;

/**
 * @author limx
 * 2011-9-2
 */
public class NewspaperOffice {

	private String message;
	
	Jane jane;
	
	public void release(String message) {
		notifyObserver(message);
	}
	
	public void notifyObserver(String message) {
		jane.update(message);
	}

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * @param message the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * @return the jane
	 */
	public Jane getJane() {
		return jane;
	}

	/**
	 * @param jane the jane to set
	 */
	public void setJane(Jane jane) {
		this.jane = jane;
	}
}

package observer.com.cn;

/**
 * @author limx
 * 2011-9-3
 */
public class Jane {

	public void update(String message) {
		System.out.println(message);
	}
}

package observer.com.cn;
import org.junit.Test;

/**
 * @author limx
 * 2011-9-3
 */
public class ObserverTest {
	
	@Test
	public void testChange() {
		Jane jane = new Jane();
		NewspaperOffice newspaper = new NewspaperOffice();
		newspaper.setJane(jane);
		newspaper.release("hello world");
	}
}

当报社发布“hello world”的消息的时候,会自动发送给Jane,Jane将其打印出来。好了,在此,我们先告一段落。


change:


在接下来的日子,由于报社秉承用良心说话,尽可能不带任何个人的偏见,给予最真实客观的报道的优秀新闻理念。渐渐赢得了人民百姓的认可,随之而来的是订阅该报社的市民越来越多,在这里我们只是假设多了Steven,类图如下:


多了一个steven之后,我们可以观察到的变化有:Newspaperoffice类里面多了一个steven的成员,

并且由于steven标新立异,不是那么的盲目随从,只提供了一个和jane完全不相同的update2()

接口,所以在notifyObservers()里面,我们除了需要调用jane的update()方法,还要调用

steven的update2()方法,这样才能把新闻消息正确无误地发送给所有的订阅者。


此时的java代码如下:


package observer.com.cn;

/**
 * @author limx
 * 2011-9-2
 */
public class NewspaperOffice {

	private String message;
	
	private Jane jane;
	
	private Steven steven;
	
	public void release(String message) {
		notifyObserver(message);
	}
	
	public void notifyObserver(String message) {
		jane.update(message);
		steven.update2(message);
	}
       //getter and settter
}

package observer.com.cn;

/**
 * @author limx
 * 2011-9-3
 */
public class Jane {

	public void update(String message) {
		System.out.println("jane : " + message);
	}
}

package observer.com.cn;

/**
 * @author limx
 * 2011-9-3
 */
public class Steven {

	public void update2(String message) {
		System.out.println("steven : " + message);
	}
}

package observer.com.cn;
import org.junit.Test;

/**
 * @author limx
 * 2011-9-3
 */
public class ObserverTest {
	
	@Test
	public void testChange() {
		Jane jane = new Jane();
		Steven steven = new Steven();
		NewspaperOffice newspaper = new NewspaperOffice();
		newspaper.setJane(jane);
		newspaper.setSteven(steven);
		newspaper.release("hello world");
	}
}

测试结果为:

jane : hello world
steven : hello world


这里暴露出来的问题主要是,一旦有新的订阅者,我们就得修改Newspaperoffice类,将其加入成为Newspaperoffice的成员,并且在notifyObservers方法调用订阅者相对应提供的接口,不一定是update()。


未完待续!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值