博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript设计模式-组合模式(6)
阅读量:4290 次
发布时间:2019-05-27

本文共 6770 字,大约阅读时间需要 22 分钟。

组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式。使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为。这可以简化粘贴性代码,使其更容易维护,而那些复杂行为则被委托给各个对象

传统的层级业务场景

/* * 场景模拟: *  -> 公司  *          -> 财务部门 *                      -> 张一 *                      -> 张二 *                      -> 张三 *          -> 销售部门 *                      -> 张四 *                      -> 张五 *                      -> 张六 *   *      实际的任务具体是落实到人上去实施的 也就是说只有人才具有具体的方法实现 *           */          var Org = function(name){
this.name = name ; this.depts = [] ; }; Org.prototype = { constructor:Org , addDepts:function(child){
this.depts.push(child); return this ; } , getDepts:function(){
return this.depts; } }; var Dept = function(name){
this.name = name ; this.persons = [] ; }; Dept.prototype = { constructor:Dept , addPersons: function(child){
this.persons.push(child); return this ; } , getPersons:function(){
return this.persons; } }; var Person = function(name){
this.name = name ; }; Person.prototype = { constructor : Person , hardworking : function(){
document.write(this.name + '...努力工作!'); } , sleeping : function(){
document.write(this.name + '...努力睡觉!'); } }; var p1 = new Person('张1'); var p2 = new Person('张2'); var p3 = new Person('张3'); var p4 = new Person('张4'); var p5 = new Person('张5'); var p6 = new Person('张6'); var dept1 = new Dept('开发部门'); dept1.addPersons(p1).addPersons(p2).addPersons(p3); var dept2 = new Dept('销售部门'); dept2.addPersons(p4).addPersons(p5).addPersons(p6); var org = new Org('bjsxt'); org.addDepts(dept1).addDepts(dept2); // 需求: 具体的让一个人(张3)去努力工作 //org.getDepts() //org.hardworking('开发部门'); for(var i = 0 ,depts = org.getDepts(); i

对于一些对层级有修改的需求,或者对层级结构也需要修改,需要调整实现的业务代码会很复杂,不易于扩展和维护。

使用组合模式重构上述场景

