JavaScript组合设计模式--改进引入案例分析


Posted in Javascript onMay 23, 2020

本文实例讲述了JavaScript组合设计模式--改进引入案例。分享给大家供大家参考,具体如下:

对于组合设计模式:

 (1)组合模式中把对象分为两种(组合对象,和叶子对象)
 (2)组合对象和叶子对象实现:同一批操作
 (3)对组合对象执行的操作可以向下传递到叶子节点进行操作
 (4)这样就会弱化类与类之间的耦合
 (5)他常用的手法是把对象组合成属性结构的对象

根据组合模式的这些特性我们改写代码如下:

由于用到了接口检验所以我们先引入接口文件代码

//定义一个静态方法来实现接口与实现类的直接检验
//静态方法不要写出Interface.prototype ,因为这是写到接口的原型链上的
//我们要把静态的函数直接写到类层次上
//定义一个接口类
var Interface=function (name,methods) {//name:接口名字
  if(arguments.length<2){
    alert("必须是两个参数")
  }
  this.name=name;
  this.methods=[];//定义一个空数组装载函数名
  for(var i=0;i<methods.length;i++){
    if(typeof methods[i]!="string"){
      alert("函数名必须是字符串类型");
    }else {
      this.methods.push( methods[i]);
    }
  }
};
Interface.ensureImplement=function (object) {
  if(arguments.length<2){
    throw new Error("参数必须不少于2个")
    return false;
  }
  for(var i=1;i<arguments.length;i++){
    var inter=arguments[i];
    //如果是接口就必须是Interface类型
    if(inter.constructor!=Interface){
      throw new Error("如果是接口类的话,就必须是Interface类型");
    }
    //判断接口中的方法是否全部实现
    //遍历函数集合
    for(var j=0;j<inter.methods.length;j++){
      var method=inter.methods[j];//接口中所有函数

      //object[method]传入的函数
      //最终是判断传入的函数是否与接口中所用函数匹配
      if(!object[method]||typeof object[method]!="function" ){//实现类中必须有方法名字与接口中所用方法名相同
        throw new Error("实现类中没有完全实现接口中的所有方法")
      }
    }
  }
}

(1)统一接口

var composite=new Interface("composite",["getChildByName","add"]);//侧重点获取子
var student=new Interface("composite",["goToClass","finishClass"]);//侧重点为每个对象的实现

(2)定义组合类

var compositeObj=function (name) {
         this.name=name;
         this.type="com";//默认是组合类
         var childs=new Array();
        //得到相关的所有孩子节点
         this.getChildByName=function (name) {
           //涉及到递归
           var toChilds=new Array();
           if(!name){
             for(var i=0;i<childs.length;i++){
                if(childs[i].type=="com"){
                  toChilds=toChilds.concat(childs[i].getChildByName())
                }else {
                  toChilds.push(childs[i]);
                }
             }
           }else {
             for (var i = 0; i < childs.length; i++){
               if(childs[i].name==name){
                 if(childs[i].type=="com"){
                   toChilds=toChilds.concat(childs[i].getChildByName());
                   break;
                 }else {
                   toChilds.push(childs[i]);
                   break;
                 }
               }else {
                 if(childs[i].type == "com"){
                   toChilds =toChilds.concat(childs[i].getChildByName(name));
                 }
               }
             }
               }
               return toChilds;
         };
         //增加子节点
         this.add=function (child) {
           childs.push(child);
           return this;
         };
         //去上课
        this.goToClass=function (name) {
        var toChilds=this.getChildByName(name);
         for(var i=0;i<toChilds.length;i++){
              toChilds[i].goToClass();
         }
      };
          //下课
         this.finishClass=function (name) {
      var toChilds=this.getChildByName(name);
      for(var i=0;i<toChilds.length;i++){
        toChilds[i].finishClass();
      }
    };
    Interface.ensureImplement(this,composite,student);
    };

(3)定义叶子类

var studentObj=function (name) {
    this.name=name;
    this.type="student";//默认是叶子
    //得到所有孩子节点
   this.getChildByName=function (name) {
     if(this.name==name){
       return this;
     }else {
       return null;
     }
   }
   //增加子节点
    this.add=function (child) {
      throw new Error("add 不成被初始化(在叶子了中)")
    }
    //去上课
    this.goToClass = function(name){
      document.write(this.name +" 去上课<br>");
    }
    //下课
    this.finishClass = function(name){
      document.write(this.name +" 下课<br>");
    }
    Interface.ensureImplement(this,composite,student);
  }

(4)应用---将学校,班级,组,学生关联起来

