设计模式之观察者模式
前言:
觀察者模式(Observer Pattern)定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使他們能夠自己更新自己。
一.觀察者模式簡介:
觀察者模式(Observer Pattern)應用在當一個對象的改變,需要同時改變其他對象的時候,實現了兩個相互協作的對象不會為了保持一致性而耦合在一起,這兩個對象都依賴于各自的抽象。
二.觀察者模式的實例講解:
案例:學生們觀察老師講課時的動態,決定是否繼續睡覺或者繼續抄作業。
1.產品設計UML類圖:
(圖片加載慢,多刷新幾下,耐心等待……)
注:指揮者類Client和Observer、Subject的實現類是依賴關系。
2.通知者抽象類(主題類):
設計分析:Subject類把所有對觀察者對象的引用保存在一個聚集里,每個主題都可以有任何數量的觀察者,抽象主題增加一個接口,可以增加和刪除觀察者對象。抽象主題類可以被多個具體主題類繼承。
package com.pattern.observer.subject;import com.pattern.observer.observer.Observer;/*** 通知者抽象類*/ public abstract class Subject {// 通知者狀態protected String subjectState;// 獲取通知者狀態public String getSubjectState() {return subjectState;}// 設置通知者狀態public void setSubjectState(String subjectState) {this.subjectState = subjectState;}// 添加觀察者public abstract void addObserver(Observer observer);// 刪除觀察者public abstract void removeObserver(Observer observer);// 通知觀察者public abstract void notifyObserver(); }3.老師通知者類(具體主題類):
設計分析: 將有關狀態存入觀察者對象,在主題內部狀態改變的時候,給所有觀察者發信息。
在本例中,老師的行為受到所有學生的關注,一旦反生改變,將會通知(notifyObserver())學生改變(update())行為。比如:正在打瞌睡的同學,看到老師過來,會立馬打起精神。正在語文課上,抄數學作業的人,會立馬收起作業,假裝認真的讀語文書。
package com.pattern.observer.subject;import java.util.ArrayList; import java.util.List;import com.pattern.observer.observer.Observer;public class ChineseTeacher extends Subject {// 所有學生集合(所有觀察者集合)private List<Observer> studentList = new ArrayList<Observer>();@Overridepublic void addObserver(Observer observer) {studentList.add(observer);}@Overridepublic void removeObserver(Observer observer) {studentList.remove(observer);}// 通知觀察者@Overridepublic void notifyObserver() {for (Observer o : studentList) {// 提醒觀察者,做出反應o.update();}}// 設置通知者狀態@Overridepublic void setSubjectState(String subjectState) {// 接收狀態,并設置super.setSubjectState(subjectState);}// 獲取通知者狀態@Overridepublic String getSubjectState() {// 獲取狀態return super.getSubjectState();}}4.觀察者抽象類
設計分析: 抽象觀察者,為所有的具體觀察者定義一個接口,在得到主題的通知時,通知自己。抽象觀察者類可以被多個具體觀察者繼承。
package com.pattern.observer.observer;import com.pattern.observer.subject.Subject;public abstract class Observer {protected String name;protected Subject subject;public Observer(String name, Subject subject) {super();this.name = name;this.subject = subject;}public abstract void update(); }5.學生觀察者類(具體觀察者類)
①:打瞌睡的學生觀察者類
package com.pattern.observer.observer;import com.pattern.observer.subject.Subject;/*** 瞌睡的學生(具體觀察者類)*/ public class SleepStudent extends Observer {// 構造方法public SleepStudent(String name, Subject subject) {super(name, subject);}// 觀察者做出反應@Overridepublic void update() {System.out.println(subject.getSubjectState() + "!" + name + ",下雨了,別睡了");}}②抄作業的學生觀察者類:
package com.pattern.observer.observer;import com.pattern.observer.subject.Subject;/*** 抄作業的學生(具體的觀察者類)* */ public class CopyHomeworkStudent extends Observer {// 構造方法public CopyHomeworkStudent(String name, Subject subject) {super(name, subject);}// 觀察者做出反應@Overridepublic void update() {System.out.println(subject.getSubjectState() + "!" + name + ",高數能考及格了,就別抄數學作業了");}}5.客戶端中使用:
設計分析: 客戶端需要依賴指揮著類和具體的建造者類,通過指揮者中的方法,控制建造者繪制具體的人物畫像,使得建造者類中的代碼和客戶端的表示層代碼分離,降低耦合度。
注:本客戶端用到Java的Swing繪圖,若不了解如何用Java繪圖,請點擊參考本人另一篇博文介紹《 Java用JFrame、JPanel、Graphics繪圖案例講解》。
package com.pattern.observer.client;import com.pattern.observer.observer.CopyHomeworkStudent; import com.pattern.observer.observer.SleepStudent; import com.pattern.observer.subject.ChineseTeacher;/*** 客戶端類*/ public class Client {public static void main(String[] args) {// 實例化通知者ChineseTeacher chTeacher = new ChineseTeacher();// 實例化觀察者SleepStudent sleepStudent = new SleepStudent("王臣", chTeacher);CopyHomeworkStudent copyStudent = new CopyHomeworkStudent("田壯", chTeacher);// 通知者添加被通知對象chTeacher.addObserver(sleepStudent);chTeacher.addObserver(copyStudent);// 通知者改變狀態chTeacher.setSubjectState("我要找幾個同學爬黑板");// 發出通知chTeacher.notifyObserver();} }6.運行結果展示:
我要找幾個同學爬黑板!王臣,下雨了,別睡了 我要找幾個同學爬黑板!田壯,高數能考及格了,就別抄數學作業了7.源碼下載
本文示例代碼下載地址:點擊下載
三.總結:
1.觀察者模式的優點:
- 觀察者對象和主題對象之間是接觸耦合的,二者都依賴于各自的抽象,體現出依賴倒轉原則的應用。
- 建立了一套觸發機制,可以當一個對象改變時,同時改變其他對象(類似Oracle的觸發器)。
2.觀察者式的缺點:
- 觀察者只能知道主題對象發生變化的狀態,卻不能知道主題對象是怎么發生變化的。
- 耗時增加,當有很多觀察者時,通知所有的觀察者會花費很多時間。
總結
以上是生活随笔為你收集整理的设计模式之观察者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS 实战: Switch 按钮开关(
- 下一篇: asp.net ajax控件工具集 Au