javascript设计模式 ? 组合模式原理与应用实例分析


Posted in Javascript onApril 14, 2020

本文实例讲述了javascript设计模式 ? 组合模式原理与应用。分享给大家供大家参考,具体如下:

介绍:组合模式又叫部分整体模式,用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次

定义:组合多个对象形成树形结构以表示具有整体一部分关系的层次机构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以成为整体一部分模式。
它是一种对象结构型模式。

场景:我们对公司的人员架构进行一下打印,假设所有管理岗和开发岗的区别只有一个,是不是有下级员工。我们来实现下:

示例:

var LEADER = function(name,dept){
  this._name = name || '';  //姓名
  this._dept = dept || '';  //职位
  this._subordinates = [];  //下属
 
  this.add = function(employee){
    this._subordinates.push(employee);
  }
 
  this.remove = function(employee){
    this._subordinates.splice(this._subordinates.indexOf(employee),1);
  }
 
  this.getSubordinates = function(){
    return this._subordinates;
  }
  this.toString = function(){
    console.log('姓名:'+this._name+',职位:'+this._dept)
  }
}
var JAVARD = function(name,dept){
  this._name = name || '';  //姓名
  this._dept = dept || '';  //职位
 
  this.toString = function(){
    console.log('姓名:'+this._name+',职位:'+this._dept)
  }
}
 
var FERD = function(name,dept){
  this._name = name || '';  //姓名
  this._dept = dept || '';  //职位
  this.toString = function(){
    console.log('姓名:'+this._name+',职位:'+this._dept)
  }
}
 
function addData(){
  var CEO = new LEADER('spancer','CEO');
 
  var CTO = new LEADER('zijian','CTO');
 
  var MANAGER = new LEADER('jiang','LEADER');
 
  var JAVA_LEADER = new LEADER('fei','JAVA_LEADER');
  var FE_LEADER = new LEADER('risker','FE_LEADER');
 
  var wh = new FERD('wanghui','FE');
  var si = new FERD('si','FE');
  var amy = new FERD('amy','FE');
 
  var wei = new JAVARD('wei','JAVA');
  var guo = new JAVARD('guo','JAVA');
  var yuan = new JAVARD('yuan','JAVA');
 
  CEO.add(CTO);
 
  CTO.add(MANAGER);
 
  MANAGER.add(JAVA_LEADER);
  MANAGER.add(FE_LEADER);
 
  FE_LEADER.add(wh);
  FE_LEADER.add(si);
  FE_LEADER.add(amy);
 
  JAVA_LEADER.add(wei);
  JAVA_LEADER.add(guo);
  JAVA_LEADER.add(yuan);
  return CEO;
}
var eachEmployee = function(employee){
  for(var employ of employee.getSubordinates()){
    employ.toString();
    if(employ.getSubordinates && employ.getSubordinates().length > 0){
      eachEmployee(employ);
    }
  }
}
 
var CEO = addData();
CEO.toString();
eachEmployee(CEO);
// 姓名:spancer,职位:CEO
// 姓名:zijian,职位:CTO
// 姓名:jiang,职位:LEADER
// 姓名:fei,职位:JAVA_LEADER
// 姓名:wei,职位:JAVA
// 姓名:guo,职位:JAVA
// 姓名:yuan,职位:JAVA
// 姓名:risker,职位:FE_LEADER
// 姓名:wanghui,职位:FE
// 姓名:si,职位:FE
// 姓名:amy,职位:FE

这里我们简单写的这个demo,用来对公司组织架构进行遍历输出。因为rd和leader具体职能的不同,我们把技术和管理分为两大类。但是这样的设计存在很多问题:

* 可扩展性差,当一个新的职位产生,在对其归类时是新增一个还是放到已有类目下面都是一个问题。
* 当某一行为发生变化需要挨个修改leader类rd类,不符合开关原则。

接下来我们用组合模式实现下:

var Employee = function(name, dept){
  this._name = name || '';  //姓名
  this._dept = dept || '';  //职位
  this._subordinates = [];  //下属
 
  this.add = function(employee){
    this._subordinates.push(employee);
  }
 
  this.remove = function(employee){
    this._subordinates.splice(this._subordinates.indexOf(employee),1);
  }
 
  this.getSubordinates = function(){
    return this._subordinates;
  }
  this.toString = function(){
    console.log('姓名:'+this._name+',职位:'+this._dept)
  }
}
 
function addData(){
  var CEO = new Employee('spancer','CEO');
 
  var CTO = new Employee('zijian','CTO');
 
  var LEADER = new Employee('jiang','LEADER');
 
  var JAVA_LEADER = new Employee('fei','JAVA_LEADER');
  var FE_LEADER = new Employee('risker','FE_LEADER');
 
  var wh = new Employee('wanghui','FE');
  var si = new Employee('si','FE');
  var amy = new Employee('amy','FE');
 
  var wei = new Employee('wei','JAVA');
  var guo = new Employee('guo','JAVA');
  var yuan = new Employee('yuan','JAVA');
 
  CEO.add(CTO);
 
  CTO.add(LEADER);
 
  LEADER.add(JAVA_LEADER);
  LEADER.add(FE_LEADER);
 
  FE_LEADER.add(wh);
  FE_LEADER.add(si);
  FE_LEADER.add(amy);
 
  JAVA_LEADER.add(wei);
  JAVA_LEADER.add(guo);
  JAVA_LEADER.add(yuan);
  return CEO;
}
var eachEmployee = function(employee){
  for(var employ of employee.getSubordinates()){
    employ.toString();
    if(employ.getSubordinates().length > 0){
      eachEmployee(employ);
    }
  }
}
 
