“怎样优雅地表达着凉拉肚子了?”“你是无意穿堂风,偏偏孤倨引山洪 (摘抄~~画面太恶心了)
本节讲述的是:使用Java内置的观察者模式(java.util下的Observable)
Observable类和我们上文定义的GuildWolfOne类类似,并且提供了其他方法。
package java.util;
public class Observable {
private boolean changed = false;
private Vector obs;
public Observable() {
obs = new Vector();
}
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
public void notifyObservers() {
notifyObservers(null);
}
public void notifyObservers(Object arg) {//只会在changed标为true时通知观察者,通知完毕后,changed标志设回false
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
public synchronized void deleteObservers() {
obs.removeAllElements();
}
protected synchronized void setChanged() {//setChanged()方法把changed标为true
changed = true;
}
protected synchronized void clearChanged() {
changed = false;
}
public synchronized boolean hasChanged() {
return changed;
}
public synchronized int countObservers() {
return obs.size();
}
}
狼人杀公会修改:
package com.zl.observer.two;
import java.util.Observable;
public class GuildWolftwo extends Observable {
private String message;
public void MessageContentChanged(){
setChanged();
notifyObservers(message);
}
public String getMessage() {//此方法主要用作观察者主动获取消息的方法‘拉’
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setMessagecontent(String message) {
this.message = message;
}
}
游戏玩家设计类:
package com.zl.observer.two;
import java.util.Observable;
import java.util.Observer;
import com.zl.observer.one.DisplayMessage;
public class Observerthree implements Observer, DisplayMessage {
Observable observable;
private String message;
public Observerthree(Observable observable){
this.observable=observable;
observable.addObserver(this);
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println(this.getClass().getName()+message);
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if(o instanceof GuildWolftwo){
this.message=(String) arg;
display();
}
}
}
package com.zl.observer.two;
import java.util.Observable;
import java.util.Observer;
import com.zl.observer.one.DisplayMessage;
public class Observerfour implements Observer, DisplayMessage {
Observable observable;
private String message;
public Observerfour(Observable observable){
this.observable=observable;
observable.addObserver(this);
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println(this.getClass().getName()+message);
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if(o instanceof GuildWolftwo){
this.message=(String) arg;
display();
}
}
}
测试类:
package com.zl.observer.two;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
public class TestObserver {
/**
* @param args
*/
public static void main(String[] args) {//结果的显示和游戏玩家加入公会的顺序相反,这是由于Observable类中notifyObservers方法的处理不同
//所以程序不能依赖获取消息的次序
// TODO Auto-generated method stub
GuildWolftwo tObservable=new GuildWolftwo();
Observer tObserver=new Observerthree(tObservable);
Observer mObserver=new Observerfour(tObservable);
tObservable.setMessagecontent("你好");
tObservable.MessageContentChanged();
}
}
上面主要用可观察者主动“推”消息。
假设:一个游戏玩家可以同时进入多个公会,但公会类型不一样。比如:一个属于相亲类型的公会,一个属于分享游戏心得的公会。
这里只是讨论多个可观察者如何主动推送消息,观察者知道是那个可观察者进行推送的消息,所以具体的类操作就不去扩展了。
新的公会设计与第一个一致:
package com.zl.observer.two;
import java.util.Observable;
public class GuildWolfthree extends Observable {
private String message;
public void MessageContentChanged(){
setChanged();
notifyObservers(message);
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setMessagecontent(String message) {
this.message = message;
}
}
需要修改一下显示消息的方法:
package com.zl.observer.two;
import java.util.Observable;
import java.util.Observer;
import com.zl.observer.one.DisplayMessage;
public class Observerthree implements Observer, DisplayMessage {
Observable observable;
private String message;
private String GuildWolfName="";
public Observerthree(Observable observable){
this.observable=observable;
observable.addObserver(this);
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println(GuildWolfName+this.getClass().getName()+message);
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
this.GuildWolfName=o.getClass().getName();
if(o instanceof Observable){
this.message=(String) arg;
display();
}
}
}
测试类:
package com.zl.observer.two;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
public class TestObserver {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GuildWolftwo tObservable=new GuildWolftwo();
GuildWolfthree mObservable=new GuildWolfthree();
Observer tObserver=new Observerthree(tObservable);
Observer mObserver=new Observerthree(mObservable);
tObservable.setMessagecontent("你好");
tObservable.MessageContentChanged();
mObservable.setMessagecontent("有人通知您相亲");
mObservable.MessageContentChanged();
}
}