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

深入理解JavaScript系列(36):設(shè)計模式之中介者模式詳解

 更新時間:2015年03月04日 08:46:43   投稿:junjie  
這篇文章主要介紹了深入理解JavaScript系列(36):設(shè)計模式之中介者模式詳解,中介者模式(Mediator)是指用一個中介對象來封裝一系列的對象交互,需要的朋友可以參考下

介紹

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

主要內(nèi)容來自:http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#mediatorpatternjavascript

正文

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

打個比方,平時常見的機場交通控制系統(tǒng),塔臺就是中介者,它控制著飛機(子模塊)的起飛和降落,因為所有的溝通都是從飛機向塔臺匯報來完成的,而不是飛機之前相互溝通。中央控制系統(tǒng)就是該系統(tǒng)的關(guān)鍵,也就是軟件設(shè)計中扮演的中介者角色。

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

復制代碼 代碼如下:

// 如下代碼是偽代碼,請不要過分在意代碼
// 這里app命名空間就相當于扮演中介者的角色
var app = app || {};
 
// 通過app中介者來進行Ajax請求
app.sendRequest = function ( options ) {
    return $.ajax($.extend({}, options);
}
 
// 請求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里,中介者非常常見,相當于觀察者模式上的消息Bus,只不過不像觀察者那樣通過調(diào)用pub/sub的形式來實現(xiàn),而是通過中介者統(tǒng)一來管理,讓我們在觀察者的基礎(chǔ)上來給出一個例子:
復制代碼 代碼如下:

var mediator = (function () {
    // 訂閱一個事件,并且提供一個事件觸發(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)用代碼,相對就簡單了:
復制代碼 代碼如下:

(function (Mediator) {

    function initialize() {

        // 默認值
        mediator.name = "dudu";

        // 訂閱一個事件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);


中介者和觀察者

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

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

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

中介者和外觀模式

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

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


再給出一個完整的例子:

復制代碼 代碼如下:

<!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'),

            // 更新分數(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以后,更新分數(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é)

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

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

相關(guān)文章

  • 關(guān)于不同頁面之間實現(xiàn)參數(shù)傳遞的幾種方式討論

    關(guān)于不同頁面之間實現(xiàn)參數(shù)傳遞的幾種方式討論

    下面小編就為大家?guī)硪黄P(guān)于不同頁面之間實現(xiàn)參數(shù)傳遞的幾種方式討論。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • 詳解javascript中var與ES6規(guī)范中l(wèi)et、const區(qū)別與用法

    詳解javascript中var與ES6規(guī)范中l(wèi)et、const區(qū)別與用法

    es6剛流行那會,我只知道var即將退出歷史舞臺,取而代之的是let和const,卻不知道var有什么缺陷,為什么會被取代。今天在網(wǎng)上看到一段視頻,解答了我的疑惑
    2020-01-01
  • Javascript中Array.prototype.map()詳解

    Javascript中Array.prototype.map()詳解

    map 方法會給原數(shù)組中的每個元素都按順序調(diào)用一次 callback 函數(shù)。callback 每次執(zhí)行后的返回值組合起來形成一個新數(shù)組。 callback 函數(shù)只會在有值的索引上被調(diào)用;那些從來沒被賦過值或者使用 delete 刪除的索引則不會被調(diào)用。
    2014-10-10
  • 一起來看看js對象和事件的學習筆記

    一起來看看js對象和事件的學習筆記

    這篇文章主要為大家詳細介紹了js對象和事件學習筆記,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • HTML form表單提交方法案例詳解

    HTML form表單提交方法案例詳解

    這篇文章主要介紹了HTML form表單提交方法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • RGB和YUV 多媒體編程基礎(chǔ)詳細介紹

    RGB和YUV 多媒體編程基礎(chǔ)詳細介紹

    這篇文章主要介紹了 RGB和YUV 多媒體編程基礎(chǔ)詳細介紹的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • 關(guān)于JavaScript中string 的replace

    關(guān)于JavaScript中string 的replace

    在使用JavaScript對字符串進行處理的時候我們經(jīng)常會用到replace方法,很簡單的一個方法,以前一直不以為意,直到今天看JavaScript語言精粹的時候讀到了一個有趣的小例子的時候,并不是十分理解,了解了一下replace的用法才明白,原來replace不像想象中的那么簡單
    2013-04-04
  • JS鍵盤的鍵碼(event.keyCode)圖片版

    JS鍵盤的鍵碼(event.keyCode)圖片版

    js獲取鍵盤按鍵的鍵碼event.keyCode,下面則是鍵盤的鍵碼分布,記錄一下,以備不時之需
    2013-01-01
  • Javascript學習筆記之數(shù)組的構(gòu)造函數(shù)

    Javascript學習筆記之數(shù)組的構(gòu)造函數(shù)

    這篇文章主要介紹了Javascript數(shù)組的構(gòu)造函數(shù)及常見的操作,講解的十分詳細,這里推薦給大家
    2014-11-11
  • javascript新手語法小結(jié)

    javascript新手語法小結(jié)

    我們不論用什么程序,經(jīng)常會用到的js代碼,建議大家收藏好,方便以后使用
    2008-06-06

最新評論

望城县| 宣汉县| 高平市| 桃园市| 全椒县| 南宁市| 云阳县| 阳城县| 潞西市| 临高县| 商河县| 勐海县| 嘉祥县| 营口市| 柏乡县| 钟山县| 龙井市| 措美县| 永福县| 乌海市| 新建县| 双江| 巴南区| 蚌埠市| 津市市| 兴隆县| 铜梁县| 丰城市| 孝昌县| 乐都县| 鄯善县| 巴林左旗| 郴州市| 嘉善县| 金溪县| 襄垣县| 景洪市| 南昌县| 股票| 额尔古纳市| 临湘市|