設(shè)計模式筆記——觀察者模式

什么是觀察者模式(Observer Pattern)

觀察者模式定義了對象之間的一對多依賴。這樣一來焦读,當一個對象狀態(tài)改變時它的所有依賴者都會收到通知并自動更新。

觀察者模式的應(yīng)用

觀察者模式的應(yīng)用很廣泛。例如在Android開發(fā)時需要對控件注冊事件監(jiān)聽创淡,控件屬于被觀察者另绩,在該控件上所注冊的事件屬于觀察者儒陨,當控件發(fā)生變化時相應(yīng)的監(jiān)聽事件會立即做出回應(yīng)。我想大家都有自己喜歡的微信公眾號笋籽,其實微信公眾號的訂閱蹦漠、推送很好的體現(xiàn)了觀察者模式。當我們想及時獲得自己喜歡的公號的更新就得先關(guān)注它车海,然后公號有更新時會第一時間通知它的每一位仰慕者笛园。
設(shè)計模式來源于生活,細細品味生活能夠更好的去理解設(shè)計模式侍芝。

觀察者模式所涉及的 OO 設(shè)計原則

  • 實現(xiàn)交互對象之間的松耦合研铆。

  • 何為對象之間的松耦合?松耦合就是兩個對象可以交互州叠,但是不太清楚彼此的細節(jié)棵红。更通俗一點來說就是你和你的手機就是松耦合的,你可以很輕松的玩耍你的手機(你和手機進行者交互)咧栗,但你并知道手機內(nèi)部的實現(xiàn)逆甜,手機也更不知道使用者是誰啦。

  • 封裝變化致板。

  • 多用組合交煞,少用繼承。

  • 針對接口編程斟或,不針對實現(xiàn)編程素征。

觀察者模式 Java 代碼實現(xiàn)及分析

  • 分析

  • 此 Demo 借用模擬微信公眾號簡單地實現(xiàn)了觀察者模式。

  • WeChatPublicNumber 是所有微信公眾號的公共接口萝挤,所有具體的微信公眾號都要實現(xiàn)此接口御毅,CnboJavaDev 就是一個實現(xiàn)此接口的微信公眾號(我決定了,我以后的微信公眾號就叫此名了怜珍,嘻嘻)亚享。WeChatPublicNumber 提供了用戶訂閱 registerUser(User user) 和取消訂閱的方法 removeUser(User user),還有推送更新的方法 notifyUsers()绘面。

  • User 是所有用戶的公共接口欺税,此接口提供了更新方法 update() 和文章閱讀方法 readArticle() (此方法主要用來測試打印)侈沪。Facebook 和 Google 實現(xiàn)了 User 接口。

  • TestObserver 用于對此 Demo 的測試晚凿。

  • Demo 的 UML 類圖

observer demo uml
  • WeChatPublicNumber.java
/**
 * WeChatPublicNumber(微信公眾號接口)
 * @author cnbo
 */
public interface WeChatPublicNumber {
    //用戶訂閱公號
    public void registerUser(User user);
    
    //用戶取消訂閱
    public void removeUser(User user);
    
    //向所有訂閱用戶推送更新
    public void notifyUsers();
}
  • Article.java
/**
 * 文章(別亂想哦)
 * @author cnbo
 * 
 */
public class Article {
    /** 文章的標題 */
    private String title;

    /** 文章的作者 */
    private String author;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
    
    @Override
    public String toString() {
        return "title:" + title + "; author:" + author;
    }
}
  • User.java
/**
 * 微信用戶接口
 * @author cnbo
 *
 */
public interface User {
    public void update(Article article);
    
    public void readAritcle();
}
  • CnboJavaDev.java
/**
 * CnboJavaDev是一個實現(xiàn)了接口WeChatPublicNumber
 * 的具體的公號
 * @author cnbo
 */
public class CnboJavaDev implements WeChatPublicNumber {
    private Article article;
    private List<User> users;

    public CnboJavaDev() {
        users = new ArrayList<>();
    }
    
    @Override
    public void registerUser(User user) {
        if (users != null) {
            users.add(user);
        }
    }
    
    @Override
    public void removeUser(User user) {
        if (users != null && users.contains(user)) {
            users.remove(user);
        }
    }

    //發(fā)布文章
    public void publishArticle() {
        notifyUsers();
    }
    
     //向所有訂閱者推送文章
    @Override
    public void notifyUsers() {
        if (users == null) {
            return;
        }
        
        for (User user : users) {
            user.update(article);
            user.readAritcle();
        }
    }
    
    public void addArticle(Article article) {
        this.article = article;
        publishArticle();
    }
}
  • Facebook.java
/**
 * 微信用戶Facebook
 * @author cnbo
 *
 */
public class Facebook implements User {
    private Article article;
    private WeChatPublicNumber weChatPublicNumber;
    
    public Facebook(WeChatPublicNumber weChatPublicNumber) {
        this.weChatPublicNumber = weChatPublicNumber;
        weChatPublicNumber.registerUser(this);
    }

