1、定義
觀察者模式又叫做釋出-訂閱(Public/Subscribe)模式。
定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀态發生變化時,會通知所有的觀察者對象,使他們能夠自動更新自己。
2、使用場景
老闆回來。我不知道?
辦公場景,同僚小王,同僚小明,前台小花,老闆王老五,主要時這四個人物。小王長期喜歡理财炒股會在工作間隙看一些股票走勢圖,小明忙着考公務員會在工作間隙看一些作業習題,小王、小明和前台小花關系處得比較好,是以大家聊得比較好。
老闆王老五經常出去跑業務有時候會不定期回到公司,是以小王和小明都比較擔心老闆回來撞見沒做工作之内的事情而受到批評,是以小王和小明就和前台小花達成了一個共識,小花要是看到老闆回來的時候麻煩通知一下。
3、代碼結構UML圖
抽象通知者:它把所有對觀察者對象的引用儲存在一個集合裡,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以添加和移除觀察者對象。
抽象觀察者:為所有的具體觀察者定義一個接口,在得到主題通知時更新自己。
老闆、小花:具體主題,将有管狀态存入具體觀察者對象;在具體主題的内部狀态改變時,給所有登記過的觀察者發出通知。
看股票觀察者、做習題觀察者:具體觀察者,實作抽象觀察者角色所要求的更新接口,以便使本身的狀态與主題的狀态相協調。
4、類的實作
(1)、Observable(抽象通知者)
interface Observable{
void add(Observer o);
void remover(Observer o);
void notify();
void setState(String state);
String getState();
}
(2)、Observer(抽象觀察者)
abstract Observer{
protected String name;
protected Observable obs;
public Observer(String name,Observable obs){
this.name=name;
this.obs=obs;
}
public abstract void update();
}
(3)、Boss(具體通知類老闆)
public class Boss implements Observable{
private List<Observer> observers=new ArrayList<>();
private String action;
@Overrride
public void add(Observer o){
observers.add(O);
}
@Override
public void remove(Observer o){
observers.add(o);
}
@Override
public void notify(){
foreach(Observer o:observers){
o.update();
}
}
@Override
public String getState(){
return action;
}
@Override
public void setState(String state){
action=state;
}
}
(4)、Staff(具體通知類 前台職員小花)
public class Staff implements Observable{
private List<Observer> observers=new ArrayList<>();
private String action;
@Overrride
public void add(Observer o){
observers.add(O);
}
@Override
public void remove(Observer o){
observers.add(o);
}
@Override
public void notify(){
foreach(Observer o:observers){
o.update();
}
}
@Override
public String getState(){
return action;
}
@Override
public void setState(String state){
action=state;
}
}
(5)、StockObserver(具體通知類小王)
public class StockObserver extends Observer{
Observable o;
String name;
public StockObserver(String name,Observable o){
this.o=o;
this.name=name;
}
public void update(){
System.out.println(o.getState()+" ," +name +" 關閉股票走勢圖,繼續工作!");
}
}
(6)、PracticeObserver(具體通知類小明)
public class PracticeObserver extends Observer{
Observable o;
String name;
public PracticeObserver(String name,Observable o){
this.o=o;
this.name=name;
}
public void update(){
System.out.println(o.getState()+" ," +name +" 關閉作業習題,繼續工作!");
}
}
5、用戶端調用
public static void main(String[] args){
Boss wlw=new Boss();
// Staff xiaohua=new Staff();
wlw=new Boss();
StockObserver tongshi1=new StockObserver("小王",wlw);
PracticeObserver tongshi2=new PracticeObserver("小明",wlw);
wlw.add(tongshi1);
wlw.add(tongshi2);
wlw.setState("我王老五回來了");
wlw.notify();
}
6、總結
觀察者模式,将一個系統分割成一系列互相協作的類有一個很不很好的副作用,那就是需要維護相關對象間的一緻性。我們不希望為了維持一緻性而使各類緊密耦合,這樣會給維護、擴充和重用都帶來不便。而觀察者模式的關鍵對象時主題Subject(Observable)和觀察者Observer,一個Subject可以在任意數目的依賴它的Observer,一旦Subject的狀态發生變化,所有的Observer都可以得到通知。Subject發出通知時,并不需要知道誰是它的觀察者,也就時說觀察者時誰,它根本不需要知道。而任何一個具體觀察者不知道也不需要知道其他觀察者的存在。
觀察者所做的工作其實就是在解除耦合。讓耦合雙方都依賴于抽象,而不是依賴具體。進而使得各自的變化都不會影響另一邊的變化。
參考:《大話設計模式》