亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java設(shè)計(jì)模式中觀察者模式詳解

 更新時(shí)間:2022年11月24日 08:47:31   作者:lpf_wei  
觀察者模式是極其重要的一個(gè)設(shè)計(jì)模式,也是我?guī)啄觊_(kāi)發(fā)過(guò)程中使用最多的設(shè)計(jì)模式,本文首先概述觀察者模式的基本概念和Demo實(shí)現(xiàn),接著是觀察者模式在Java和Spring中的應(yīng)用,最后是對(duì)觀察者模式的應(yīng)用場(chǎng)景和優(yōu)缺點(diǎn)進(jìn)行總結(jié)

編程是一門(mén)藝術(shù),大批量的改動(dòng)顯然是非常丑陋的做法,用心的琢磨寫(xiě)的代碼讓它變的更美觀。

在現(xiàn)實(shí)世界中,許多對(duì)象并不是獨(dú)立存在的,其中一個(gè)對(duì)象的行為發(fā)生改變可能會(huì)導(dǎo)致一個(gè)或者多個(gè)其他對(duì)象的行為也發(fā)生改變。例如,某種商品的物價(jià)上漲時(shí)會(huì)導(dǎo)致部分商家高興,而消費(fèi)者傷心;還有,當(dāng)我們開(kāi)車(chē)到交叉路口時(shí),遇到紅燈會(huì)停,遇到綠燈會(huì)行。股票價(jià)格與股民、微信公眾號(hào)與微信用戶、天氣預(yù)報(bào)與聽(tīng)眾等。

在軟件世界也是這樣,例如MVC 模式中的模型與視圖的關(guān)系;事件模型中的事件源與事件處理者。所有這些,如果用觀察者模式來(lái)實(shí)現(xiàn)就非常方便。

1.觀察者設(shè)計(jì)模式定義

觀察者(Observer)模式:指多個(gè)對(duì)象間存在一對(duì)多的依賴(lài)關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象都得到通知并被自動(dòng)更新。這種模式有時(shí)又稱(chēng)作發(fā)布-訂閱模式、模型-視圖模式,它是對(duì)象行為型模式。

2.觀察者設(shè)計(jì)模式優(yōu)點(diǎn)與不足

觀察者模式是一種對(duì)象行為型模式,其主要優(yōu)點(diǎn):

  • 降低了目標(biāo)與觀察者之間的耦合關(guān)系,兩者之間是抽象耦合關(guān)系。符合依賴(lài)倒置原則。
  • 目標(biāo)與觀察者之間建立了一套觸發(fā)機(jī)制。

它的主要不足:

  • 目標(biāo)與觀察者之間的依賴(lài)關(guān)系并沒(méi)有完全解除,而且有可能出現(xiàn)循環(huán)引用。
  • 當(dāng)觀察者對(duì)象很多時(shí),通知的發(fā)布會(huì)花費(fèi)很多時(shí)間,影響程序的效率。

3.觀察者設(shè)計(jì)模式實(shí)現(xiàn)思路

實(shí)現(xiàn)觀察者模式時(shí)要注意具體目標(biāo)對(duì)象和具體觀察者對(duì)象之間不能直接調(diào)用,否則將使兩者之間緊密耦合起來(lái),這違反了面向?qū)ο蟮脑O(shè)計(jì)原則。

觀察者模式的主要角色如下。

  • 抽象主題(Subject)角色:也叫抽象目標(biāo)類(lèi),它提供了一個(gè)用于保存觀察者對(duì)象的聚集類(lèi)和增加、刪除觀察者對(duì)象的方法,以及通知所有觀察者的抽象方法。
  • 具體主題(Concrete Subject)角色:也叫具體目標(biāo)類(lèi),它實(shí)現(xiàn)抽象目標(biāo)中的通知方法,當(dāng)具體主題的內(nèi)部狀態(tài)發(fā)生改變時(shí),通知所有注冊(cè)過(guò)的觀察者對(duì)象。
  • 抽象觀察者(Observer)角色:它是一個(gè)抽象類(lèi)或接口,它包含了一個(gè)更新自己的抽象方法,當(dāng)接到具體主題的更改通知時(shí)被調(diào)用。
  • 具體觀察者(Concrete Observer)角色:實(shí)現(xiàn)抽象觀察者中定義的抽象方法,以便在得到目標(biāo)的更改通知時(shí)更新自身的狀態(tài)。

4.觀察者設(shè)計(jì)模式應(yīng)用實(shí)例

