2018-7-20-observer-model
layout: post
title: ‘觀察者模式’
subtitle: ‘’
date: 2018-07-20
categories: 設計模式
cover: ‘’
tags: 觀察者模式 設計模式
個人網站:https://tinuv.me/
**更好的閱讀體驗請訪問:https://tinuv.me/2018/07/02/188.html
介紹
觀察者模式屬於行為型模式.當物件存在一對多的關係時,使用觀察者模式.比如當一個物件被修改時,自動通知它的依賴物件
分析
我覺得很重要的一點是搞清哪一個是觀察者,哪一個是被觀察者,就是說到底一
是觀察者還是一
被觀察者,從它的另一個名字:訂閱釋出模式
一
就是釋出者
也就是被觀察者,多
是訂閱者,也就是觀察者.從這兩個名字的措辭來看,這兩個名字的主被動關係剛好完全被顛倒.從易理解角度看,訂閱釋出模式
的名字可能更好.
所以分析的結果就是:
一
: 釋出者,被觀察者
多
: 訂閱者,觀察者
練習
說明
- 被觀察者
被觀察者,狀態的改變是通過這個物件釋出給觀察者的,也有可能是作為被觀察者和觀察者的橋樑,與觀察者和被觀察者都關聯,被觀察者把狀態的改變傳遞給這個橋樑,橋樑把這個狀態的改變再發布給釋出者.
- 觀察者
觀察者被動的接受被觀察者釋出資訊,所以說訂閱釋出模式
更符合這種模式的叫法,觀察者通常設計會設計一個成抽象類或者介面,因為觀察者往往有很多,這種設計容納一些頂層設計.
示例
觀察者設定為一個抽象類(個人認為不優雅)
- 被觀察者基類
通常基類有三個函式addObserver(Observer observer)
,removeObserver(Observer observer)
和一個抽象函式publishMessage()
,addObserver(Observer observer)
函式用來繫結觀察者和被觀察者,removeObserver(Observer observer)
函式用來移除觀察者和被觀察者的繫結關係(訂閱關係),值得注意的是,如果是通過抽象類的方式,那麼觀察者必須要持有被觀察者的引用,繫結關係的新增和移除通常都由觀察者(訂閱者)進行,這也是我認為這種方式不優雅的原因,因為觀察者通常有多個,這種會造成程式碼維護困難,但好處是把訂閱和解除訂閱的權利交給了觀察者
import java.util.ArrayList;
import java.util.List;
public abstract class Observeable {
List<Observer> Observers = new ArrayList<>();
public void addObseriver(Observer observer){
Observers.add(observer);
}
public void removeObserver(Observer observer){
Observers.remove(observer);
}
public abstract void publishMessage();
}
- 被觀察者
被觀察者必須實現publishMessage()
,這個方法是一個通知訂閱的物件的函式,因為要傳遞的事件或者說引數具體都不同.
public class Observe extends Observeable {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
publishMessage();
}
@Override
public void publishMessage() {
for (Observer observer:Observers){
observer.receiveMessage();
}
}
}
- Observer基類
Observer
擁有一個類似receive()
的抽象函式,子類實現這個函式用來處理被觀察者傳遞過來的事件或者資料,如果是通過抽象類的方式來實現觀察者模式,那個每個Observer
必須持有一個Observe
物件
public abstract class Observer {
public abstract void receiveMessage();
protected Observe observe;
}
- Observer子類
Observer
子類實現Observer
基類,擁有訂閱和解除訂閱的權利,通過實現抽象函式receiveMessage()
來處理被觀察者傳遞過來的事件或者資料
public class FristObserver extends Observer {
public FristObserver(Observe observe){
this.observe = observe;
observe.addObseriver(this);
}
@Override
public void receiveMessage() {
System.out.println("frist observer receive message"+observe.getState());
}
}
觀察者通過介面的方式實現觀察者模式
這是觀察者模式非常通用的形式,觀察者必須實現這個介面,這種方式下,是一種中央集權的方式:只有被觀察者有權力新增和移除觀察者物件(其實都是通過被觀察物件新增或解除訂閱關係,只是位置不同而已)
Observe
基類Observeable
import java.util.ArrayList;
import java.util.List;
public abstract class Observeable {
List<Observer> Observers = new ArrayList<>();
public void addObseriver(Observer observer){
Observers.add(observer);
}
public void removeObserver(Observer observer){
Observers.remove(observer);
}
public abstract void publishMessage();
}
Observe
類
public class Observe extends Observeable {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
publishMessage();
}
@Override
public void publishMessage() {
for (Observer observer:Observers){
observer.receiveMessage(state);
}
}
}
Observer
介面
public interface Observer{
void receiveMessage(String message);
}
Observer
實現類
public class FristObserver implements Observer {
@Override
public void receiveMessage(String message) {
System.out.println("frist observer receive message"+message);
}
}