zoukankan      html  css  js  c++  java
  • js设计模式--策略模式

    策略模式:

    定义了一系列的算法,把他们封装起来,是它们之间可以互相替换,此模式不会影响到使用算法的客户。

    回忆下jquery里的animate方法:

    $( div ).animate( {"left: 200px"}, 1000, 'linear' );  //匀速运动
    $( div ).animate( {"left: 200px"}, 1000, 'cubic' );  //三次方的缓动

    这2句代码都是让div在1000ms内往右移动200个像素. linear(匀速)和cubic(三次方缓动)就是一种策略模式的封装。

    一般用在检验表单输入的合法性,根据策略模式,先将相同的工作代码单独封装成不同的类,然后通过统一的策略类来处理,例如:

     var vidata = {
        // 所有可以的验证规则处理类存放的地方,后面会单独定义
        types: {},
    
        // 验证类型所对应的错误消息
        messages: [],
    
        // 当然需要使用的验证类型
        config: {},
    
        validate:function(data){
    
               var i, msg, type, checker, result_ok;
    
               // 清空所有的错误信息
               this.messages = [];
               for (i in data) {
    
                   if (data.hasOwnProperty(i)) {
    
                      type = this.config[i];  // 根据key查询是否有存在的验证规则
                      checker = this.types[type]; // 获取验证规则的验证类
    
                      if (!type) {
                          continue; // 如果验证规则不存在,则不处理
                      };
    
                      if (!checker) { // 如果验证规则类不存在,抛出异常
                        throw {
                            name: "ValidationError",
                            message: "No handler to validate type " + type
                        };
                      };
    
                      result_ok = checker.validate(data[i]); // 使用查到到的单个验证类进行验证
                     //若果检验的结果通过,则messages中不添加任何消息,即checker.instructions
                       if (!result_ok) {
                           msg = "Invalid value for *" + i + "*, " + checker.instructions;
                            this.messages.push(msg);
                         };
                   }; 
               };
                return this.hasError();
        },
    
        hasError:function(){
          //如果全部通过,则messages的length为0;
          return this.messages.length !== 0;
        }
    
      };

    定义了相同的策略处理类之后,在定义具体的处理函数:

    vidata.types.isString = {
    
      validate: function (value) {
            return value !== "";
        },
        instructions: "传入的值不能为空";//返回的不通过时候的消息
    };
    
    vidata.types.isNum = {
    
     validate: function (value) {
            return !isNaN(value);
        },
        instructions: "传入的值只能是合法的数字,例如:1, 3.14 or 2010"//返回的不通过时候的消息
    };

    定义了具体的处理函数之后,我们可以随意在这个类上面增加我们需要的验证函数,验证规则,以及错误时候的信息,这样使用它:
      //要验证的数据
      var data = {
        userName:"rrr",
        password:"3333"

    };
    //验中的证规则的配置,其中key值要和data中的key值保持一致性,value值要和所验证的函数方法保持命名一致性。
      vidata.config = {
        userName:"isString",
        password:"isNum"
      };

    当我们需要增加新的规则是,只需要分别在data,vidata.config,vidata.types做如下的增加:

    //新添加的验证方法
    
    vidata.types.isEmail = {
    
      validate: function (value) {
            return /w+((-w+)|(.w+))*@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+)*.[A-Za-z0-9]+/.test(value)
        },
        instructions: "传入的值必须是邮箱格式!"//返回的不通过时候的消息
    };
    //新增加的验证邮箱数据
      var data = {
        ......
        email:"wang@163.com"
      };
    
    //在配置信息中这样配置:
    vidata.config = {
      ......
       email:"isEmail"
    };

    使用:

    vidata.validate(data);//执行
      if(vidata.hasError()){
        console.log(vidata.messages);//返回来的结果。
      };

    单独定义算法类,也方便单元测试,可通过自己的算法进行测试。

    实践中,不仅可以封装算法,也可以用来封装几乎任何类型的规则,是要在分析过程中需要在不同时间应用不同的业务规则,就可以考虑是要策略模式来处理各种变化。

    参考:《javascript模式》

    汤姆大叔:http://www.cnblogs.com/TomXu/archive/2012/03/05/2358552.html

    http://www.alloyteam.com/2012/10/commonly-javascript-design-patterns-strategy-mode/

  • 相关阅读:
    Atitit sql计划任务与查询优化器统计信息模块
    Atitit  数据库的事件机制触发器与定时任务attilax总结
    Atitit 图像处理知识点体系知识图谱 路线图attilax总结 v4 qcb.xlsx
    Atitit 图像处理 深刻理解梯度原理计算.v1 qc8
    Atiti 数据库系统原理 与数据库方面的书籍 attilax总结 v3 .docx
    Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析
    Atitit View事件分发机制
    Atitit 基于sql编程语言的oo面向对象大规模应用解决方案attilax总结
    Atitti 存储引擎支持的国内点与特性attilax总结
    Atitit 深入理解软件的本质 attilax总结 软件三原则"三次原则"是DRY原则和YAGNI原则的折
  • 原文地址:https://www.cnblogs.com/floatboy/p/module_4.html
Copyright © 2011-2022 走看看