【設計模式】觀察者

目前這篇觀察者是自己剛整理的,很多都來源於網上,自己目前沒有設計模式的書,自己過一段時間買完書,重新理解完,會回來整理的。

定義對象之間的一對多依賴,當一個對象狀態改變時,它的所有依賴都會收到通知並且自動更新狀態。
主題(Subject)是被觀察的對象,而其所有依賴者(Observer)稱爲觀察者。
在這裏插入圖片描述
觀察者模式所涉及的角色有:

●  抽象主題(Subject)角色:抽象主題角色把所有對觀察者對象的引用保存在一個聚集(比如ArrayList對象)裏,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象,抽象主題角色又叫做抽象被觀察者(Observable)角色。
●  具體主題(ConcreteSubject)角色:將有關狀態存入具體觀察者對象;在具體主題的內部狀態改變時,給所有登記過的觀察者發出通知。具體主題角色又叫做具體被觀察者(Concrete Observable)角色。
●  抽象觀察者(Observer)角色:爲所有的具體觀察者定義一個接口,在得到主題的通知時更新自己,這個接口叫做更新接口。
●  具體觀察者(ConcreteObserver)角色:存儲與主題的狀態自恰的狀態。具體觀察者角色實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題的狀態 像協調。如果需要,具體觀察者角色可以保持一個指向具體主題對象的引用。

模型

推模型

主題對象向觀察者推送主題的詳細信息,不管觀察者是否需要,推送的信息通常是主題對象的全部或部分數據。

拉模型

主題對象在通知觀察者的時候,只傳遞少量信息。如果觀察者需要更具體的信息,由觀察者主動到主題對象中獲取,相當於是觀察者從主題對象中拉數據。一般這種模型的實現中,會把主題對象自身通過update()方法傳遞給觀察者,這樣在觀察者需要獲取數據的時候,就可以通過這個引用來獲取了。

推模型

/**
 * 抽象觀察者角色
 *
 */
public interface Observer {
    void update(String state);

    String getName();
}


/**
 * @desc 具體觀察者
 * @date 2017年5月13日 下午5:11:52
 */
public class ConcreteObserver implements Observer {

    private String name;
    private String state;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public void update(String state) {
        // 更新觀察着狀態
        this.state = state;
        System.out.println(getName() + "觀察者狀態更新爲:" + state);
    }

    @Override
    public String getName() {
        return name;
    }

}


import java.util.ArrayList;
import java.util.List;

/**
 * 抽象主題角色類
 */
public abstract class Subject {
    /**
     * 保存觀察者的容器
     */
    private List<Observer> list = new ArrayList<Observer>();

    /**
     * 註冊觀察者
     */
    public void register(Observer o) {
        list.add(o);
        System.out.println("增加了一個觀察者:" + o.getName());
    }

    /**
     * 移除觀察者
     * 
     * @param o
     */
    public void remove(Observer o) {
        System.out.println("移除了一個觀察者:" + o.getName());
        list.remove(o);
    }

    /**
     * 通知觀察者
     * 
     * @param newState
     */
    public void nodifyObservers(String newState) {
        for (Observer observer : list) {
            observer.update(newState);
        }
    }
}



/**
 * 具體主題角色
 */
public class ConcreteSubject extends Subject {
    /**
     * 狀態
     */
    private String state;

    public String getState() {
        return state;
    }

    public void change(String newState) {
        state = newState;
        System.out.println("狀態變爲:" + newState);
        System.out.println("開始通知觀察者...");
        this.nodifyObservers(state);
    }

}



/**
 * @desc 測試觀察者模式

 * @date 2017年5月13日 下午5:18:30
 */
public class MainTest {
    public static void main(String[] args) {
        Observer o1 = new ConcreteObserver("o1");
        Observer o2 = new ConcreteObserver("o2");
        Observer o3 = new ConcreteObserver("o3");
        ConcreteSubject csj = new ConcreteSubject();
        csj.register(o1);
        csj.register(o2);
        csj.register(o3);
        csj.remove(o2);
        csj.change("new State!");
    }
}

拉模型



/**
 * 抽象觀察者角色
 * 
 */
public interface Observer {
    /**
     * 傳入主題,獲取中的對象
     * @param subject
     */
    void update(Subject subject);

    String getName();
}


/**
 * @desc 具體觀察者

 */
public class ConcreteObserver implements Observer {

    private String name;
    private String state;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void update(Subject subject) {
        // 主動去主題裏拿數據
        state = ((ConcreteSubject) subject).getState();
        System.out.println(getName() + "觀察者狀態更新爲:" + state);
    }

}



import java.util.ArrayList;
import java.util.List;

/**
 * 抽象主題角色類
 *
 */
public abstract class Subject {
    /**
     * 保存觀察者的容器
     */
    private List<Observer> list = new ArrayList<Observer>();

    /**
     * 註冊觀察者
     */
    public void register(Observer o) {
        list.add(o);
        System.out.println("增加了一個觀察者:" + o.getName());
    }

    /**
     * 移除觀察者
     * 
     * @param o
     */
    public void remove(Observer o) {
        System.out.println("移除了一個觀察者:" + o.getName());
        list.remove(o);
    }

    /**
     * 通知觀察者
     * 
     * @param newState
     */
    public void nodifyObservers() {
        for (Observer observer : list) {
            observer.update(this);
        }
    }
}

/**
 * 具體主題角色
 *
 */
public class ConcreteSubject extends Subject {
    /**
     * 狀態
     */
    private String state;

    public String getState() {
        return state;
    }

    public void change(String newState) {
        state = newState;
        System.out.println("狀態變爲:" + newState);
        System.out.println("開始通知觀察者...");
        this.nodifyObservers();
    }

}

/**
 * @desc 測試觀察者模式(拉模式)
 */
public class MainTest {
    public static void main(String[] args) {
        Observer o1 = new ConcreteObserver("o1");
        Observer o2 = new ConcreteObserver("o2");
        Observer o3 = new ConcreteObserver("o3");
        ConcreteSubject csj = new ConcreteSubject();
        csj.register(o1);
        csj.register(o2);
        csj.register(o3);
        csj.remove(o2);
        csj.change("new State!");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章