中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript設計模式之中介者模式的示例分析

發布時間:2021-04-26 14:43:34 來源:億速云 閱讀:141 作者:小新 欄目:web開發

這篇文章將為大家詳細講解有關javascript設計模式之中介者模式的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

Java可以用來干什么

Java主要應用于:1. web開發;2. Android開發;3. 客戶端開發;4. 網頁開發;5. 企業級應用開發;6. Java大數據開發;7.游戲開發等。

 先來理解這么一個問題,假如我們前端開發接的需求是需求方給我們需求,可能一個前端開發會和多個需求方打交道,所以會保持多個需求方的聯系,那么在程序里面就意味著保持多個對象的引用,當程序的規模越大,對象會越來越多,他們之間的關系會越來越復雜,那現在假如現在有一個中介者(假如就是我們的主管)來對接多個需求方的需求,那么需求方只需要把所有的需求給我們主管就可以,主管會依次看我們的工作量來給我們分配任務,這樣的話,我們前端開發就不需要和多個業務方聯系,我們只需要和我們主管(也就是中介)聯系即可,這樣的好處就弱化了對象之間的耦合。

日常生活中的列子:

中介者模式對于我們日常生活中經常會碰到,比如我們去房屋中介去租房,房屋中介人在租房者和房東出租者之間形成一條中介;租房者并不關心租誰的房,房東出租者也并不關心它租給誰,因為有中介,所以需要中介來完成這場交易。

中介者模式的作用是解除對象與對象之間的耦合關系,增加一個中介對象后,所有的相關對象都通過中介者對象來通信,而不是相互引用,所以當一個對象發送改變時,只需要通知中介者對象即可。中介者使各個對象之間耦合松散,而且可以獨立地改變它們之間的交互。

實現中介者的列子如下:

不知道大家有沒有玩過英雄殺這個游戲,最早的時候,英雄殺有2個人(分別是敵人和自己);我們針對這個游戲先使用普通的函數來實現如下:

比如先定義一個函數,該函數有三個方法,分別是win(贏), lose(輸),和die(敵人死亡)這三個函數;只要一個玩家死亡該游戲就結束了,同時需要通知它的對手勝利了; 代碼需要編寫如下:

function Hero(name) {
  this.name = name;
  this.enemy = null; 
}
Hero.prototype.win = function(){
  console.log(this.name + 'Won');
}
Hero.prototype.lose = function(){
  console.log(this.name + 'lose');
}
Hero.prototype.die = function(){
  this.lose();
  this.enemy.win();
}
// 初始化2個對象
var h2 = new Hero("朱元璋");
var h3 = new Hero("劉伯溫");
// 給玩家設置敵人
h2.enemy = h3;
h3.enemy = h2;
// 朱元璋死了 也就輸了
h2.die(); // 輸出 朱元璋lose 劉伯溫Won

現在我們再來為游戲添加隊友

比如現在我們來為游戲添加隊友,比如英雄殺有6人一組,那么這種情況下就有隊友,敵人也有3個;因此我們需要區分是敵人還是隊友需要隊的顏色這個字段,如果隊的顏色相同的話,那么就是同一個隊的,否則的話就是敵人;

我們可以先定義一個數組players來保存所有的玩家,在創建玩家之后,循環players來給每個玩家設置隊友或者敵人;

var players = [];

接著我們再來編寫Hero這個函數;代碼如下:

