在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ 設(shè)計(jì)模式之中介者模式
代碼復(fù)用模式(避免篇)
S.O.L.I.D 五大原則之接口隔離原則 ISP
設(shè)計(jì)模式之狀態(tài)模式
JavaScript 核心(晉級(jí)高手必讀篇)
設(shè)計(jì)模式之建造者模式
JavaScript 與 DOM(上)——也適用于新手
設(shè)計(jì)模式之中介者模式
設(shè)計(jì)模式之裝飾者模式
設(shè)計(jì)模式之模板方法
設(shè)計(jì)模式之外觀模式
強(qiáng)大的原型和原型鏈
設(shè)計(jì)模式之構(gòu)造函數(shù)模式
揭秘命名函數(shù)表達(dá)式
深入理解J avaScript 系列(結(jié)局篇)
執(zhí)行上下文(Execution Contexts)
函數(shù)(Functions)
《你真懂 JavaScript 嗎?》答案詳解
設(shè)計(jì)模式之適配器模式
設(shè)計(jì)模式之組合模式
設(shè)計(jì)模式之命令模式
S.O.L.I.D 五大原則之單一職責(zé) SRP
編寫高質(zhì)量 JavaScript 代碼的基本要點(diǎn)
求值策略
閉包(Closures)
對(duì)象創(chuàng)建模式(上篇)
This? Yes,this!
設(shè)計(jì)模式之代理模式
變量對(duì)象(Variable Object)
S.O.L.I.D 五大原則之里氏替換原則 LSP
面向?qū)ο缶幊讨话憷碚?/span>
設(shè)計(jì)模式之單例模式
Function 模式(上篇)
S.O.L.I.D 五大原則之依賴倒置原則 DIP
設(shè)計(jì)模式之迭代器模式
立即調(diào)用的函數(shù)表達(dá)式
設(shè)計(jì)模式之享元模式
設(shè)計(jì)模式之原型模式
根本沒有“JSON 對(duì)象”這回事!
JavaScript 與 DOM(下)
面向?qū)ο缶幊讨?ECMAScript 實(shí)現(xiàn)
全面解析 Module 模式
對(duì)象創(chuàng)建模式(下篇)
設(shè)計(jì)模式之職責(zé)鏈模式
S.O.L.I.D 五大原則之開閉原則 OCP
設(shè)計(jì)模式之橋接模式
設(shè)計(jì)模式之策略模式
設(shè)計(jì)模式之觀察者模式
代碼復(fù)用模式(推薦篇)
作用域鏈(Scope Chain)
Function 模式(下篇)
設(shè)計(jì)模式之工廠模式

設(shè)計(jì)模式之中介者模式

介紹

中介者模式(Mediator),用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互。中介者使各對(duì)象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。

正文

軟件開發(fā)中,中介者是一個(gè)行為設(shè)計(jì)模式,通過提供一個(gè)統(tǒng)一的接口讓系統(tǒng)的不同部分進(jìn)行通信。一般,如果系統(tǒng)有很多子模塊需要直接溝通,都要?jiǎng)?chuàng)建一個(gè)中央控制點(diǎn)讓其各模塊通過該中央控制點(diǎn)進(jìn)行交互。中介者模式可以讓這些子模塊不需要直接溝通,而達(dá)到進(jìn)行解耦的目的。

打個(gè)比方,平時(shí)常見的機(jī)場交通控制系統(tǒng),塔臺(tái)就是中介者,它控制著飛機(jī)(子模塊)的起飛和降落,因?yàn)樗械臏贤ǘ际菑娘w機(jī)向塔臺(tái)匯報(bào)來完成的,而不是飛機(jī)之前相互溝通。中央控制系統(tǒng)就是該系統(tǒng)的關(guān)鍵,也就是軟件設(shè)計(jì)中扮演的中介者角色。

我們先用偽代碼來理解一下:

