前言
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();
}
}
運行結果
補充說明
模式可以用接口實現,這裏用的是抽象類。用接口的話只要把一些屬性放到具體的子類裏去實現就行了.