最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TypeScript設(shè)計(jì)模式之中介者、觀察者的實(shí)現(xiàn)

 更新時(shí)間:2025年06月13日 08:28:28   作者:布魯克石  
本文主要介紹了TypeScript設(shè)計(jì)模式之中介者、觀察者的實(shí)現(xiàn),分別以滴滴打車(chē)和群聊天為例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

看看用TypeScript怎樣實(shí)現(xiàn)常見(jiàn)的設(shè)計(jì)模式,順便復(fù)習(xí)一下。
學(xué)模式最重要的不是記UML,而是知道什么模式可以解決什么樣的問(wèn)題,在做項(xiàng)目時(shí)碰到問(wèn)題可以想到用哪個(gè)模式可以解決,UML忘了可以查,思想記住就好。
這里盡量用原創(chuàng)的,實(shí)際中能碰到的例子來(lái)說(shuō)明模式的特點(diǎn)和用處。

中介者模式 Mediator

特點(diǎn):為減少對(duì)象間的互相引用而引入的一個(gè)中介對(duì)象,用來(lái)來(lái)封裝一系列對(duì)象的互相操作。

用處:當(dāng)多個(gè)對(duì)象間需要互相引用且互相頻繁操作時(shí)可以考慮中介者模式,如MVC里的Controller。

注意:中介者本身的復(fù)雜度。

下面用TypeScript簡(jiǎn)單實(shí)現(xiàn)一下中介模式:
現(xiàn)在滴滴打車(chē)其實(shí)就可以算是中介,就以這個(gè)例子吧,對(duì)象主要就是用戶,車(chē)主和平臺(tái)。

先定義用戶, 車(chē)主和中介者接口:
用戶的行為是叫車(chē),車(chē)主是接送,中介者則需要維護(hù)用戶和車(chē)主列表并且知道車(chē)的狀態(tài)和提供叫車(chē)服務(wù)。

interface Client{
    getTaxi();
    pay();
} 

interface Car{
    isWorking: boolean;

    startWork();
    finishWork();
}

interface Mediator{

    registerClient(client: Client);
    registerCar(car: Car);

    getCar(): Car;
    pay(car: Car);
    updateCarStatus(car: Car);
}

接口定義好了就可以寫(xiě)實(shí)現(xiàn)了:
用戶的實(shí)現(xiàn),持有中介者的引用,用來(lái)注冊(cè),叫車(chē)和付款,本來(lái)是沒(méi)必要存taxi的,只需要個(gè)id就可以了,具體是由中介去做匹配,不過(guò)這里為了簡(jiǎn)單就直接存對(duì)象了

class User implements Client{
    taxi: Car;

    constructor(private mediator: Mediator){
        this.mediator.registerClient(this);
    }

    getTaxi(){
        this.taxi = this.mediator.getCar();
        if(this.taxi){
            console.log('車(chē)來(lái)了');
        } else {
            console.log('沒(méi)叫到車(chē)');
        }
    }

    pay(){
        this.mediator.pay(this.taxi);
        console.log('付款');
    }
}

車(chē)主的實(shí)現(xiàn),同樣需要持有中介者引用來(lái)領(lǐng)任務(wù)和報(bào)狀態(tài)

class Taxi implements Car{
    isWorking: boolean = false;

    constructor(private mediator: Mediator){
        this.mediator.registerCar(this);
    }

    startWork(){
        console.log('有人叫車(chē)');
        this.isWorking = true;
        this.mediator.updateCarStatus(this);
    }

    finishWork(){
        console.log('送完這趟了');
        this.isWorking = false;
        this.mediator.updateCarStatus(this);
    }
}

中介的實(shí)現(xiàn),中介的作用就是提供車(chē)子服務(wù),這里為了簡(jiǎn)單沒(méi)維護(hù)用戶與車(chē)子的關(guān)系

class DiDi implements Mediator{
    private clientList: Array<Client> = [];
    private carList: Array<Car> = [];

    registerClient(client: Client){
        this.clientList.push(client);
    }

    registerCar(car: Car){
        this.carList.push(car);
    }

    getCar(): Car{
        let car = this.carList.find(o=>!o.isWorking);
        car.startWork();
        return car;
    }

    pay(car: Car){
        car.finishWork();
    }

    updateCarStatus(car: Car){
        console.log(`車(chē)子狀態(tài):${car.isWorking ? '工作' : '閑置'}`);
    }
}

跑一下看看:

let didi = new DiDi();
let taxi = new Taxi(didi);
let user = new User(didi);
user.getTaxi();
user.pay();

//結(jié)果
有人叫車(chē)
車(chē)子狀態(tài):工作
車(chē)來(lái)了
送完這趟了
車(chē)子狀態(tài):閑置
付款

