??觀察者模式是設(shè)計(jì)模式種較簡(jiǎn)單的智政,且挺常用的一種掏缎,主要用在事件發(fā)布系統(tǒng)中阐斜,當(dāng)被觀察者狀態(tài)改變的時(shí)候衫冻,立即通知觀察者。
角色
抽象被觀察者角色:把所有對(duì)觀察者對(duì)象的引用保存在一個(gè)集合中谒出,每個(gè)被觀察者角色都可以有任意數(shù)量的觀察者隅俘。被觀察者提供一個(gè)接口邻奠,可以增加和刪除觀察者角色。一般用一個(gè)抽象類和接口來(lái)實(shí)現(xiàn)为居。
抽象觀察者角色:為所有具體的觀察者定義一個(gè)接口碌宴,在得到主題的通知時(shí)更新自己。
具體被觀察者角色:在被觀察者內(nèi)部狀態(tài)改變時(shí)蒙畴,給所有登記過(guò)的觀察者發(fā)出通知贰镣。具體被觀察者角色通常用一個(gè)子類實(shí)現(xiàn)。
具體觀察者角色:該角色實(shí)現(xiàn)抽象觀察者角色所要求的更新接口膳凝,以便使本身的狀態(tài)與主題的狀態(tài)相協(xié)調(diào)碑隆。通常用一個(gè)子類實(shí)現(xiàn)。如果需要蹬音,具體觀察者角色可以保存一個(gè)指向具體主題角色的引用上煤。
舉個(gè)例子
日常開(kāi)發(fā)的時(shí)候,產(chǎn)品一有更改著淆,就會(huì)通知程序員修改代碼劫狠。
抽象的觀察者
public interface Watcher {
void update();
}
抽象被觀察者
public interface Watched {
void addWatched(Watcher watcher);
void removeWatched(Watcher watcher);
void notifyWatcher();
}
具體被觀察者
public class ProductorManager implements Watched {
private Set<Watcher> watchers = new HashSet<>();
@Override
public void addWatched(Watcher watcher) {
watchers.add(watcher);
}
@Override
public void removeWatched(Watcher watcher) {
watchers.remove(watcher);
}
@Override
public void notifyWatcher() {
for(Watcher watcher:watchers){
watcher.update();
}
}
}
具體觀察者
public class CoderManA implements Watcher{
@Override
public void update() {
System.out.println("Man A got");
}
}
public class CoderManB implements Watcher{
@Override
public void update() {
System.out.println("Man B got");
}
}
測(cè)試類
public class test {
public static void main(String args[]){
ProductorManager manager = new ProductorManager();
manager.addWatched(new CoderManA());
manager.addWatched(new CoderManB());
manager.notifyWatcher();
}
}
The End
??例子中沒(méi)有關(guān)于數(shù)據(jù)和狀態(tài)的變化通知,只是簡(jiǎn)單通知到各個(gè)觀察者永部,告訴他們被觀察者改變了独泞。
??觀察者模式在關(guān)于目標(biāo)角色、觀察者角色通信的具體實(shí)現(xiàn)中扬舒,有兩個(gè)版本阐肤。
一種情況便是目標(biāo)角色在發(fā)生變化后凫佛,僅僅告訴觀察者角色“我變化了”讲坎,觀察者角色如果想要知道具體的變化細(xì)節(jié),則就要自己從目標(biāo)角色的接口中得到愧薛。這種模式被很形象的稱為:拉模式——就是說(shuō)變化的信息是觀察者角色主動(dòng)從目標(biāo)角色中“拉”出來(lái)的晨炕。
還有一種方法,那就是“推模式”毫炉,當(dāng)目標(biāo)角色改變時(shí)瓮栗,通知你發(fā)生變化的同時(shí),通過(guò)一個(gè)參數(shù)將變化的細(xì)節(jié)傳遞到觀察者角色中去瞄勾。這就是——管你要不要费奸,先給你。
這兩種模式的使用进陡,取決于系統(tǒng)設(shè)計(jì)時(shí)的需要愿阐。如果目標(biāo)角色比較復(fù)雜,并且觀察者角色進(jìn)行更新時(shí)必須得到一些具體變化的信息趾疚,則“推模式”比較合適缨历。如果目標(biāo)角色比較簡(jiǎn)單以蕴,則“拉模式”就很合適。