var CEO = addData();
CEO.toString();
eachEmployee(CEO);
// 姓名:spancer,职位:CEO
// 姓名:zijian,职位:CTO
// 姓名:jiang,职位:LEADER
// 姓名:fei,职位:JAVA_LEADER
// 姓名:wei,职位:JAVA
// 姓名:guo,职位:JAVA
// 姓名:yuan,职位:JAVA
// 姓名:risker,职位:FE_LEADER
// 姓名:wanghui,职位:FE
// 姓名:si,职位:FE
// 姓名:amy,职位:FE

大家可以对比下两段代码的差异,我们用一个Employee类来替换leader和rd类,其实这就是组合模式的关键:

定义一个抽象类,它既可以代表leader也可以代表rd,添加、打印时也基于Employee类,而无需知道这个人是什么角色。可以对其进行统一处理。

组合模式总结:

优点:
* 可以清楚的定义存在层次关系的复杂对象,让客户端开发过程中忽略层次的差异
* 全局修改时,只需修改一处位置

缺点:
* 无法对生成结果进行限制,不能像第一个例子一样,所有的rd都没有下级员工属性,也没有对应方法。所以在使用时要注意这些约束

适用场景;
* 在一个面向对象的语言开发系统中需要处理一个树形结构。
* 在具有整体和部分的结构中,希望忽略掉二者差异,使客户端一致对待。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
js 页面关闭前的出现提示的实现代码
May 25 Javascript
Three.js源码阅读笔记(光照部分)
Dec 27 Javascript
javascript学习笔记(二)数组和对象部分
Sep 30 Javascript
微信小程序 JS动态修改样式的实现代码
Feb 10 Javascript
利用angularjs1.4制作的简易滑动门效果
Feb 28 Javascript
详解react-webpack2-热模块替换[HMR]
Aug 03 Javascript
详解node单线程实现高并发原理与node异步I/O
Sep 21 Javascript
在vue里面设置全局变量或数据的方法
Mar 09 Javascript
泛谈JS逻辑判断选择器 || &&
May 24 Javascript
vue-cli脚手架引入弹出层layer插件的几种方法
Jun 24 Javascript
Vue 动态组件components和v-once指令的实现
Aug 30 Javascript
vue-cli3单页构建大型项目方案
Apr 07 Javascript
vue项目前端微信JSAPI与外部H5支付相关实现过程及常见问题
Apr 14 #Javascript
JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法
Apr 13 #Javascript
JS实现表单中点击小眼睛显示隐藏密码框中的密码
Apr 13 #Javascript
vue cli3适配所有端方案的实现
Apr 13 #Javascript
RxJS在TypeScript中的简单使用详解
Apr 13 #Javascript
JS错误处理与调试操作实例分析
Apr 13 #Javascript
JS正则表达式常见函数与用法小结
Apr 13 #Javascript
You might like
给WordPress中的留言加上楼层号的PHP代码实例
2015/12/14 PHP
详解php中生成标准uuid(guid)的方法
2019/04/28 PHP
jquery1.9 下检测浏览器类型和版本的方法
2013/12/26 Javascript
JavaScript 学习笔记之操作符(续)
2015/01/14 Javascript
JavaScript中的splice()方法使用详解
2015/06/09 Javascript
浅析Node.js中的内存泄漏问题
2015/06/23 Javascript
jQuery插件Timelinr 实现时间轴特效
2015/10/04 Javascript
JavaScript实现输入框(密码框)出现提示语
2016/01/12 Javascript
JavaScript函数柯里化详解
2016/04/29 Javascript
JS实现评价的星星功能
2017/08/20 Javascript
微信小程序开发之好友列表字母列表跳转对应位置
2017/09/26 Javascript
Angular ElementRef简介及其使用
2018/10/01 Javascript
JavaScript常用内置对象用法分析
2019/07/09 Javascript
[01:02:18]VGJ.S vs infamous Supermajor 败者组 BO3 第一场 6.4
2018/06/05 DOTA
python使用sorted函数对列表进行排序的方法
2015/04/04 Python
python多进程中的内存复制(实例讲解)
2018/01/05 Python
tensorflow 输出权重到csv或txt的实例
2018/06/14 Python
Python绘制股票移动均线的实例
2019/08/24 Python
wxPython实现整点报时
2019/11/18 Python
python cv2读取rtsp实时码流按时生成连续视频文件方式
2019/12/25 Python
Python面向对象之多态原理与用法案例分析
2019/12/30 Python
40行Python代码实现天气预报和每日鸡汤推送功能
2020/02/27 Python
TensorFlow tf.nn.softmax_cross_entropy_with_logits的用法
2020/04/19 Python
5分钟实现Canvas鼠标跟随动画背景
2019/11/18 HTML / CSS
世界上最大的艺术和工艺用品商店:MisterArt.com
2018/07/13 全球购物
尤为Wconcept中国官网:韩国设计师品牌服饰
2019/01/10 全球购物
英国顶尖手表珠宝品牌独家授权经销商:HS Johnson
2020/10/28 全球购物
英国时尚首饰品牌:Missoma
2020/06/29 全球购物
新闻专业个人自我评价
2013/09/21 职场文书
小学班主任评语大全
2014/04/23 职场文书
奥巴马英文演讲稿
2014/05/15 职场文书
学校施工安全责任书
2015/01/29 职场文书
趣味运动会通讯稿
2015/07/18 职场文书
Pytorch使用shuffle打乱数据的操作
2021/05/20 Python
教你如何使用Python实现二叉树结构及三种遍历
2021/06/18 Python
python的html标准库
2022/04/29 Python