觀察者模式git
觀察者模式是對象的行爲模式,又叫發佈-訂閱(Publish-Subscribe)模式。這是一種很是有用的設計模式,生活中咱們使用的應用程序涉及到依賴關係的很是多,那麼就很是適合用觀察者模式來實現。這種模式主要應用於對象之間一對多關係時,當一個對象發生改變時,多個對該對象有依賴的其餘對象也會跟着作出相應的改變。使用觀察者模式能夠根據須要增長或刪除對象,解決一對多對象間的耦合關係,使程序易於擴展和維護。github
下面是GitHub上的一個關於求職招聘項目的觀察者模式解析設計模式
通俗地說觀察者模式,其實就是觀察者和被觀察者之間牽扯到的一些關係。在這個招聘求職項目中,HR或者說獵頭就至關於被觀察者,咱們又稱之爲觀察目標,而求職人員如:建築師、初級工程師或者高級工程師就至關於觀察者,時刻觀察着職位的變化,一旦有新的工做信息發佈,便會立刻通知觀察者,觀察者也常常會作出相應的反應。設計
1、首先說下觀察者模式的定義:code
觀察者模式定義了對象之間的一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象都會接收到通知。對象
在本項目中,獵頭就至關於一,而求職者們就至關於多,每次獵頭這個目標對象的狀態發生變化,就會通知衆多的觀察者(求職者),求職者們通常也會作出對應的響應。blog
2、觀察者模式主要解決的問題:一方的狀態發生了變化,依賴於這一方的觀察者當即能收到通知。rem
常見的好比消息通知,向用戶發送一個消息須要同時通知到站內信、郵件、短信等多種消息,這種一對多的狀況就很是適合用觀察者模式來實現。get
例如咱們平時使用的新浪微博,在微博裏咱們會關注微博大V,只要他們發佈新的微博,咱們刷新即可以在分組或者首頁收到他們的新發布。
這裏須要注意的是,目標對象會把狀態的變化通知全部觀察者,而無論觀察者的具體身份,而他們本身也並不知道通知的這我的到底是誰。
3、觀察者模式結構圖:
4、觀察者模式通常的代碼實現:
1.目標對象與具體目標對象代碼示例
public abstract class AbstractHR { //定義一個觀察者集合用於存儲全部觀察者對象 protected Collection<ITalent> allTalents = new ArrayList<ITalent>(); //聲明抽象通知方法 public abstract void publishJob(String job); public void addTalent(ITalent talent) { //註冊方法,用於向觀察者集合中增長一個觀察者 allTalents.add(talent); } public void removeTalent(ITalent talent) { //註銷方法,用於在觀察者集合中刪除一個觀察者 allTalents.remove(talent); //具體目標類HeadHunter是實現了抽象目標類AbstractHR的一個具體子類 //其具體代碼以下所示: public class HeadHunter extends AbstractHR { public void publishJob(String job) { //調用每個觀察者的響應方法 allTalents.forEach(talent -> talent.newJob(job)); } }
2.觀察者與具體觀察者代碼實現
public interface ITalent { //聲明響應方法 void newJob(String job); } 以觀察者Architect爲例,JuniorEngineer、SeniorEngineer同理 //在具體觀察者Architect中實現了newJob ()方法 //其典型代碼以下所示: public class Architect implements ITalent { private static final Logger LOG = LoggerFactory.getLogger(Architect.class); //實現響應方法 public void newJob(String job) { LOG.info("Architect get new position {}", job); } }
5、優勢:
一、從這個項目中咱們能夠看出觀察者和被觀察者是抽象耦合的,只有輕微的關聯關係;
二、創建一套觸發機制。被觀察者一旦發生變化,便會觸發廣播通知,觀察者一旦收到通知,也會觸發相應的響應。
6、缺點:
一、若是一個被觀察者對象有不少的直接和間接的觀察者的話,那麼全部的觀察者都通知到會花費不少時間。
二、若是在觀察者和觀察目標之間有循環依賴的話,當觸發它們之間進行循環調用時,可能會致使系統崩潰。
三、觀察者模式沒法使觀察者知道所觀察的目標對象是內部變化過程,而僅僅只是知道觀察目標發生了變化。