/** *  组合模式应用的场景和特点: *  场景: *  1 存在一批组织成某种层次体系的对象 *  2 希望对这批对象或其中的一部分对象实施一个操作 *   *  应用特点: *  1 组合模式中只有两种类型对象:组合对象、叶子对象 *  2 这两种类型都实现同一批接口 *  3 一般我们会在组合对象中调用其方法并隐式调用"下级对象"的方法(这里我们一般采用递归的形式去做) *  * * * 场景模拟: *  -> 公司  *       -> 北京分公司 *                  -> 财务部门 *                              -> 张1 *                              -> 张2 *                              -> 张3 *                  -> 销售部门 *                              -> 张4 *                              -> 张5 *                              -> 张6         -> 长沙分公司  *                  -> 财务部门 *                              -> 张7 *                              -> 张8 *                              -> 张9 *                  -> 销售部门 *                              -> 张10 *                              -> 张11 *                              -> 张12                    *   *      实际的任务具体是落实到人上去实施的 也就是说只有人才具有具体的方法实现 *           */var CompositeInterface = new BH.Interface('CompositeInterface', ['addChild', 'getChild']);var LeafInterface = new BH.Interface('LeafInterface', ['hardworking', 'sleeping']);var Composite = function(name) {
this.name = name; this.type = 'Composite'; //说明对象的类型(组合对象) this.children = []; //承装孩子的数组 //创建对象的最后要验证接口 BH.Interface.ensureImplements(this, CompositeInterface, LeafInterface);};Composite.prototype = { constructor: Composite, addChild: function(child) {
this.children.push(child); return this; }, getChild: function(name) {
// 接受叶子对象类型的数组 var elements = []; // 判断对象是否为Leaf类型的,如果是直接加到elements数组中,不是继续递归调用 var pushLeaf = function(item) {
if (item.type === 'Composite') { item.children.each(arguments.callee); } else if (item.type === 'Leaf') { elements.push(item); } }; // 根据name(一定是从根节点开始遍历) 让指定name下的所有的类型为Leaf的对象去执行操作 if (name && this.name !== name) { this.children.each(function(item) {
// 如果传递的name是2级节点名称 if (item.name === name && item.type === 'Composite') { item.children.each(pushLeaf); } // 如果传递的name是3级节、4级、5级...N级 if (item.name !== name && item.type === 'Composite') { item.children.each(arguments.callee); } // 如果传递的name是叶子节点的时候 if (item.name === name && item.type === 'Leaf') { elements.push(item); } }); } // 不传递name(一定是根节点) 让整个公司所有类型为Leaf的对象去执行操作 else { this.children.each(pushLeaf); } return elements; }, hardworking: function(name) {
//得到所有的Leaf类型的对象数组 var leafObjects = this.getChild(name); for (var i = 0; i < leafObjects.length; i++) { leafObjects[i].hardworking(); } }, sleeping: function(name) {
//得到所有的Leaf类型的对象数组 var leafObjects = this.getChild(name); for (var i = 0; i < leafObjects.length; i++) { leafObjects[i].sleeping(); } }};var Leaf = function(name) {
this.name = name; this.type = 'Leaf'; //说明对象的类型(叶子对象) //创建对象的最后要验证接口 BH.Interface.ensureImplements(this, CompositeInterface, LeafInterface);};Leaf.prototype = { constructor: Leaf, addChild: function(child) {
throw new Error('this method is disabled....'); }, getChild: function(name) {
if (this.name = name) { return this; } return null; }, hardworking: function() {
document.write(this.name + '...努力工作!'); }, sleeping: function() {
document.write(this.name + '...努力睡觉!'); }};//测试数据var p1 = new Leaf('张1');var p2 = new Leaf('张2');var p3 = new Leaf('张3');var p4 = new Leaf('张4');var p5 = new Leaf('张5');var p6 = new Leaf('张6');var p7 = new Leaf('张7');var p8 = new Leaf('张8');var p9 = new Leaf('张9');var p10 = new Leaf('张10');var p11 = new Leaf('张11');var p12 = new Leaf('张12');var dept1 = new Composite('北京开发部门');dept1.addChild(p1).addChild(p2).addChild(p3);var dept2 = new Composite('北京销售部门');dept2.addChild(p4).addChild(p5).addChild(p6);var dept3 = new Composite('长沙开发部门');dept3.addChild(p7).addChild(p8).addChild(p9);var dept4 = new Composite('长沙销售部门');dept4.addChild(p10).addChild(p11).addChild(p12);var org1 = new Composite('北京分公司');org1.addChild(dept1).addChild(dept2);var org2 = new Composite('长沙分公司');org2.addChild(dept3).addChild(dept4);var org = new Composite('尚学堂总部');org.addChild(org1).addChild(org2);// 让整个公司下所有的员工都去努力工作org.hardworking(); //尚学堂总部document.write('
----------------------------------
');// name为总公司的直接子节点的时候org.hardworking('长沙分公司');document.write('
----------------------------------
');// name为总公司的间接子节点的时候(类型不为leaf)(3级4级...N级)org.hardworking('长沙开发部门');document.write('
----------------------------------
');// name为leaf对象的时候org.hardworking('张5');document.write('
----------------------------------
');

转载地址:http://dergi.baihongyu.com/

你可能感兴趣的文章
mysql substring函数截取值后赋给一个declare变量
查看>>
Java Thread 的 sleep() 和 wait() 的区别
查看>>
DbUtils入门
查看>>
每一个程序员需要了解的10个Linux命令
查看>>
service的自调用 VS service之间调用
查看>>
Android权限管理之Permission权限机制及使用
查看>>
重识Retrofit
查看>>
PowerDesigner(数据建模)使用大全
查看>>
RadioButton与CheckBox_优就业
查看>>
java中的throw与throws的区别
查看>>
优化用户登录体验效果
查看>>
用js批量选中功能实现更改数据库中status状态值_优就业
查看>>
MySql表信息基础知识学习
查看>>
为什么document找到的不是html节点_优就业
查看>>
Javascript本地存储小结
查看>>
常用排序方法介绍
查看>>
Java异常分类和统一处理
查看>>
原 荐 cache线程池对数据库操作的饥饿问题
查看>>
使用Eclipse把java文件打包成jar 含有第三方jar库的jar包
查看>>
3种web会话管理的方式
查看>>