起因:在看架構(gòu)設計的時候,有這樣的一句話“觀察者模式(Observer pattern)被用于 Swing 和很多的事件監(jiān)聽中”這樣的一句話,想到自己對其還不是很熟悉,所以去研究一下觀察者模式。
1 觀察者模式
觀察者(Observer)模式的定義:
指多個對象間存在一對多的依賴關(guān)系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。
這種模式有時又稱作發(fā)布-訂閱模式、模型-視圖模式,它是對象行為型模式。
2 觀察者模式 概述
我認為觀察者模式其主要的目的是解耦,降低耦合關(guān)系,(可能我的理解還不到位),
比如,我想要發(fā)一個公告,添加公告,查詢所有的訂閱人,給訂閱人添加消息,是寫在一個方法里面,現(xiàn)在用觀察者模式
我想要發(fā)一個公告,調(diào)用抽象目標,的具體目標的方法,在具體目標中查詢所有訂閱人,給訂閱人添加消息
觀察者模式是一種對象行為型模式,其主要優(yōu)點如下:
- 降低了目標與觀察者之間的耦合關(guān)系,兩者之間是抽象耦合關(guān)系。符合依賴倒置原則。
- 目標與觀察者之間建立了一套觸發(fā)機制。
它的主要缺點如下:
- 目標與觀察者之間的依賴關(guān)系并沒有完全解除,而且有可能出現(xiàn)循環(huán)引用。
- 當觀察者對象很多時,通知的發(fā)布會花費很多時間,影響程序的效率。
3 觀察者模式 模式結(jié)構(gòu)
觀察者模式的主要角色如下:
- 抽象主題(Subject)角色:也叫抽象目標類,它提供了一個用于保存觀察者對象的聚集類和增加、刪除觀察者對象的方法,以及通知所有觀察者的抽象方法。
- 具體主題(Concrete Subject)角色:也叫具體目標類,它實現(xiàn)抽象目標中的通知方法,當具體主題的內(nèi)部狀態(tài)發(fā)生改變時,通知所有注冊過的觀察者對象。
- 抽象觀察者(Observer)角色:它是一個抽象類或接口,它包含了一個更新自己的抽象方法,當接到具體主題的更改通知時被調(diào)用。
- 具體觀察者(Concrete Observer)角色:實現(xiàn)抽象觀察者中定義的抽象方法,以便在得到目標的更改通知時更新自身的狀態(tài)。
4 觀察者模式 代碼實現(xiàn)
package com.observer;
import java.util.*;
public class ObserverPattern {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
Observer obs1 = new ConcreteObserver1();
Observer obs2 = new ConcreteObserver2();
subject.add(obs1);
subject.add(obs2);
subject.notifyObserver();
}
}
//抽象目標
abstract class Subject {
protected List<Observer> observers = new ArrayList<>();
//增加觀察者方法
public void add(Observer observer) {
observers.add(observer);
}
//刪除觀察者方法
public void remove(Observer observer) {
observers.remove(observer);
}
public abstract void notifyObserver(); //通知觀察者方法
}
//具體目標
class ConcreteSubject extends Subject {
public void notifyObserver() {
System.out.println("具體目標發(fā)生改變...");
System.out.println("--------------");
for (Object obs : observers) {
((Observer) obs).update();
}
}
}
//抽象觀察者
interface Observer {
void update(); //反應
}
//具體觀察者1
class ConcreteObserver1 implements Observer {
public void update() {
System.out.println("具體觀察者1作出反應!");
}
}
//具體觀察者1
class ConcreteObserver2 implements Observer {
public void update() {
System.out.println("具體觀察者2作出反應!");
}
}
不要以為每天把功能完成了就行了,這種思想是要不得的,互勉~!