JavaScript常見設計模式(面試篇)

發(fā)布訂閱模式

在“發(fā)布者-訂閱者”模式中渴逻,稱為發(fā)布者的消息發(fā)送者不會將消息編程為直接發(fā)送給稱為訂閱者的特定接受者,這意味著發(fā)布者和訂閱者不知道彼此的存在音诫。存在第三個組件裸卫,稱為消息代理或調(diào)度中心,他由發(fā)布者和訂閱者都知道纽竣,他過濾所有傳入的消息并相應地分發(fā)他們墓贿。


發(fā)布訂閱模式
        //先有訂閱茧泪,再有發(fā)布
        class PubSub{
            constructor(){
                this.sub = {}; //訂閱者名單
            }
            subscribe(type,handler){ //訂閱
                /*
                    @type : 訂閱者標識
                    @handler : 訂閱者具體訂閱內(nèi)容 
                */
                if(!this.sub[type]){ // 如果該對象不存在訂閱名單初始化一個數(shù)組
                    this.sub[type] = [];
                }
                this.sub[type].push(handler); //如果該對象存在于訂閱者名單中,就push進數(shù)組
            }
            publish(type,params){
                /*
                    @type : 訂閱者標識
                    @params : 發(fā)布時的額外參數(shù) 
                */
                if(!(type in this.sub)){
                    console.log(type+'該對象沒有訂閱')
                    return;
                }
                this.sub[type].forEach((handler)=>{ //發(fā)布 遍歷該對象下的所有訂閱的事件 進行執(zhí)行
                    handler(params)
                })
            }
            removeSub(type,handler){
                if(!(type in this.sub)){
                    console.log( type+'該對象沒有訂閱')
                    return;
                }
                if(!handler){
                    delete this.sub[type]
                }else{
                    let idx = this.sub[type].findIndex((item)=>{
                        return item == handler
                    })
                    if(idx<0){
                        console.log(type+'沒有訂閱過此事件');
                        return;
                    }
                    this.sub[type].splice(idx,1);
                    if(this.sub[type].length<=0){
                        delete this.sub[type]
                    }
                }
            }
        }

        //Example:

        function xiaoming(params){
            console.log('我是小明訂閱的事件'+params)
        }

        function xiaohong1(params){
            console.log('我是小紅訂閱的事件1'+params)
        }

        function xiaohong2(params){
            console.log('我是小紅訂閱的事件2'+params)
        }

        let pubsub = new PubSub();
        pubsub.subscribe('小明',xiaoming);

        pubsub.subscribe('小紅',xiaohong1);

        pubsub.subscribe('小紅',xiaohong2);

        pubsub.removeSub('小紅',xiaohong2)

        pubsub.publish('小明','發(fā)布了');

        pubsub.publish('小紅','發(fā)布了');

觀察者模式

觀察者模式

觀察者模式指的是一個對象(Subject)維持一系列依賴于他的對象(Observer),當有關狀態(tài)發(fā)生變更時Subject對象通知一系列Observer對象進行更新聋袋。

    class Subject{
        constructor(){
            this.obList = [];  //observer 集合
            this.state = 1; //默認狀態(tài)
        }
        getState(){  // 讀取狀態(tài)監(jiān)聽
            console.log('我被讀取了')
            return this.state;
        }
        setState(value){  //重寫狀態(tài)監(jiān)聽
            console.log('我被重寫了')
            this.state = value;
            this.notifyAllOber();  //重寫時通知所有的觀察者
        }
        attach(ob){  // 添加觀察者
            this.obList.push(ob);
        }
        notifyAllOber(){
            this.obList.forEach((ob)=>{  //核心 通知所有觀察者進行更新
                ob.update();
            })
        }
    };

    class Observer{
        constructor(name,subject){
            this.name = name;
            this.subject = subject;
            this.subject.attach(this); // 添加觀察者
        }
        update(){
            console.log(this.name,'我觀察到了變化')
        }
    } 


    let subject = new Subject();

    let observer = new Observer('我是張三',subject);

    subject.setState(2)

單例模式

單例模式是指保證一個類僅有一個實例队伟,并提供一個訪問它的全局節(jié)點。實現(xiàn)方式是先判斷實例是否存在幽勒,如果存在則直接返回嗜侮,如果不存在就創(chuàng)建之后再返回,這就確保了一個類只有一個實例對象啥容。
比如最簡單的單例模式:

