Java設計模式-觀察者模式

觀察者模式中,一個被觀察者管理所有相依於它的觀察者物件,並且在本身的狀態改變時主動發出通知。這通常通過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實現事件處理系統。

角色
抽象被觀察者角色:把所有對觀察者對象的引用保存在一個集合中,每個被觀察者角色都可以有任意數量的觀察者。被觀察者提供一個接口,可以增加和刪除觀察者角色。一般用一個抽象類和接口來實現。
抽象觀察者角色:爲所有具體的觀察者定義一個接口,在得到主題的通知時更新自己。
具體被觀察者角色:在被觀察者內部狀態改變時,給所有登記過的觀察者發出通知。具體被觀察者角色通常用一個子類實現。
具體觀察者角色:該角色實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題的狀態相協調。通常用一個子類實現。如果需要,具體觀察者角色可以保存一個指向具體主題角色的引用。

適用場景
1) 當一個抽象模型有兩個方面, 其中一個方面依賴於另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和複用。
2) 當對一個對象的改變需要同時改變其它對象, 而不知道具體有多少對象有待改變。
3) 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不希望這些對象是緊密耦合的。

應用:通過一個簡單的例子,描述學生給玩遊戲和看電影的學生把風,如果看見老師來了,則通知玩遊戲和看電影的學生老師來了,該學習了,老師沒看見玩遊戲和看電影的學生做小動作。如果沒看見老師,則玩遊戲和看電影的學生被老師看到。
下面是源碼:
1 Observer 抽象的觀察者

package com.whf.observer;
/*
 *  @author:辰
 *  @E-mail:[email protected]
 *  @2017年6月19日下午5:44:38
 */

/**
 * 抽象的觀察者
 * @author WU
 *
 */
public interface Observer {
    /**
     * 更新接口狀態
     * @param state
     */
    public void update(String state);
}

2 Watched 抽象的被觀察者

package com.whf.observer;
/*
 *  @author:辰
 *  @E-mail:[email protected]
 *  @2017年6月19日下午5:45:39
 */

/**
 * 抽象的 【被觀察者】
 * 聲明的方法(添加、移除觀察者,通知觀察者)
 * @author WU
 *
 */
public interface Watched {

     public void addWatcher(Observer observer);  

     public void removeWatcher(Observer observer);  

     public void notifyWatchers(); 

}

3 PlayGameStudent類

package com.whf.observer;
/*
 *  @author:辰
 *  @E-mail:[email protected]
 *  @2017年6月19日下午5:50:05
 */


/**
 * 具體的觀察者
 * 玩遊戲的學生
 * @author WU
 *
 */
public class PlayGameStudent implements Observer {

    @Override
    public void update(String state) {
        // TODO Auto-generated method stub
        System.out.println("玩遊戲的學生,老師來了,"+state);

    }

}

4 WactchMoveStudent 類

package com.whf.observer;
/*
 *  @author:辰
 *  @E-mail:[email protected]
 *  @2017年6月19日下午5:50:05
 */


/**
 * 具體的觀察者
 * 看電影的學生
 * @author WU
 *
 */
public class WactchMoveStudent implements Observer {

    @Override
    public void update(String state) {
        // TODO Auto-generated method stub
        System.out.println("看電影的學生,老師來了,"+state);

    }

}

5 Sutdent 類

package com.whf.observer;

import java.util.ArrayList;

/*
 *  @author:辰
 *  @E-mail:[email protected]
 *  @2017年6月19日下午5:47:27
 */


/**
 * 具體的觀察者
 * @author WU
 *
 */
public class Student implements Watched{

    /**
     * 用來保存註冊的觀察者對象
     */
    private ArrayList<Observer> observe = new ArrayList<Observer>();


    private String state;


    public Student(String state) {
        super();
        this.state = state;
    }

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

    /**
     * 註冊觀察者對象
     *  觀察者對象
     */
    @Override
    public void addWatcher(Observer observer) {
        // TODO Auto-generated method stub
        observe.add(observer);
    }



    /**
     * 刪除觀察者對象
     * 觀察者對象
     */
    @Override
    public void removeWatcher(Observer observer) {
        // TODO Auto-generated method stub
        observe.remove(observer);
    }

     /**
     * 通知所有註冊的觀察者對象
     */
    @Override
    public void notifyWatchers() {
        // TODO Auto-generated method stub
        for(Observer observer : observe){
            observer.update(state);
        }
    }


}

6 Teacher 類

package com.whf.observer;

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

/*
 *  @author:辰
 *  @E-mail:[email protected]
 *  @2017年6月19日下午6:52:45
 */

/**
 * 具體的被觀察者
 * @author WU
 *
 */
public class Teacher implements Watched{

    /**
     * 用來保存註冊的觀察者對象
     */
    private List<Observer> list = new ArrayList<Observer>();

    /**
     * 狀態
     */
    private String state;

    public Teacher(String state) {
        super();
        this.state = state;
    }

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


    /**
     * 註冊觀察者對象
     *  觀察者對象
     */
    @Override
    public void addWatcher(Observer observer) {
        // TODO Auto-generated method stub
        list.add(observer);
    }


    /**
     * 刪除觀察者對象
     * 觀察者對象
     */
    @Override
    public void removeWatcher(Observer observer) {
        // TODO Auto-generated method stub
        list.remove(observer);
    }

     /**
     * 通知所有註冊的觀察者對象
     */
    public void notifyWatchers() {
        // TODO Auto-generated method stub
        for(Observer observer : list){
            observer.update(state);
        }
    }

}

7 Client 類

package com.whf.observer;
/*
 *  @author:辰
 *  @E-mail:[email protected]
 *  @2017年6月19日下午7:33:58
 */

/**
 * 客戶端測試類
 * @author WU
 *
 */
public class Client {


    public static void main(String[] args) {

        //被觀察的學生
        Student student = new Student("");

        //被觀察的老師
        Teacher teacher = new Teacher("");

        //玩遊戲的學生
        PlayGameStudent playGameStudent = new PlayGameStudent();

        //看電影的學生
        WactchMoveStudent wactchMoveStudent = new WactchMoveStudent();

        // 註冊觀察者對象
        student.addWatcher(playGameStudent);
        student.addWatcher(wactchMoveStudent);

        // 註冊觀察者對象
        teacher.addWatcher(playGameStudent);
        teacher.addWatcher(wactchMoveStudent);

        //情況一 : 學生看見老師,狀態發生變化
        System.out.println("--------學生看見老師來了----------");
        student.setState("學生看見老師來了,並進行提醒,老師沒看見 ^_^");

        System.out.println("\n");  

        //情況二 : 學生未老師,狀態發生變化
        System.out.println("---------學生沒看見老師來了-------");
        teacher.setState("學生沒看見老師,老師看見了");



    }

}

測試結果:

--------學生看見老師來了----------
玩遊戲的學生,老師來了,學生看見老師來了,並進行提醒,老師沒看見 ^_^
看電影的學生,老師來了,學生看見老師來了,並進行提醒,老師沒看見 ^_^


---------學生沒看見老師來了-------
玩遊戲的學生,老師來了,學生沒看見老師,老師看見了
看電影的學生,老師來了,學生沒看見老師,老師看見了

至此,一個簡單的觀察者模式實現。

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