设计模式(3)观察者模式(Observer)

观察者模式(Observer)


1.网络上的一句话说明

想知道咱们公司最新MM情报吗?加入公司的MM情报邮件组就行了,tom负责搜集情报,他发现的新情报不用一个一个通知我们,直接发布给邮件组,我们作为订阅者(观察者)就可以及时收到情报啦

2.定义

在对象之间定义一对多的依赖,这样依赖,当一个对象改变状态,依赖它的对象都会收到通知并自动更新。

3.设计原则

① 为交互对象之间的松耦合设计

注意:不要依赖于观察者被通知的次序

4.举例说明

java中一个对象的改变要通知另一个对象对此改变做出相应的事件,最简单的方法就相互握有对方的引用。(一般情况下也不建议这么使用 这里只是举个列子) 


上图中Cat握有Dog的引用

cat执行了run方法 逃跑了 这个时候Dog要根据cat发生的改变而改变 这里理解为追上

最简单的就是在cat的run方法里面调用dog的rush()方法

如果这个时候 又有其他许多对象需要执行改变 而且对象类型也不相同 就比较麻烦了。

所以观察者模式就能派上用场 很好的解决这个问题。


java的jdk提供了Observable(类)和Observer(接口)可以实现其观察者模式

Observable是被观察者 这里有个弊端 要用jdk的类 被观察者就要继承Observable而且Observer里只有一个方法

void update(Observable o, Object arg);当我们要传递多个对象的时候可能会给开发带来一些不便  


下面我想讲讲我们自己来实现观察者模式

首先实现观察者接口 所有的观察者都必须实现这个接口

/**
 * 观察者
 * 
 * @author icetiger
 */
public interface ChangeListener 
{
	/** 对象改变方法 
	 *  source:被观察者
	 *  type:定义一些改变常量 以便更好的判断和区分(比如被观察者是A属性改变还是B属性改变)
	 *  value:被观察者改变后,观察者收到的一些具体信息
	 * */
	public void change(Object source,int type,Object value);
}
实现被观察者类

package observer;

import java.util.Vector;

/**
 * 被观察者
 * 
 * @author icetiger
 */
public class ChangeListenerList 
{
	/**观察者集合*/
	private Vector obs;
	
	public ChangeListenerList()
	{
		obs = new Vector();
	}
	
	/**添加一个观察者*/
	 public synchronized void addListener(ChangeListener o) 
	 {
	    if (o == null)
	            throw new NullPointerException();
		if (!obs.contains(o)) 
		{
		    obs.addElement(o);
		}
	 }

	 /**移除一个观察者*/
	 public synchronized void deleteListener(ChangeListener o) 
	 {
	        obs.removeElement(o);
	 }
	 
	 /**移除所有观察者*/
	 public synchronized void deleteListeners() 
	 {
			obs.removeAllElements();
         }
	 
	 /**通知观察者*/
	 public void change(Object source,int type,Object value)
	 {
		 Object[] arrLocal=obs.toArray();
		 for (int i = arrLocal.length-1; i>=0; i--)
	            ((ChangeListener)arrLocal[i]).change(source,type,value);
	 }
}

这里我们要实现ChangeListener接口的方法 以便更好的通知观察者 甚至我认为让它实现ChangeListener接口也是可行的


实现一个具体的被观察者

package observer;


/**
 * 具体被观察者
 * 
 * @author icetiger
 */
public class Player 
{
	/**消息传递常量*/
	public static final int CHANGE_WEAPON=1,CHANGE_CAP=2;
	/**观察者列表*/
	ChangeListenerList listenerList = new ChangeListenerList();
	
	
	/** 获得状态改变事件监听器列表 */
	public  ChangeListenerList getChangeListenerlist()
	{
		return listenerList;
	}

	/** 添加状态改变事件监听器 */
	public  void addChangelistener(ChangeListener listener)
	{
		listenerList.addListener(listener);
	}

	/** 移除状态改变事件监听器 */
	public  void removeChangelistener(ChangeListener listener)
	{
		if(listenerList==null) return;
		listenerList.deleteListener(listener);
	}

	/** 移除全部监听器 */
	public  void clearChangelisteners()
	{
		if(listenerList==null) return;
		listenerList.deleteListeners();
	}
	
	/**切换武器*/
	public void changeWeapon()
	{
		listenerList.change(this,CHANGE_WEAPON,new Object());
	}

}
当有观察者需要关心这个玩家的时候,就调用addChangeListener方法把自己传进去 加入到观察者列表 当然观察者要实现ChangeListener接口

玩家在切换武器的时候就会通知观察者 玩家武器改变了。

最后这里让被观察者(Player)握有ChangeListenerList类 主要是为了让它还可以继承其他类。

我们还可以增加ChangeListener的方法 以便适应更多的参数需求。


最后OVER了 请大家一起讨论 指教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值