var instance = null;
function getNum(num){
    if(!instance){
        return instance = num;
    }
    return instance;
}

var a = getNum(10);
var b = getNum(20)
console.log(a);//10
console.log(b);//10

這實際上就是一個單例模式锈颗,但是它的所有變量都暴露在全局不是很好,我們使用一下立即執(zhí)行函數(shù)加閉包這么寫一下咪惠。

class Num{
    constructor(num){
        this.num = num;

    }
    getNum(){
        return this.num;
    }
}

let createInstance = (function(){
    var instance = null;
    return function(num){
        if(!instance){
            instance = new Num(num)
        }
        return instance;
    }
})();

var num1 = createInstance(10);
var num2 = createInstance(20);

console.log(num1===num2) //true

策略模式

策略模式指的是定義一系列的算法击吱,把他們一個個封裝起來,并且使他們可以相互替換遥昧。
一個基于策略模式的程序至少有兩部分組成覆醇,一部分是策略類(可變),它封裝了具體算法炭臭,并負責整個具體計算過程永脓,另一部分是環(huán)境類(不變),環(huán)境類接收客戶的請求鞋仍,隨后將請求委托給某一個策略類常摧。也就是說在環(huán)境類中維持對某個策略的引用。

比如財務部門算年終獎威创,不同的身份有不同的獎金額度落午。
舉例:CEO : 10個月獎金,CTO:5個月獎金那婉,CFO:4個月獎金,COO:2個月獎金党瓮。
如果使用正常的邏輯去做那就是使用if條件判斷職位類型详炬。使用策略模式可以參考一下代碼

//策略類
var strategies = {
    "CEO":function(bonus){ //首席執(zhí)行官
        return bonus*10
    },
    "CTO":function(bonus){ //首席技術官
        return bonus*5
    },
    "CFO":function(bonus){ //首席財務官
        return bonus*4
    },
    "COO":function(bonus){ //首席運營官
        return bonus*2
    }
}

var calculateBonus = function(position,bonus){
    return strategies[position](bonus);
}
//環(huán)境類
var ceobonus = calculateBonus('CEO',50);
var ctobonus = calculateBonus('CTO',30);

console.log(ceobonus,ctobonus);//500 150

未完待續(xù)。寞奸。呛谜。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市枪萄,隨后出現(xiàn)的幾起案子隐岛,更是在濱河造成了極大的恐慌,老刑警劉巖瓷翻,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聚凹,死亡現(xiàn)場離奇詭異割坠,居然都是意外死亡,警方通過查閱死者的電腦和手機妒牙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門彼哼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人湘今,你說我怎么就攤上這事敢朱。” “怎么了摩瞎?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵拴签,是天一觀的道長。 經(jīng)常有香客問我旗们,道長蚓哩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任蚪拦,我火速辦了婚禮杖剪,結果婚禮上,老公的妹妹穿的比我還像新娘驰贷。我一直安慰自己盛嘿,他們只是感情好,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布括袒。 她就那樣靜靜地躺著次兆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锹锰。 梳的紋絲不亂的頭發(fā)上芥炭,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音恃慧,去河邊找鬼园蝠。 笑死,一個胖子當著我的面吹牛痢士,可吹牛的內(nèi)容都是我干的彪薛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼怠蹂,長吁一口氣:“原來是場噩夢啊……” “哼善延!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起城侧,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤易遣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嫌佑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豆茫,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡侨歉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了澜薄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片为肮。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖肤京,靈堂內(nèi)的尸體忽然破棺而出颊艳,到底是詐尸還是另有隱情,我是刑警寧澤忘分,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布棋枕,位于F島的核電站,受9級特大地震影響妒峦,放射性物質(zhì)發(fā)生泄漏重斑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一肯骇、第九天 我趴在偏房一處隱蔽的房頂上張望窥浪。 院中可真熱鬧,春花似錦笛丙、人聲如沸漾脂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骨稿。三九已至,卻和暖如春姜钳,著一層夾襖步出監(jiān)牢的瞬間坦冠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工哥桥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留辙浑,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓拟糕,卻偏偏與公主長得像判呕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子已卸,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355