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

来源:互联网 发布:腾讯大数据 手游 编辑:程序博客网 时间:2024/05/01 21:35

观察者模式(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了 请大家一起讨论 指教