var astudent=new studentObj("我是a同学");
  var bstudent=new studentObj("我是b同学");
  var cstudent=new studentObj("我是c同学");
  var dstudent=new studentObj("我是d同学");
  var estudent=new studentObj("我是e同学");
  var fstudent=new studentObj("我是f同学");
  var gstudent=new studentObj("我是g同学");
  var hstudent=new studentObj("我是h同学");
  var istudent=new studentObj("我是i同学");

  var one = new compositeObj("一班");
  var oneOne = new compositeObj("一班一组");
  oneOne.add(astudent).add(bstudent);
  var oneTwo = new compositeObj("一班二组");
  oneTwo.add(cstudent).add(dstudent);

  one.add(oneOne).add(oneTwo);
  var two = new compositeObj("二班");
  var twoOne = new compositeObj("二班一组");
  twoOne.add(estudent).add(fstudent);
  var twoTwo = new compositeObj("二班二组");
  twoTwo.add(gstudent).add(hstudent).add(istudent)
  two.add(twoOne).add(twoTwo);
  var usPcat = new compositeObj("组合设计模式培训学校");
  usPcat.add(one).add(two);

(5)客户端调用API,只需要简单的安排去上课即可,也就是客户端只需要写去上课的代码即可

usPcat.goToClass();
document.write("-------------------------<br>");
usPcat.goToClass("一班");
document.write("-------------------------<br>");
usPcat.goToClass("二班一组");

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

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

Javascript 相关文章推荐
解决使用attachEvent函数时,this指向被绑定的元素的问题的方法
Aug 13 Javascript
IE和FireFox(FF)中js和css的不同
Apr 13 Javascript
纯JAVASCRIPT图表动画插件Highcharts Examples
Apr 16 Javascript
JQUERY dialog的用法详细解析
Dec 19 Javascript
微信小程序 开发工具快捷键整理
Oct 31 Javascript
原生JS实现在线问卷调查投票特效
Jan 03 Javascript
AngularJs中 ng-repeat指令中实现含有自定义指令的动态html的方法
Jan 19 Javascript
详解Vue2+Echarts实现多种图表数据可视化Dashboard(附源码)
Mar 21 Javascript
vue axios基于常见业务场景的二次封装的实现
Sep 21 Javascript
微信小程序可滑动月日历组件使用详解
Oct 21 Javascript
基于JS实现视频上传显示进度条
May 12 Javascript
详解TS数字分隔符和更严格的类属性检查
May 06 Javascript
JavaScript组合模式---引入案例分析
May 23 #Javascript
JavaScript设计模式--桥梁模式引入操作实例分析
May 23 #Javascript
JavaScript设计模式--简单工厂模式实例分析【XHR工厂案例】
May 23 #Javascript
JavaScript设计模式--简单工厂模式定义与应用案例详解
May 23 #Javascript
基于element-ui封装可搜索的懒加载tree组件的实现
May 22 #Javascript
微信小程序点击滚动到指定位置的实现
May 22 #Javascript
使用JavaScript通过前端发送电子邮件
May 22 #Javascript
You might like
function.inc.php超越php
2006/12/09 PHP
PHP 全角转半角实现代码
2010/05/16 PHP
php实现递归与无限分类的方法
2015/02/16 PHP
php中array_column函数简单实现方法
2016/07/11 PHP
php mysql实现mysql_select_db选择数据库
2016/12/30 PHP
Thinkphp 框架扩展之标签库驱动原理与用法分析
2020/04/23 PHP
JQery jstree 大数据量问题解决方法
2010/03/09 Javascript
javascript判断iphone/android手机横竖屏模式的函数
2011/12/20 Javascript
js 代码优化点滴记录
2012/02/19 Javascript
通过js获取div的background-image属性
2013/10/15 Javascript
jquery设置text的值示例(设置文本框 DIV 表单值)
2014/01/06 Javascript
关于JS数组追加数组采用push.apply的问题
2014/06/09 Javascript
jquery插件bxslider用法实例分析
2015/04/16 Javascript
js实现发送验证码后的倒计时功能
2015/05/28 Javascript
js匿名函数作为函数参数详解
2016/06/01 Javascript
基于zepto.js实现登录界面
2017/10/09 Javascript
浅谈Vue SSR 的 Cookies 问题
2017/11/20 Javascript
Element Tooltip 文字提示的使用示例
2020/07/26 Javascript
基于element-ui对话框el-dialog初始化的校验问题解决
2020/09/11 Javascript
vue动态合并单元格并添加小计合计功能示例
2020/11/26 Vue.js
[23:18]Spirit vs Liquid Supermajor小组赛A组 BO3 第二场 6.2
2018/06/03 DOTA
Python中使用PyQt把网页转换成PDF操作代码实例
2015/04/23 Python
Python中的探索性数据分析(功能式)
2017/12/22 Python
Python简单实现词云图代码及步骤解析
2020/06/04 Python
Django def clean()函数对表单中的数据进行验证操作
2020/07/09 Python
python 实现压缩和解压缩的示例
2020/09/22 Python
Python尾递归优化实现代码及原理详解
2020/10/09 Python
总结python 三种常见的内存泄漏场景
2020/11/20 Python
农村婚礼证婚词
2014/01/10 职场文书
电台实习生求职信
2014/02/25 职场文书
英语专业求职信
2014/07/08 职场文书
婚内房产协议书范本
2014/10/02 职场文书
幸福家庭事迹材料
2014/12/20 职场文书
安全教育培训心得体会
2016/01/15 职场文书
Python echarts实现数据可视化实例详解
2022/03/03 Python
python标准库ElementTree处理xml
2022/05/20 Python