// 如下代碼是偽代碼,請(qǐng)不要過分在意代碼
// 這里app命名空間就相當(dāng)于扮演中介者的角色
var app = app || {};
// 通過app中介者來進(jìn)行Ajax請(qǐng)求
app.sendRequest = function ( options ) {
    return $.ajax($.extend({}, options);
}
// 請(qǐng)求URL以后,展示View
app.populateView = function( url, view ){
  $.when(app.sendRequest({url: url, method: 'GET'})
     .then(function(){
         //顯示內(nèi)容
     });
}
// 清空內(nèi)容
app.resetView = function( view ){
   view.html('');
}

在 JavaScript 里,中介者非常常見,相當(dāng)于觀察者模式上的消息 Bus,只不過不像觀察者那樣通過調(diào)用 pub/sub 的形式來實(shí)現(xiàn),而是通過中介者統(tǒng)一來管理,讓我們?cè)谟^察者的基礎(chǔ)上來給出一個(gè)例子:

var mediator = (function () {
    // 訂閱一個(gè)事件,并且提供一個(gè)事件觸發(fā)以后的回調(diào)函數(shù)
    var subscribe = function (channel, fn) {
        if (!mediator.channels[channel]) mediator.channels[channel] = [];
        mediator.channels[channel].push({ context: this, callback: fn });
        return this;
    },
    // 廣播事件
    publish = function (channel) {
        if (!mediator.channels[channel]) return false;
        var args = Array.prototype.slice.call(arguments, 1);
        for (var i = 0, l = mediator.channels[channel].length; i < l; i++) {
            var subscription = mediator.channels[channel][i];
            subscription.callback.apply(subscription.context, args);
        }
        return this;
    };
    return {
        channels: {},
        publish: publish,
        subscribe: subscribe,
        installTo: function (obj) {
            obj.subscribe = subscribe;
            obj.publish = publish;
        }
    };
} ());

調(diào)用代碼,相對(duì)就簡單了:

(function (Mediator) {
    function initialize() {
        // 默認(rèn)值
        mediator.name = "dudu";
        // 訂閱一個(gè)事件nameChange
        // 回調(diào)函數(shù)顯示修改前后的信息
        mediator.subscribe('nameChange', function (arg) {
            console.log(this.name);
            this.name = arg;
            console.log(this.name);
        });
    }
    function updateName() {
        // 廣播觸發(fā)事件,參數(shù)為新數(shù)據(jù)
        mediator.publish('nameChange', 'tom'); // dudu, tom
    }
    initialize(); // 初始化
    updateName(); // 調(diào)用
})(mediator);

中介者和觀察者

到這里,大家可能迷糊了,中介者和觀察者貌似差不多,有什么不同呢?其實(shí)是有點(diǎn)類似,但是我們來看看具體的描述:

觀察者模式,沒有封裝約束的單個(gè)對(duì)象,相反,觀察者 Observer 和具體類 Subject 是一起配合來維護(hù)約束的,溝通是通過多個(gè)觀察者和多個(gè)具體類來交互的:每個(gè)具體類通常包含多個(gè)觀察者,而有時(shí)候具體類里的一個(gè)觀察者也是另一個(gè)觀察者的具體類。

而中介者模式所做的不是簡單的分發(fā),卻是扮演著維護(hù)這些約束的職責(zé)。

中介者和外觀模式

很多人可能也比較迷糊中介者和外觀模式的區(qū)別,他們都是對(duì)現(xiàn)有各模塊進(jìn)行抽象,但有一些微妙的區(qū)別。

中介者所做的是在模塊之間進(jìn)行通信,是多向的,但外觀模式只是為某一個(gè)模塊或系統(tǒng)定義簡單的接口而不添加額外的功能。系統(tǒng)中的其它模塊和外觀模式這個(gè)概念沒有直接聯(lián)系,可以認(rèn)為是單向性。

完整的例子

再給出一個(gè)完整的例子:

<!doctype html>
<html lang="en">
<head>
    <title>JavaScript Patterns</title>
    <meta charset="utf-8">
</head>
<body>
<div id="results"></div>
    <script>
        function Player(name) {
            this.points = 0;
            this.name = name;
        }
        Player.prototype.play = function () {
            this.points += 1;
            mediator.played();
        };
        var scoreboard = {
            // 顯示內(nèi)容的容器
            element: document.getElementById('results'),
            // 更新分?jǐn)?shù)顯示
            update: function (score) {
                var i, msg = '';
                for (i in score) {
                    if (score.hasOwnProperty(i)) {
                        msg += '<p><strong>' + i + '<\/strong>: ';
                        msg += score[i];
                        msg += '<\/p>';
                    }
                }
                this.element.innerHTML = msg;
            }
        };
        var mediator = {
            // 所有的player
            players: {},
            // 初始化
            setup: function () {
                var players = this.players;
                players.home = new Player('Home');
                players.guest = new Player('Guest');
            },
            // play以后,更新分?jǐn)?shù)
            played: function () {
                var players = this.players,
                    score = {
                        Home: players.home.points,
                        Guest: players.guest.points
                    };
                scoreboard.update(score);
            },
            // 處理用戶按鍵交互
            keypress: function (e) {
                e = e || window.event; // IE
                if (e.which === 49) { // 數(shù)字鍵 "1"
                    mediator.players.home.play();
                    return;
                }
                if (e.which === 48) { // 數(shù)字鍵 "0"
                    mediator.players.guest.play();
                    return;
                }
            }
        };
        // go!
        mediator.setup();
        window.onkeypress = mediator.keypress;
        // 30秒以后結(jié)束
        setTimeout(function () {
            window.onkeypress = null;
            console.log('Game over!');
        }, 30000);
    </script>
</body>
</html>

總結(jié)

中介者模式一般應(yīng)用于一組對(duì)象已定義良好但是以復(fù)雜的方式進(jìn)行通信的場合,一般情況下,中介者模式很容易在系統(tǒng)中使用,但也容易在系統(tǒng)里誤用,當(dāng)系統(tǒng)出現(xiàn)了多對(duì)多交互復(fù)雜的對(duì)象群時(shí),先不要急于使用中介者模式,而是要思考一下是不是系統(tǒng)設(shè)計(jì)有問題。

另外,由于中介者模式把交互復(fù)雜性變成了中介者本身的復(fù)雜性,所以說中介者對(duì)象會(huì)比其它任何對(duì)象都復(fù)雜。