觀察者模式-Observer Pattern

前言

Define a one-to-many dependency between objects so that when one object changes state,all its dependents are notified and updated automatically.

定義對象間一種一對多的依賴關係,使得每當一個對象改變狀態,所有依賴於它的對象都會得到通知並被自動更新.

GitHub源碼:

https://github.com/YEN-GitHub/PatternDemo/tree/master/src/BehavioralPattern2/ObserverPattern

題目

觀察者有遊戲觀察者(GameObserver)和視頻觀察者(VideoObserver)。
觀察者中的更新函數(updata)只需輸出具體Subject對象的狀態和狀態改變語句即可。
目標對象(Subject)有哨兵(Sentry)和老師(teacher),一個目標對象可以對應多個和多種觀察者對象,
當客服端目標對象狀態設置爲("高老師來了"),調用通知函數(notifyObserver)通知所有對應的觀察者對象執行更新函數。
其中老師(teacher)的狀態還包括一個懲罰(panish)函數,懲罰(panish)函數輸出如下“XXX  XXX(所有懲罰人的名字)把觀察者模式的結構圖抄寫10遍”
完成狀態更新。

UML類圖

這裏寫圖片描述

代碼

package BehavioralPattern2.ObserverPattern.demo1;

/**
 * Created by yangenneng on 2017-06-14 10:37
 * Abstract:抽象觀察者角色
 */
public abstract class Observer {



    protected String stuName;//學生姓名
    protected Subject subject;//哨兵

    /*構造函數*/
    Observer(String stuName,Subject subject){
        this.stuName=stuName;
        this.subject=subject;
    }

    /*改變狀態*/
    public abstract void update();

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public Subject getSubject() {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

}
package BehavioralPattern2.ObserverPattern.demo1;

import java.util.ArrayList;

/**
 * Created by yangenneng on 2017-06-14 10:37
 * Abstract:抽象主題角色-即哨兵
 */
public abstract class Subject {

    protected String msg="";//通知信息

    Subject(String msg){
        this.msg=msg;
    }

    /*存放所有待通知的觀察者*/
    protected ArrayList<Observer> arrayList=new ArrayList<>();

    /*增加被觀察者*/
    public void addObserver(Observer obj) {arrayList.add(obj);}

    /*移除被觀察者*/
    public void removeObserver(Observer obj){arrayList.remove(obj);}

    /*通知函數*/
    public abstract void notifyObserver();

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }


}
package BehavioralPattern2.ObserverPattern.demo1;

/**
 * Created by yangenneng on 2017-06-14 11:01
 * Abstract:遊戲觀察者
 */
public class GameObserver extends Observer {

    GameObserver(String name,Subject subject){super(name,subject);}

    @Override
    public void update() {
        System.out.println(this.stuName+"切換狀態,由遊戲狀態變爲做實驗狀態");
    }

}
package BehavioralPattern2.ObserverPattern.demo1;

/**
 * Created by yangenneng on 2017-06-14 11:02
 * Abstract:視頻觀察者
 */
public class VideoObserver extends Observer {

    VideoObserver(String name,Subject subject){super(name,subject);}

    @Override
    public void update() {
        System.out.println(this.stuName+"切換狀態,由視頻狀態變爲做實驗狀態");
    }
}
package BehavioralPattern2.ObserverPattern.demo1;

/**
 * Created by yangenneng on 2017-06-14 11:03
 * Abstract:好人哨兵
 */
public class SentrySubject extends Subject{

    SentrySubject(String msg) {
        super(msg);
    }

    /*通知函數*/
    public void notifyObserver(){
        System.out.println(msg);
        for (Observer observer:arrayList){
            observer.update();
        }
    }

}
package BehavioralPattern2.ObserverPattern.demo1;

/**
 * Created by yangenneng on 2017-06-14 11:06
 * Abstract:老師-哨兵
 */
public class TeacherSubject extends Subject{

    TeacherSubject(String msg) {
        super(msg);
    }

    /*通知函數*/
    public void notifyObserver(){
        System.out.println(msg);
        for (Observer observer:arrayList){
            observer.update();
        }
        panish();//懲罰
    }

    /*懲罰學生函數*/
    public void panish(){
        for (Observer observer:arrayList){
            System.out.print(observer.getStuName()+ " ");
        }
        System.out.println("罰抄觀察者模式10遍");
    }

}
package BehavioralPattern2.ObserverPattern.demo1;

/**
 * Created by yangenneng on 2017-06-14 11:10
 * Abstract:客戶端測試
 */
public class Client {
    public static void main(String[] args) {
        Subject subject=new SentrySubject("");

        Observer stu1=new GameObserver("張三",subject);
        Observer stu2=new VideoObserver("李四",subject);

        subject.addObserver(stu1);
        subject.addObserver(stu2);

        subject.notifyObserver();

        System.out.println("-------------------------------------");

        subject=new TeacherSubject("高老師來了");

        subject.addObserver(stu1);
        subject.addObserver(stu2);
        subject.notifyObserver();
    }
}

運行結果

這裏寫圖片描述

補充說明

模式可以用接口實現,這裏用的是抽象類。用接口的話只要把一些屬性放到具體的子類裏去實現就行了.

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