這樣,用戶的目的只是叫車(chē),對(duì)中介說(shuō)聲,中介派出車(chē),用戶不管是什么車(chē),哪來(lái)的,把我送到目的地就可以了。
這就是中介者模式的作用,邏輯都在自己這里,用戶不需要管車(chē),車(chē)子也不用管用戶,一個(gè)叫車(chē),一個(gè)接單,互不干擾。
當(dāng)然也是因?yàn)檫@里聚集了各方面的邏輯,所以要注意中介者本身的復(fù)雜度,中介者本身也需要良好的設(shè)計(jì)和模式來(lái)提高代碼的可讀性和可維護(hù)性。

觀察者模式 Observer

特點(diǎn):定義了對(duì)象間的一對(duì)多關(guān)系,當(dāng)對(duì)象狀態(tài)改變時(shí),其他訂閱了這個(gè)對(duì)象的對(duì)象就會(huì)收到通知。

用處:當(dāng)一個(gè)對(duì)象狀態(tài)的改變時(shí)需要其他對(duì)象也做出響應(yīng)時(shí)可以考慮觀察者模式,如網(wǎng)絡(luò)聊天里的群。

注意:與中介者的區(qū)別。

下面用TypeScript簡(jiǎn)單實(shí)現(xiàn)一下觀察者模式:
就以上面說(shuō)的群聊天為例,群里的每個(gè)人都是注冊(cè)到群里的對(duì)象,任何一個(gè)人發(fā)了信息其他人都能收到。

先定義群和群用戶的接口:
群需要知道有哪些用戶注冊(cè)進(jìn)來(lái)了,并且在有人發(fā)消息時(shí)去通知所有注冊(cè)的人。
用戶則需要發(fā)送消息和接收消息。

interface Observer{
    name: string;

    sendMsg(msg: string);
    receiveMsg(sender: Observer, msg: string);
}

interface Subject{
    register(observer: Observer);
    unregister(observer: Observer);
    sendMsg(sender: Observer, msg: string);
}

實(shí)現(xiàn)用戶和群,用戶在發(fā)消息時(shí)需要往群里發(fā),群收到消息后通知所有注冊(cè)的人

class User implements Observer{
    constructor(public name: string, private subject: Subject){
        this.subject.register(this);
    }

    sendMsg(msg: string){
        console.log(`${this.name} 發(fā)送 ${msg}`);
        this.subject.sendMsg(this, msg);
    }

    receiveMsg(sender: Observer, msg: string){
        console.log(`${this.name} 收到來(lái)自${sender.name}的消息: ${msg} `);
    }
}

class Group implements Subject{
    private userList: Array<Observer> = [];

    register(observer: Observer){
        this.userList.push(observer);
    }

    unregister(observer: Observer){
        var index = this.userList.indexOf(observer);
        if (index > -1) {
            this.userList.splice(index, 1);
        }
    }

    sendMsg(sender: Observer, msg: string){
        console.log(`群收到${sender.name}發(fā)信息:${msg},通知所有人`);
        this.notify(sender, msg);
    }

    private notify(sender: Observer, msg: string){
        this.userList.forEach(user=>user.receiveMsg(sender, msg));
    }
}

寫(xiě)段代碼測(cè)試一下:

let group = new Group();
let jim = new User1('jim', group);
let brook = new User1('brook', group);
let lucy = new User1('lucy', group);

jim.sendMsg('hello');
lucy.sendMsg('well done!');
//結(jié)果:
jim 發(fā)送 hello
群收到j(luò)im發(fā)信息:hello,通知所有人
jim 收到來(lái)自jim的消息: hello 
brook 收到來(lái)自jim的消息: hello 
lucy 收到來(lái)自jim的消息: hello 

lucy 發(fā)送 well done!
群收到lucy發(fā)信息:well done!,通知所有人
jim 收到來(lái)自lucy的消息: well done! 
brook 收到來(lái)自lucy的消息: well done! 
lucy 收到來(lái)自lucy的消息: well done! 

只有要人發(fā)消息,所有注冊(cè)的人都會(huì)收到,跟廣播一樣。
其實(shí)觀察者模式可以做得更通用,類似一個(gè)消息中心,所有注冊(cè)的對(duì)象按照一定協(xié)議實(shí)現(xiàn)匹配事件的方法來(lái)獲取通知,消息中心不需要知道是什么類型的對(duì)象注冊(cè)了,只要實(shí)現(xiàn)這個(gè)方法,那相關(guān)事件有通知時(shí)這個(gè)方法就會(huì)被調(diào)到,這樣基本沒(méi)有耦合度,有興趣的朋友可以參考我之前寫(xiě)的一個(gè)win10開(kāi)源庫(kù):LLQNotify,就是用這種方式實(shí)現(xiàn)的。

