Java設計模式--觀察者模式

應用場合:

主題-觀察者,當主題的狀態改變時,調用notify方法通知所有的觀察者作出相應的處理(即調用觀察者的updae方法)。

是一種一對多的關係,主題只有一個,這個主題有一個觀察者隊列(observerList<Observer>)。

主題和觀察者都是接口,雖然說觀察者模式解耦了觀察者和主題,但是對於這兩個接口來說,他們是相互依賴的。

觀察者模式接口關係

主題

  • 這個接口要提供1.添加觀察者的方法;2.刪除觀察者的方法;3.通知觀察的方法。
  • 其實現類中,有一個List類型的成員變量用來存儲觀察者。在通知觀察的方法中,對List進行變量,調用觀察者的update方法。

觀察者

  • 觀察者接口中要有一個update方法,當主題通知觀察者時,會調用這個update方法來將業務狀態傳遞給觀察者。

每聲明一個觀察者時,通過構造函數的方式需要綁定一個主題,此時將這個觀察者添加到某個主題的隊列中。當觀察者想要退出主題時,需要調用主題的方法,主題從自己的隊列中刪除這個觀察者。

Subject sub=new Sub();
Observer obj=new Observer(sub); //綁定主題
sub.notify(); //遍歷觀察者,調用觀察者的update方法
sub.removeObserver(obj); //主題將觀察者從自己的觀察者隊列中移除

小實例

主題接口

主題接口中提供了三個基礎方法:addObserver()用於給主題添加Observer,removeObserver()用於將Observer移除主題的監聽隊列,notifying()方法用於遍歷、通知觀察者,即遍歷調用Observer的update()方法。

package com.model;

public interface Subject
{

    void addObserver(Observer obj);

    void removeObserver(Observer obj);

    void notifying(Message message);

}

觀察者接口

Observer接口中主要是定義了update()方法,主題在通知觀察者時,就會調用這個方法

package com.model;

public interface Observer
{
    String getObserverName();

    void update(Message message);
}

輔助的一個業務類接口

一個輔助類,用於Subject和Observer間傳遞消息內容

package com.model;

public interface Message
{
    String getMessage();
}

主題的實現類

package com.model.impl;

import java.util.ArrayList;
import java.util.Iterator;

import com.model.Message;
import com.model.Observer;
import com.model.Subject;

public class Event implements Subject{

    ArrayList<Observer> observerList;


    public Event() {
        super();
        this.observerList = new ArrayList<Observer>();
    }

    @Override
    public void addObserver(Observer obj) {
        this.observerList.add(obj);
    }

    @Override
    public void removeObserver(Observer obj) {
        this.observerList.remove(obj);
    }

    public String getObserverList() {
        String list="";
        for(Iterator<Observer> iter=observerList.iterator();iter.hasNext();) {
            list+=iter.next().getObserverName();
        }
        return list;
    }

    @Override
    public void notifying(Message message) {
        for (Iterator iterator = observerList.iterator(); iterator.hasNext();) {
            Observer observer = (Observer) iterator.next();
            observer.update(message);

        }
    }

}

觀察者實現類

- package com.model.impl;

import com.model.Message;
import com.model.Observer;
import com.model.Subject;

public class Listener implements Observer
{
    private String message;

    private String listenerName;

    Subject sub;

    public Listener(Subject sub)
    {
        this.sub = sub;
        sub.addObserver(this);
        this.message = "";
        this.listenerName = "";
    }

    @Override
    public void update(Message message)
    {
        this.setMessage(message.getMessage());
        System.out.println(this.getRuleMessage());
    }

    public void setMessage(String message)
    {
        this.message = message;
    }

    String getMessage()
    {
        return this.message;
    }

    String getRuleMessage()
    {
        String message = this.getListenerName() + "-->" + this.getMessage();
        return message;
    }

    public String getListenerName()
    {
        return listenerName;
    }

    public void setListenerName(String listenerName)
    {
        this.listenerName = listenerName;
    }

    @Override
    public String getObserverName()
    {
        return this.getListenerName();

    }
}

業務實現類

- package com.model.impl;

import com.model.Message;

public class RuleMessage implements Message
{
    String message;

    public RuleMessage(String message)
    {
        super();
        this.message = message;
    }

    public void setMessage(String message)
    {
        this.message = message;
    }

    @Override
    public String getMessage()
    {
        return this.message;
    }

}

主方法運行類

場景一
首先定義一個Event,此時他的監聽隊列是空的。
1號觀察者Listener 1註冊了Event的監聽
Event發生變化後通知自己的觀察者隊列
場景二
2號觀察者Listener 2註冊了Event的監聽
Event發生變化後通知自己的觀察者隊列
場景三
1號監聽者取消監聽Event
Event發生變化後通知自己的觀察者隊列
package com.model.impl;

import com.model.Message;
import com.model.Subject;

public class Main
{

    public static void main(String[] args)
    {
        Subject processorRule = new Event();
        System.out.println("This rule event's observerList:{" + ((Event) processorRule).getObserverList() + "}");
        Listener processorRuleListener = new Listener(processorRule);
        processorRuleListener.setListenerName("listener 1");
        System.out.println("listener 1 subscribes!");
        System.out.println("This rule event's observerList:{" + ((Event) processorRule).getObserverList() + "}");
        System.out.println();

        Message ruleMsg1 = new RuleMessage("processor rule1 is fired");
        System.out.println("fired rule!");
        processorRule.notifying(ruleMsg1);
        System.out.println();

        Listener processorRuleListener2 = new Listener(processorRule);
        processorRuleListener2.setListenerName("listener 2");
        System.out.println("listener 2 subscribes!");
        System.out.println("This rule event's observerList:{" + ((Event) processorRule).getObserverList() + "}");
        Message ruleMsg = new RuleMessage("processor rule2 is fired");
        System.out.println("fired rule!");
        processorRule.notifying(ruleMsg);
        System.out.println();

        processorRule.removeObserver(processorRuleListener);
        System.out.println("listener 1 leaves!");
        System.out.println("This rule event's observerList:{" + ((Event) processorRule).getObserverList() + "}");
        Message ruleMsg3 = new RuleMessage("processor rule3 is fired");
        System.out.println("fired rule!");
        processorRule.notifying(ruleMsg3);
    }

}

業務運行結果:

eclipse運行結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章