/**
 * 觀察者
 */
public interface Observer {
    /**
     * 更新
     */
    void update();
}
/**
 * 注意事項(xiàng)  被觀察者  被觀察者發(fā)出通知
 */
public abstract class Attentions {
    /**
     * 觀察者列表
     */
    protected List<Observer> observers = new ArrayList();
    /**
     * 添加觀察者
     * @param observer
     */
    public void add(Observer observer) {
        observers.add(observer);
    }
    /**
     * 取消關(guān)注
     * @param observer
     */
    public void remove(Observer observer) {
        observers.remove(observer);
    }
    /**
     * 被觀察者發(fā)出通知 通知所有觀察者  觀察者可以做出相應(yīng)的行為
     */
    public abstract void notifyObservers();
}
/**
 * 觀察者  各種各樣的觀察者
 */
public class SoulMasterObserver implements Observer {
    private String name;
    public SoulMasterObserver(String name){
        this.name = name;
    }
    /**
     * 觀察者接收到通知做一些事情
     */
    @Override
    public void update() {
        System.out.println(name + "收到作戰(zhàn)通知,趕往嘉陵關(guān)");
    }
}
public class MangoAttention extends Attentions{
    @Override
    public void notifyObservers() {
        //遍歷觀察者集合
        for(Observer obs : observers) {
            obs.update();
        }
    }
    /*通知觀察者*/
    public void perform(){
        this.notifyObservers();
    }
}
public class ObserverClient {
    public static void main(String[] args) {
        MangoAttention attentions = new MangoAttention();//目標(biāo)
        attentions.add(new SoulMasterObserver("唐三"));
        attentions.add(new SoulMasterObserver("馬紅俊"));
        attentions.add(new SoulMasterObserver("小舞"));
        attentions.add(new SoulMasterObserver("寧榮榮"));
        attentions.perform();
    }
}

觀察者設(shè)計(jì)模式,首先需要定義一個(gè)觀察者的接口,這個(gè)接口定義了做什么一個(gè)行為,

然后定義一個(gè)被觀察者,這個(gè)里邊包含了一個(gè)觀察者的集合以及添加和刪除觀察者的方法以及一個(gè)通知的方法。

然后定義具體的觀察者,實(shí)現(xiàn)具體的行動(dòng),當(dāng)被通知之后就可以行動(dòng)了。

具體的被觀察者實(shí)現(xiàn)通知的一個(gè)方法,遍歷所以的觀察者,通知觀察者執(zhí)行動(dòng)作。

另外由于jkd本身提供了用于支持觀察者設(shè)計(jì)模式實(shí)現(xiàn)的兩個(gè)類(lèi),可以不用自己實(shí)現(xiàn)接口和抽象類(lèi),直接借助jdk提供的Observer和Obserable就可以,jdk提供的做的更好線程安全啥的都做了。

public class SoulMaster implements Observer {
    private String name;
    public SoulMaster(String name){
        this.name = name;
    }
    @Override
    public void update(Observable o, Object arg) {
        System.out.println(name + "收到作戰(zhàn)通知,趕往嘉陵關(guān)");
    }
}
public class War extends Observable {
    private String name;
    public War(String name){
        this.name = name;
    }
    public void perform(){
        /*先設(shè)置改變*/
        this.setChanged();
        /*然后通知*/
        this.notifyObservers();
    }
}
public class JdkObserverClient {
    public static void main(String[] args) {
        War war = new War(":戰(zhàn)爭(zhēng)");
        war.addObserver(new SoulMaster("唐三"));
        war.addObserver(new SoulMaster("馬紅俊"));
        war.addObserver(new SoulMaster("小舞"));
        war.addObserver(new SoulMaster("寧榮榮"));
        war.perform();
    }
}

可見(jiàn)通過(guò)jdk提供的兩個(gè)類(lèi)實(shí)現(xiàn)觀察者,更加簡(jiǎn)潔。

5.觀察者設(shè)計(jì)模式模式的應(yīng)用場(chǎng)景

在軟件系統(tǒng)中,當(dāng)系統(tǒng)一方行為依賴(lài)另一方行為的變動(dòng)時(shí),可使用觀察者模式松耦合聯(lián)動(dòng)雙方,使得一方的變動(dòng)可以通知到感興趣的另一方對(duì)象,從而讓另一方對(duì)象對(duì)此做出響應(yīng)。