    @Override
    public void update(Article article) {
        this.article = article;
    }

    @Override
    public void readAritcle() {
        System.out.println("facebook read " + article);
    }
}
  • Google.java
/**
 * 微信用戶Google
 * @author cnbo
 */
public class Google implements User {
    private Article article;
    private WeChatPublicNumber weChatPublicNumber;
    
    public Google(WeChatPublicNumber weChatPublicNumber) {
        this.weChatPublicNumber = weChatPublicNumber;
        weChatPublicNumber.registerUser(this);
    }

    @Override
    public void update(Article article) {
        this.article = article;
    }

    @Override
    public void readAritcle() {
        System.out.println("google read " + article);
    }
}
  • TestObserver.java
/*
 * 測試觀察者模式
 * @author cnbo
 */
public class TestObserver {
    public static void main(String[] args) {
        CnboJavaDev cnboJavaDev = new CnboJavaDev();
        //facebook和google關(guān)注了cnboJavaDev(如果我真被facebook和google
        //關(guān)注了亭罪,那我會興奮成神經(jīng)的,哈哈)
        User facebook =  new Facebook(cnboJavaDev);
        User google = new Google(cnboJavaDev);
        Article article1 = getArticle("學習筆記之單例設(shè)計模式", "cnbo");
        //cnboJavaDev發(fā)布一篇新文章article1歼秽,同時facebook和google
        //都接收到了更新应役,然后他哥倆有滋有味的讀者cnbo的文章。
        cnboJavaDev.addArticle(article1);
        Article article2 = getArticle("學習筆記之策略設(shè)計模式", "cnbo");
        cnboJavaDev.addArticle(article2);
    }
    
    public static Article getArticle(String title, String author) {
        Article article = new Article();
        article.setTitle(title);
        article.setAuthor(author);
        
        return article;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末燥筷,一起剝皮案震驚了整個濱河市箩祥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肆氓,老刑警劉巖袍祖,帶你破解...
    沈念sama閱讀 211,423評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異谢揪,居然都是意外死亡蕉陋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評論 2 385
  • 文/潘曉璐 我一進店門拨扶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凳鬓,“玉大人,你說我怎么就攤上這事患民∷蹙伲” “怎么了?”我有些...
    開封第一講書人閱讀 157,019評論 0 348
  • 文/不壞的土叔 我叫張陵匹颤,是天一觀的道長蚁孔。 經(jīng)常有香客問我,道長惋嚎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,443評論 1 283
  • 正文 為了忘掉前任站刑,我火速辦了婚禮另伍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绞旅。我一直安慰自己摆尝,他們只是感情好,可當我...
    茶點故事閱讀 65,535評論 6 385
  • 文/花漫 我一把揭開白布因悲。 她就那樣靜靜地躺著堕汞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晃琳。 梳的紋絲不亂的頭發(fā)上讯检,一...
    開封第一講書人閱讀 49,798評論 1 290
  • 那天琐鲁,我揣著相機與錄音,去河邊找鬼人灼。 笑死围段,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的投放。 我是一名探鬼主播奈泪,決...
    沈念sama閱讀 38,941評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼灸芳!你這毒婦竟也來了涝桅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,704評論 0 266
  • 序言:老撾萬榮一對情侶失蹤烙样,失蹤者是張志新(化名)和其女友劉穎冯遂,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體误阻,經(jīng)...
    沈念sama閱讀 44,152評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡债蜜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,494評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了究反。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寻定。...
    茶點故事閱讀 38,629評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖精耐,靈堂內(nèi)的尸體忽然破棺而出狼速,到底是詐尸還是另有隱情,我是刑警寧澤卦停,帶...
    沈念sama閱讀 34,295評論 4 329
  • 正文 年R本政府宣布向胡,位于F島的核電站,受9級特大地震影響惊完,放射性物質(zhì)發(fā)生泄漏僵芹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,901評論 3 313
  • 文/蒙蒙 一小槐、第九天 我趴在偏房一處隱蔽的房頂上張望拇派。 院中可真熱鬧,春花似錦凿跳、人聲如沸件豌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茧彤。三九已至,卻和暖如春疆栏,著一層夾襖步出監(jiān)牢的瞬間曾掂,已是汗流浹背惫谤。 一陣腳步聲響...
    開封第一講書人閱讀 31,978評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遭殉,地道東北人石挂。 一個月前我還...
    沈念sama閱讀 46,333評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像险污,于是被迫代替她去往敵國和親痹愚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,499評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理蛔糯,服務(wù)發(fā)現(xiàn)拯腮,斷路器,智...
    卡卡羅2017閱讀 134,631評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法蚁飒,類相關(guān)的語法动壤,內(nèi)部類的語法,繼承相關(guān)的語法淮逻,異常的語法琼懊,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,441評論 5 6
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,763評論 25 707
  • 概要: 1.如果有色彩理論更好(美術(shù)功底) 2.玩色彩的方法 內(nèi)容 學習配色的三個方法 1.顏料涂鴉 買一點顏料,...
    波羅蜜啊閱讀 1,102評論 0 0