另外,與中介者模式的區(qū)別在于:雖然都是注冊(cè)回復(fù),但觀察者是分發(fā)性的,注冊(cè)的人都能收到,而且中介者則是單一的,使用者發(fā)個(gè)請(qǐng)求,中介者回一個(gè),使用者不需要知道到底是誰(shuí)回的,中介隱藏了對(duì)象之間的交互。

到此這篇關(guān)于TypeScript設(shè)計(jì)模式之中介者、觀察者的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)TypeScript中介者、觀察者內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)

相關(guān)文章

  • JS監(jiān)聽(tīng)一個(gè)變量改變的兩種方法

    JS監(jiān)聽(tīng)一個(gè)變量改變的兩種方法

    在業(yè)務(wù)中,由于項(xiàng)目采用微前端架構(gòu),需要通過(guò)A應(yīng)用的某個(gè)值的變化對(duì)B應(yīng)用中的DOM進(jìn)行改變(如彈出一個(gè)Modal),第一個(gè)想到的可能是發(fā)布訂閱模式,其實(shí)不如將問(wèn)題縮小化,采用原生的能力去解決,本文介紹了兩種方法來(lái)使用JS監(jiān)聽(tīng)一個(gè)變量改變,需要的朋友可以參考下
    2023-11-11
  • 關(guān)于arguments,callee,caller等的測(cè)試

    關(guān)于arguments,callee,caller等的測(cè)試

    關(guān)于arguments,callee,caller等的測(cè)試...
    2006-12-12
  • javascript日期格式化方法匯總

    javascript日期格式化方法匯總

    本文給大家匯總介紹了javascript格式化日期時(shí)間的幾種常用方法,個(gè)人對(duì)最后一種個(gè)性化輸出時(shí)間比較有興趣,基本上只要項(xiàng)目中能用到都是使用這種,推薦給小伙伴們。
    2015-10-10
  • JS實(shí)現(xiàn)簡(jiǎn)易貪吃蛇游戲

    JS實(shí)現(xiàn)簡(jiǎn)易貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)簡(jiǎn)易貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • js兼容的placeholder屬性詳解

    js兼容的placeholder屬性詳解

    這篇文章詳細(xì)介紹了js兼容的placeholder屬性,有需要的朋友可以參考一下
    2013-08-08
  • javascript bom是什么及bom和dom的區(qū)別

    javascript bom是什么及bom和dom的區(qū)別

    BOM是瀏覽器對(duì)象模型,DOM是文檔對(duì)象模型,前者是對(duì)瀏覽器本身進(jìn)行操作,而后者是對(duì)瀏覽器(可看成容器)內(nèi)的內(nèi)容進(jìn)行操作。這篇文章給大家介紹javascript bom是什么及bom和dom的區(qū)別,感興趣的朋友一起學(xué)習(xí)吧
    2015-11-11
  • 微信小程序?qū)崿F(xiàn)撥打電話功能的示例代碼

    微信小程序?qū)崿F(xiàn)撥打電話功能的示例代碼

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)撥打電話功能的示例代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • js復(fù)制到剪切板的實(shí)例方法

    js復(fù)制到剪切板的實(shí)例方法

    這篇文章介紹了復(fù)制到剪切板js代碼,有需要的朋友可以參考需要
    2013-06-06
  • “不能執(zhí)行已釋放的Script代碼”錯(cuò)誤的原因及解決辦法

    “不能執(zhí)行已釋放的Script代碼”錯(cuò)誤的原因及解決辦法

    “不能執(zhí)行已釋放的Script代碼”錯(cuò)誤的原因及解決辦法...
    2007-09-09
  • 瀏覽器檢測(cè)JS代碼(兼容目前各大主流瀏覽器)

    瀏覽器檢測(cè)JS代碼(兼容目前各大主流瀏覽器)

    這篇文章主要介紹了瀏覽器檢測(cè)JS代碼,兼容目前各大主流瀏覽器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-02-02

最新評(píng)論

济源市| 永登县| 兴安县| 乌恰县| 京山县| 龙州县| 锡林浩特市| 灵宝市| 丰城市| 金门县| 浮梁县| 通河县| 旅游| 吕梁市| 依安县| 灵山县| 九台市| 黄大仙区| 郁南县| 新兴县| 赤壁市| 县级市| 左云县| 合川市| 金寨县| 大理市| 宜阳县| 富蕴县| 绿春县| 尚志市| 棋牌| 隆德县| 绥德县| 湖州市| 华亭县| 德格县| 新郑市| 浪卡子县| 四平市| 南康市| 平江县|