• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >JavaScript > javascript设计模式之中介者模式学习笔记

javascript设计模式之中介者模式学习笔记

作者:灰太狼-铜豌豆 字体:[增加 减小] 来源:互联网 时间:2017-05-11

灰太狼-铜豌豆通过本文主要向大家介绍了javascript设计模式之中介者模式学习笔记等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

 先来理解这么一个问题,假如我们前端开发接的需求是需求方给我们需求,可能一个前端开发会和多个需求方打交道,所以会保持多个需求方的联系,那么在程序里面就意味着保持多个对象的引用,当程序的规模越大,对象会越来越多,他们之间的关系会越来越复杂,那现在假如现在有一个中介者(假如就是我们的主管)来对接多个需求方的需求,那么需求方只需要把所有的需求给我们主管就可以,主管会依次看我们的工作量来给我们分配任务,这样的话,我们前端开发就不需要和多个业务方联系,我们只需要和我们主管(也就是中介)联系即可,这样的好处就弱化了对象之间的耦合。

日常生活中的列子:

中介者模式对于我们日常生活中经常会碰到,比如我们去房屋中介去租房,房屋中介人在租房者和房东出租者之间形成一条中介;租房者并不关心租谁的房,房东出租者也并不关心它租给谁,因为有中介,所以需要中介来完成这场交易。

中介者模式的作用是解除对象与对象之间的耦合关系,增加一个中介对象后,所有的相关对象都通过中介者对象来通信,而不是相互引用,所以当一个对象发送改变时,只需要通知中介者对象即可。中介者使各个对象之间耦合松散,而且可以独立地改变它们之间的交互。

实现中介者的列子如下:

不知道大家有没有玩过英雄杀这个游戏,最早的时候,英雄杀有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 h1 = new Hero("朱元璋");
var h2 = new Hero("刘伯温");
// 给玩家设置敌人
h1.enemy = h2;
h2.enemy = h1;
// 朱元璋死了 也就输了
h1.die(); // 输出 朱元璋lose 刘伯温Won
</div>

现在我们再来为游戏添加队友

比如现在我们来为游戏添加队友,比如英雄杀有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
</div>

如上代码: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[



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-05-11js实现图片加载淡入淡出效果
  • 2017-05-11nodejs 终端打印进度条实例代码
  • 2017-05-11node.js实现回调的方法示例
  • 2017-05-11详解angularJs模块ui-router之状态嵌套和视图嵌套
  • 2017-05-11selenium 与 chrome 进行qq登录并发邮件操作实例详解
  • 2017-05-11从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析
  • 2017-05-11基于jQuery实现滚动刷新效果
  • 2017-05-11详解angular2采用自定义指令(Directive)方式加载jquery插件
  • 2017-05-11详解百度百科目录导航树小插件
  • 2017-05-11js实现年月日表单三级联动

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • JavaScript日期对象(Date)基本用法示例
    • ionic+AngularJs实现获取验证码倒计时按钮
    • 微信小程序开发的四十个技术窍门总结(推荐)
    • jquery做个日期选择适用于手机端示例
    • 完美解决UI-Grid表格元素中多个空格显示为一个空格的问题
    • 基于JavaScript实现带缩略图的轮播效果
    • 使用BootStrap进行轮播图的制作
    • 浅谈$_FILES数组为空的原因
    • js oncontextmenu事件使用详解
    • canvas实现图像截取功能

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有