var players = []; // 定義一個數組 保存所有的玩家
function Hero(name,teamColor) {
  this.friends = [];  //保存隊友列表
  this.enemies = [];  // 保存敵人列表
  this.state = 'live'; // 玩家狀態
  this.name = name;   // 角色名字
  this.teamColor = teamColor; // 隊伍的顏色
}
Hero.prototype.win = function(){
  // 贏了
  console.log("win:" + this.name);
};
Hero.prototype.lose = function(){
  // 輸了
  console.log("lose:" + this.name);
};
Hero.prototype.die = function(){
  // 所有隊友死亡情況 默認都是活著的
  var all_dead = true;
  this.state = 'dead'; // 設置玩家狀態為死亡
  for(var i = 0,ilen = this.friends.length; i < ilen; i+=1) {
    // 遍歷,如果還有一個隊友沒有死亡的話,則游戲還未結束
    if(this.friends[i].state !== 'dead') {
      all_dead = false; 
      break;
    }
  }
  if(all_dead) {
    this.lose(); // 隊友全部死亡,游戲結束
    // 循環 通知所有的玩家 游戲失敗
    for(var j = 0,jlen = this.friends.length; j < jlen; j+=1) {
      this.friends[j].lose();
    }
    // 通知所有敵人游戲勝利
    for(var j = 0,jlen = this.enemies.length; j < jlen; j+=1) {
      this.enemies[j].win();
    }
  }
}
// 定義一個工廠類來創建玩家 
var heroFactory = function(name,teamColor) {
  var newPlayer = new Hero(name,teamColor);
  for(var i = 0,ilen = players.length; i < ilen; i+=1) {
    // 如果是同一隊的玩家
    if(players[i].teamColor === newPlayer.teamColor) {
      // 相互添加隊友列表
      players[i].friends.push(newPlayer);
      newPlayer.friends.push(players[i]);
    }else {
      // 相互添加到敵人列表
      players[i].enemies.push(newPlayer);
      newPlayer.enemies.push(players[i]);
    }
  }
  players.push(newPlayer);
  return newPlayer;
};
    // 紅隊
var p1 = heroFactory("aa",'red'),
  p2 = heroFactory("bb",'red'),
  p3 = heroFactory("cc",'red'),
  p4 = heroFactory("dd",'red');
    
// 藍隊
var p5 = heroFactory("ee",'blue'),
  p6 = heroFactory("ff",'blue'),
  p7 = heroFactory("gg",'blue'),
  p8 = heroFactory("hh",'blue');
// 讓紅隊玩家全部死亡
p1.die();
p2.die();
p3.die();
p4.die();
// lose:dd lose:aa lose:bb lose:cc
// win:ee win:ff win:gg win:hh

如上代碼:Hero函數有2個參數,分別是name(玩家名字)和teamColor(隊顏色),

首先我們可以根據隊顏色來判斷是隊友還是敵人;同樣也有三個方法win(贏),lose(輸),和die(死亡);如果每次死亡一個人的時候,循環下該死亡的隊友有沒有全部死亡,如果全部死亡了的話,就輸了,因此需要循環他們的隊友,分別告訴每個隊友中的成員他們輸了,同時需要循環他們的敵人,分別告訴他們的敵人他們贏了;因此每次死了一個人的時候,都需要循環一次判斷他的隊友是否都死亡了;因此每個玩家和其他的玩家都是緊緊耦合在一起了。

下面我們可以使用中介者模式來改善上面的demo;

首先我們仍然定義Hero構造函數和Hero對象原型的方法,在Hero對象的這些原型方法中,不再負責具體的執行的邏輯,而是把操作轉交給中介者對象,中介者對象來負責做具體的事情,我們可以把中介者對象命名為playerDirector;

在playerDirector開放一個對外暴露的接口ReceiveMessage,負責接收player對象發送的消息,而player對象發送消息的時候,總是把自身的this作為參數發送給playerDirector,以便playerDirector 識別消息來自于那個玩家對象。

代碼如下:

var players = []; // 定義一個數組 保存所有的玩家
function Hero(name,teamColor) {
  this.state = 'live'; // 玩家狀態
  this.name = name;   // 角色名字
  this.teamColor = teamColor; // 隊伍的顏色
}
Hero.prototype.win = function(){
  // 贏了
  console.log("win:" + this.name);
};
Hero.prototype.lose = function(){
  // 輸了
  console.log("lose:" + this.name);
};
// 死亡
Hero.prototype.die = function(){
  this.state = 'dead';
  // 給中介者發送消息,玩家死亡
  playerDirector.ReceiveMessage('playerDead',this);
}
// 移除玩家
Hero.prototype.remove = function(){
  // 給中介者發送一個消息,移除一個玩家
  playerDirector.ReceiveMessage('removePlayer',this);
};
// 玩家換隊
Hero.prototype.changeTeam = function(color) {
  // 給中介者發送一個消息,玩家換隊
  playerDirector.ReceiveMessage('changeTeam',this,color);
};
// 定義一個工廠類來創建玩家 
var heroFactory = function(name,teamColor) {
  // 創建一個新的玩家對象
  var newHero = new Hero(name,teamColor);
  // 給中介者發送消息,新增玩家
  playerDirector.ReceiveMessage('addPlayer',newHero);
  return newHero;
};
var playerDirector = (function(){
  var players = {}, // 保存所有的玩家
    operations = {}; // 中介者可以執行的操作
  // 新增一個玩家操作
  operations.addPlayer = function(player) {
    // 獲取玩家隊友的顏色
    var teamColor = player.teamColor;
    // 如果該顏色的玩家還沒有隊伍的話,則新成立一個隊伍
    players[teamColor] = players[teamColor] || [];
    // 添加玩家進隊伍
    players[teamColor].push(player);
   };
  // 移除一個玩家
  operations.removePlayer = function(player){
    // 獲取隊伍的顏色
    var teamColor = player.teamColor,
    // 獲取該隊伍的所有成員
    teamPlayers = players[teamColor] || [];
    // 遍歷
    for(var i = teamPlayers.length - 1; i>=0; i--) {
      if(teamPlayers[i] === player) {
        teamPlayers.splice(i,1);
      }
    }
  };
  // 玩家換隊
  operations.changeTeam = function(player,newTeamColor){
    // 首先從原隊伍中刪除
    operations.removePlayer(player);
    // 然后改變隊伍的顏色
    player.teamColor = newTeamColor;
    // 增加到隊伍中
    operations.addPlayer(player);
  };
  // 玩家死亡
operations.playerDead = function(player) {
  var teamColor = player.teamColor,
  // 玩家所在的隊伍
  teamPlayers = players[teamColor];

  var all_dead = true;
  //遍歷 
  for(var i = 0,player; player = teamPlayers[i++]; ) {
    if(player.state !== 'dead') {
      all_dead = false;
      break;
    }
  }
  // 如果all_dead 為true的話 說明全部死亡
  if(all_dead) {
    for(var i = 0, player; player = teamPlayers[i++]; ) {
      // 本隊所有玩家lose
      player.lose();
    }
    for(var color in players) {
      if(color !== teamColor) {
        // 說明這是另外一組隊伍
        // 獲取該隊伍的玩家
        var teamPlayers = players[color];
        for(var i = 0,player; player = teamPlayers[i++]; ) {
          player.win(); // 遍歷通知其他玩家win了
        }
      }
    }
  }
};
var ReceiveMessage = function(){
  // arguments的第一個參數為消息名稱 獲取第一個參數
  var message = Array.prototype.shift.call(arguments);
  operations[message].apply(this,arguments);
};
return {
  ReceiveMessage : ReceiveMessage
};
})();
// 紅隊
var p1 = heroFactory("aa",'red'),
  p2 = heroFactory("bb",'red'),
  p3 = heroFactory("cc",'red'),
    p4 = heroFactory("dd",'red');
    
  // 藍隊
  var p5 = heroFactory("ee",'blue'),
    p6 = heroFactory("ff",'blue'),
    p7 = heroFactory("gg",'blue'),
    p8 = heroFactory("hh",'blue');
  // 讓紅隊玩家全部死亡
  p1.die();
  p2.die();
  p3.die();
  p4.die();
  // lose:aa lose:bb lose:cc lose:dd 
  // win:ee win:ff win:gg win:hh

