【設計モード】観察者モード

3818 ワード

説明:これは1対の多くの依存関係で、複数の観察者が同時にあるテーマの対象を監督しています。対象が変わった時、すべての観察者に通知します。彼らは適時に自分を更新することができます。このモードは生活の中でよく見られます。例えば、最も簡単なrss購読、電子商取引などはこのようなモードを使いました。
ここで特に言及する価値があるのは、jdkのツールパッケージにもこのような設計モードの具体的な実装クラス(java.util.Observer,java.util.Observer able)があります。このうちObserverは観察者であり、Observerableは観察対象である。ObserverableとObserverをそれぞれ継承して実現すれば、この機能が実現できます。
 
具体的なコードを見て実現しましょう。
1.観察者(Observerインターフェース)は、一つの抽象的な方法しかない。この方法は二つのパラメータを受信し、それぞれ観察された対象と観察された具体的な値を表し、観察された目標値(value)が変化すると、新しいvalueをこの方法に伝える。もちろん、このインターフェースは実現クラスによって実現されなければなりません。
public interface Observer
{
	public void update(Observerable observersable,Object value);
}
2.観察された目標(Observable)は、この種類には多くの方法があり、その精髄はArayList集合とnotifyObservers方法であり、全体の種類はこの集合を維持しています。一方、notifyObserversという方法も巡回集合によってすべての観察者対象をお知らせします。このクラスを研究しましょう。
このクラスには2つのフィールド(メンバー変数)があります。ArayList型のobserversとbollan型のhas Chendがあります。ここでArayListのセットには多くのObserverオブジェクトが格納されています。集合を削除することによって、observerの添削操作ができます。notifyObservers方法は、ArayListを通じて、Pubdateの呼び出し方法もあります。「お知らせします」観察者一人に!
import java.util.ArrayList;

public class Observerable
{
	private ArrayList<Observer> observers;
	private boolean hasChanged = false;
	
	public Observerable()
	{
		observers = new ArrayList<Observer>();//observers           !
	}
	protected void setChanged()
	{
		hasChanged = true;
	}
	public void clearChanged()
	{
		hasChanged = false;
	}
	public synchronized void addObserver(Observer obs)
	{
		if(obs==null)
			throw new NullPointerException();
		if(!observers.contains(obs))
			observers.add(obs);
	}
	public synchronized void deleteObserver(Observer obs)
	{
		observers.remove(obs);
	}
	public synchronized void deleteObservers()
	{
		observers.removeAll(observers);
	}
	public synchronized int countObservers()
	{
		return observers.size();
	}
	public void notifyObservers(Object value)
	{
		if(!hasChanged)
			return;
		for(Observer observer : observers)//  observers   observer  update  
			observer.update(this, value);
	}
}
3.この類はどう使いますか?
//Observerを実現するクラス
public class Friend implements Observer
{
	private String name=null;
	public Friend(String name)
	{
		this.name = name;
	}
	@Override
	public void update(Observerable observersable, Object value)
	{
		String phoneNum = (String)value;
		System.out.println(this.name + "    :HI!         :" + phoneNum);
	}
}
//Observerableのクラスを継承する
public class Members extends Observerable
{
	public void addMember(Friend friend)
	{
		super.addObserver(friend);
	}
	public void notifyFriends(String phoneNum)
	{
		super.setChanged();//  :       setChanged  ,     true
		super.notifyObservers(phoneNum);
	}
}
//試験類
public class Main
{
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		Members members = new Members();
		members.addMember(new Friend("zhangsan"));
		members.addMember(new Friend("lisi"));
		members.addMember(new Friend("wangwu"));
		System.out.println(members.countObservers());
		members.notifyFriends("18792503354");
		members.deleteObservers();
		System.out.println(members.countObservers());
	}

}
実行結果:
3 zhangsan受信メッセージ:HI!私の携帯番号はすでになりました。1879503354 lisi受信メッセージ:HI!私の携帯番号はすでになりました。1872503354 wangwu受信メッセージ:HI!私の携帯番号はすでになりました。ここに来て、視聴者モードが分かりましたよね。紙面を考慮して、私はここでjdk提供するObseverを試しません。試してみます
                                                                                                                                                                       
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
転載を歓迎します。転載は出所を明記してください。ありがとうございます。