觀察者模式適合以下幾種情形:

  • 對(duì)象間存在一對(duì)多關(guān)系,一個(gè)對(duì)象的狀態(tài)發(fā)生改變會(huì)影響其他對(duì)象。
  • 當(dāng)一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴(lài)于另一方面時(shí),可將這二者封裝在獨(dú)立的對(duì)象中以使它們可以各自獨(dú)立地改變和復(fù)用。
  • 實(shí)現(xiàn)類(lèi)似廣播機(jī)制的功能,不需要知道具體收聽(tīng)者,只需分發(fā)廣播,系統(tǒng)中感興趣的對(duì)象會(huì)自動(dòng)接收該廣播。
  • 多層級(jí)嵌套使用,形成一種鏈?zhǔn)接|發(fā)機(jī)制,使得事件具備跨域(跨越兩種觀察者類(lèi)型)通知。

到此這篇關(guān)于Java設(shè)計(jì)模式中觀察者模式詳解的文章就介紹到這了,更多相關(guān)Java觀察者模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java開(kāi)發(fā)Dubbo負(fù)載均衡與集群容錯(cuò)示例詳解

    java開(kāi)發(fā)Dubbo負(fù)載均衡與集群容錯(cuò)示例詳解

    這篇文章主要為大家介紹了java開(kāi)發(fā)Dubbo負(fù)載均衡與集群容錯(cuò)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • Sharding Jdbc批量操作引發(fā)fullGC解決

    Sharding Jdbc批量操作引發(fā)fullGC解決

    這篇文章主要為大家介紹了Sharding Jdbc批量操作引發(fā)fullGC解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • servlet簡(jiǎn)單實(shí)現(xiàn)文件下載的方法

    servlet簡(jiǎn)單實(shí)現(xiàn)文件下載的方法

    這篇文章主要介紹了servlet簡(jiǎn)單實(shí)現(xiàn)文件下載的方法,涉及基于servlet技術(shù)實(shí)現(xiàn)流形式文件傳輸?shù)南嚓P(guān)操作技巧,需要的朋友可以參考下
    2016-12-12
  • Java并發(fā)編程中的synchronized關(guān)鍵字詳細(xì)解讀

    Java并發(fā)編程中的synchronized關(guān)鍵字詳細(xì)解讀

    這篇文章主要介紹了Java并發(fā)編程中的synchronized關(guān)鍵字詳細(xì)解讀,在Java早期版本中,synchronized 屬于 重量級(jí)鎖,效率低下,這是因?yàn)楸O(jiān)視器鎖(monitor)是依賴(lài)于底層的操作系統(tǒng)的Mutex Lock來(lái)實(shí)現(xiàn)的,Java 的線程是映射到操作系統(tǒng)的原生線程之上的,需要的朋友可以參考下
    2023-12-12
  • MyBatis如何通過(guò)xml方式實(shí)現(xiàn)SaveOrUpdate

    MyBatis如何通過(guò)xml方式實(shí)現(xiàn)SaveOrUpdate

    這篇文章主要講如何通過(guò)xml方式實(shí)現(xiàn)SaveOrUpdate,但是仍然建議在Service中實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-06-06
  • 關(guān)于RedisTemplate之opsForValue的使用說(shuō)明

    關(guān)于RedisTemplate之opsForValue的使用說(shuō)明

    這篇文章主要介紹了關(guān)于RedisTemplate之opsForValue的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • java根據(jù)本地IP獲取mac地址的方法

    java根據(jù)本地IP獲取mac地址的方法

    這篇文章主要為大家詳細(xì)介紹了java根據(jù)本地IP獲取mac地址的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Eclipse/MyEclipse轉(zhuǎn)IntelliJ IDEA完全攻略(圖文)

    Eclipse/MyEclipse轉(zhuǎn)IntelliJ IDEA完全攻略(圖文)

    這篇文章主要介紹了Eclipse/MyEclipse轉(zhuǎn)IntelliJ IDEA完全攻略(圖文),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • IDEA離線安裝maven helper插件的圖文教程

    IDEA離線安裝maven helper插件的圖文教程

    本文通過(guò)圖文并茂的形式給大家介紹IDEA離線安裝maven helper插件,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-08-08
  • 關(guān)于二分法查找Java的實(shí)現(xiàn)及解析

    關(guān)于二分法查找Java的實(shí)現(xiàn)及解析

    這篇文章主要介紹了關(guān)于二分法查找Java的實(shí)現(xiàn)及解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07

最新評(píng)論