我們可以看到如上代碼;玩家與玩家之間的耦合代碼已經解除了,而把所有的邏輯操作放在中介者對象里面進去處理,某個玩家的任何操作不需要去遍歷去通知其他玩家,而只是需要給中介者發送一個消息即可,中介者接受到該消息后進行處理,處理完消息之后會把處理結果反饋給其他的玩家對象。使用中介者模式解除了對象與對象之間的耦合代碼; 使程序更加的靈活.

中介者模式實現購買商品的列子

下面的列子是書上的列子,比如在淘寶或者天貓的列子不是這樣實現的,也沒有關系,我們可以改動下即可,我們最主要來學習下使用中介者模式來實現的思路。

首先先介紹一下業務:在購買流程中,可以選擇手機的顏色以及輸入購買的數量,同時頁面中有2個展示區域,分別顯示用戶剛剛選擇好的顏色和數量。還有一個按鈕動態顯示下一步的操作,我們需要查詢該顏色手機對應的庫存,如果庫存數量小于這次的購買數量,按鈕則被禁用并且顯示庫存不足的文案,反之按鈕高亮且可以點擊并且顯示假如購物車。

HTML代碼如下:

選擇顏色:

  <select id="colorSelect">
    <option value="">請選擇</option>
    <option value="red">紅色</option>
    <option value="blue">藍色</option>
  </select>
  <p>輸入購買的數量: <input type="text" id="numberInput"/></p>
  你選擇了的顏色:<div id="colorInfo"></div>
  <p>你輸入的數量: <div id="numberInfo"></div> </p>
  <button id="nextBtn" disabled="true">請選擇手機顏色和購買數量</button>

首先頁面上有一個select選擇框,然后有輸入的購買數量輸入框,還有2個展示區域,分別是選擇的顏色和輸入的數量的顯示的區域,還有下一步的按鈕操作;

我們先定義一下:

假設我們提前從后臺獲取到所有顏色手機的庫存量

var goods = {
  // 手機庫存
  "red": 6,
  "blue": 8
};

接著 我們下面分別來監聽colorSelect的下拉框的onchange事件和numberInput輸入框的oninput的事件,然后在這兩個事件中作出相應的處理

常規的JS代碼如下:

// 假設我們提前從后臺獲取到所有顏色手機的庫存量
var goods = {
  // 手機庫存
  "red": 6,
  "blue": 8
};
/*
我們下面分別來監聽colorSelect的下拉框的onchange事件和numberInput輸入框的oninput的事件,
然后在這兩個事件中作出相應的處理
*/
var colorSelect = document.getElementById("colorSelect"),
  numberInput = document.getElementById("numberInput"),
  colorInfo = document.getElementById("colorInfo"),
  numberInfo = document.getElementById("numberInfo"),
  nextBtn = document.getElementById("nextBtn");
    
// 監聽change事件
colorSelect.onchange = function(e){
  select();
};
numberInput.oninput = function(){
  select();
};
function select(){
  var color = colorSelect.value,  // 顏色
    number = numberInput.value, // 數量
    stock = goods[color]; // 該顏色手機對應的當前庫存
      
  colorInfo.innerHTML = color;
  numberInfo.innerHTML = number;

  // 如果用戶沒有選擇顏色的話,禁用按鈕
  if(!color) {
    nextBtn.disabled = true;
    nextBtn.innerHTML = "請選擇手機顏色";
      return;
  }
  // 判斷用戶輸入的購買數量是否是正整數
  var reg = /^\d+$/g;
  if(!reg.test(number)) {
    nextBtn.disabled = true;
    nextBtn.innerHTML = "請輸入正確的購買數量";
    return;
  }
  // 如果當前選擇的數量大于當前的庫存的數量的話,顯示庫存不足
  if(number > stock) {
    nextBtn.disabled = true;
    nextBtn.innerHTML = "庫存不足";
    return;
  }
  nextBtn.disabled = false;
  nextBtn.innerHTML = "放入購物車";
}

