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