观察者模式(二)

“怎样优雅地表达着凉拉肚子了?”“你是无意穿堂风,偏偏孤倨引山洪 (摘抄~~画面太恶心了)

本节讲述的是:使用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();
	
		
		
	}

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值