上面的代碼雖然是完成了頁面上的需求,但是我們的代碼都耦合在一起了,目前雖然問題不是很多,假如隨著以后需求的改變,SKU屬性越來越多的話,比如頁面增加一個或者多個下拉框的時候,代表選擇手機內存,現在我們需要計算顏色,內存和購買數量,來判斷nextBtn是顯示庫存不足還是放入購物車;代碼如下:

HTML代碼如下:

選擇顏色:
  <select id="colorSelect">
    <option value="">請選擇</option>
    <option value="red">紅色</option>
    <option value="blue">藍色</option>
  </select>
  <br/>
  <br/>
  選擇內存:
  <select id="memorySelect">
    <option value="">請選擇</option>
    <option value="32G">32G</option>
    <option value="64G">64G</option>
  </select>
  <p>輸入購買的數量: <input type="text" id="numberInput"/></p>
  你選擇了的顏色:<div id="colorInfo"></div>
  你選擇了內存:<div id="memoryInfo"></div>
  <p>你輸入的數量: <div id="numberInfo"></div> </p>
  <button id="nextBtn" disabled="true">請選擇手機顏色和購買數量</button>

JS代碼變為如下:

// 假設我們提前從后臺獲取到所有顏色手機的庫存量
var goods = {
  // 手機庫存
  "red|32G": 6,
  "red|64G": 16,
  "blue|32G": 8,
  "blue|64G": 18
};
/*
我們下面分別來監聽colorSelect的下拉框的onchange事件和numberInput輸入框的oninput的事件,
然后在這兩個事件中作出相應的處理
 */
var colorSelect = document.getElementById("colorSelect"),
  memorySelect = document.getElementById("memorySelect"),
  numberInput = document.getElementById("numberInput"),
  colorInfo = document.getElementById("colorInfo"),
  numberInfo = document.getElementById("numberInfo"),
  memoryInfo = document.getElementById("memoryInfo"),
  nextBtn = document.getElementById("nextBtn");
    
// 監聽change事件
colorSelect.onchange = function(){
  select();
};
numberInput.oninput = function(){
  select();
};
memorySelect.onchange = function(){
  select();  
};
function select(){
  var color = colorSelect.value,  // 顏色
    number = numberInput.value, // 數量
    memory = memorySelect.value, // 內存
    stock = goods[color + '|' +memory]; // 該顏色手機對應的當前庫存
      
  colorInfo.innerHTML = color;
  numberInfo.innerHTML = number;
  memoryInfo.innerHTML = memory;
  // 如果用戶沒有選擇顏色的話,禁用按鈕
  if(!color) {
    nextBtn.disabled = true;
    nextBtn.innerHTML = "請選擇手機顏色";
      return;
    }
    // 判斷用戶輸入的購買數量是否是正整數
    var reg = /^\d+$/g;
    if(!reg.test(number)) {
      nextBtn.disabled = true;
      nextBtn.innerHTML = "請輸入正確的購買數量";
      return;
    }
    // 如果當前選擇的數量大于當前的庫存的數量的話,顯示庫存不足
    if(number > stock) {
      nextBtn.disabled = true;
      nextBtn.innerHTML = "庫存不足";
      return;
    }
    nextBtn.disabled = false;
    nextBtn.innerHTML = "放入購物車";
  }

關于“javascript設計模式之中介者模式的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

js
AI

抚宁县| 安图县| 棋牌| 团风县| 周至县| 东山县| 夹江县| 博客| 武清区| 镶黄旗| 佳木斯市| 太康县| 永平县| 建水县| 淮滨县| 双江| 旺苍县| 莱西市| 云林县| 岑溪市| 布拖县| 连江县| 阳泉市| 青河县| 寿宁县| 安宁市| 石景山区| 永丰县| 开远市| 安泽县| 乐陵市| 和硕县| 萝北县| 江永县| 安塞县| 保定市| 建昌县| 简阳市| 太保市| 昌图县| 寻甸|