Observer模式介绍

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

例如:
1.有一个基于某种数据模型的电子表格。只要数据模型发生变化,电子表格就需要更新表格单元以及内嵌的图表。这个例子中,目标是数据模型,观察者是表格单元和图表。当观
察者接收到数据模型已经变化的通知时,它们就更新自己。
2.有一个小孩子在睡觉,当这个小孩子醒来的时候,他的父亲,母亲,爷爷,奶奶都要做出一系列的反应。在这个例子中,目标是这个小孩子,观察者是这些父亲,母亲,爷爷,奶奶作出的反应。当小孩子醒过来时,他们各自做出自己的反应。
3.Java的awt中,也使用了Observer模式。例如一个点击一下Button时,可以做出一些反应,可以使弹出一个对话框,关闭界面,打印出信息...
这个例子中,目标就是这个Button,观察者就是作出反应的这些事件。


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

下面列出了两个小例子:
   例一: 模拟awt中点击Button,监视它的事件作出反应。

package edu.smc.dp.observer.awt;

import java.util.ArrayList;
import java.util.List;

public class TestPressButton {
	public static void main(String[] args) {
		Button button=new Button();     //new 一个Button
		
		button.addActionListener(new MyButtonListener1());  //为Button添加监听时间
		button.addActionListener(new MyButtonListener2());
		
		button.pressButton();                               //调用点击Button的方法
	}
}
class Button{
	List<ActionListener> actionListeners=new ArrayList<ActionListener>(); 
	public void pressButton(){
	    ActionEvent e=new ActionEvent(System.currentTimeMillis(),this);
		for(ActionListener actionListener:actionListeners){
			actionListener.actionPerform(e);
		}
	}
	public void addActionListener(ActionListener e){
		actionListeners.add(e);
	}
}
interface ActionListener{
	public void actionPerform(ActionEvent e);
}
class ActionEvent{
	private long when;
	private Object source;
	public ActionEvent(long when,Object source){
		this.when=when;
		this.source=source;
	}
	public long getWhen() {
		return when;
	}
	public Object getSource() {
		return source;
	}
}
class MyButtonListener1 implements ActionListener{

	@Override
	public void actionPerform(ActionEvent e) {
		System.out.println("press button 1");
		
		
	}
	
}
class MyButtonListener2 implements ActionListener{

	@Override
	public void actionPerform(ActionEvent e) {
		System.out.println("press button 2");
		
		
	}
}


例二: 当一个小孩子醒过来的时候,他的爷爷,父亲作出反应。
  本例用了属性文件,将要作出反应的事件写在属性文件里,然后去读取,在执行。

1.建立属性文件 observers.properties,写入如下内容:
      observers=edu.smc.dp.observer.Dad,edu.smc.dp.observer.GrandFather

2.源代码

package edu.smc.dp.observer;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import edu.smc.dp.observer.Test.WakenListener;
class WakeUpEvent{
	private long time;
	private String loc;
	private Object Child;
	public WakeUpEvent(long time, String loc, Object child) {
		this.time = time;
		this.loc = loc;
		Child = child;
	}
	public long getTime() {
		return time;
	}
	public void setTime(long time) {
		this.time = time;
	}
	public String getLoc() {
		return loc;
	}
	public void setLoc(String loc) {
		this.loc = loc;
	}
	public Object getChild() {
		return Child;
	}
	public void setChild(Object child) {
		Child = child;
	}
}
class Child implements Runnable{
	private List<WakenListener> wakenListeners=new ArrayList<WakenListener>();
	public Child(){
		
	}
	void addWakenUpListener(WakenListener wakenListener){
		wakenListeners.add(wakenListener);
	}
	
    void wakeUp(){
    	
    	for(int i=0;i<wakenListeners.size();i++){
    		
    		WakenListener wakenListener=wakenListeners.get(i);
    		wakenListener.actionToWakeUp(new WakeUpEvent(System.currentTimeMillis(), "bed", this));
    	}
    }
	@Override
	public void run() {
	   try {
		Thread.sleep(5000);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
	this.wakeUp();
  }
}
class Dad implements WakenListener{

	@Override
	public void actionToWakeUp(WakeUpEvent wakeUpEvent) {
		System.out.println("fead children!");
	}
}
class Dog implements WakenListener{
    @Override
	public void actionToWakeUp(WakeUpEvent arg0) {
		System.out.println("wang wang..");
		}
}
class GrandFather implements WakenListener{
    @Override
	public void actionToWakeUp(WakeUpEvent wakeUpEvent) {
		// TODO Auto-generated method stub
		System.out.println("go to play!");
	}
}
public class Test {
       interface WakenListener{
		void actionToWakeUp(WakeUpEvent wakeUpEvent);
	}

	public static void main(String[] args) {
	     Child child=new Child();
    	try {
		    String observerStr=PropertyMgr.getProperty("observers");
			String[] observers=observerStr.split(",");
			for(String observer:observers){
				WakenListener wl=(WakenListener) Class.forName(observer).newInstance();
				child.addWakenUpListener(wl);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		  new Thread(child).start();
	}
}
class PropertyMgr{
	private static Properties pros=new Properties();
	static{
		try {
			pros.load(Test.class.getClassLoader().getResourceAsStream("edu/smc/dp/observer/observers.properties"));
			String observerStr=pros.getProperty("observers");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static String getProperty(String key){
		return pros.getProperty(key);
	}
}



 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值