(编辑:jimmy 日期: 2024/11/16 浏览:2)
本文实例讲述了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.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。