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/

  • 相关阅读:
    CocoaPod 常用命令
    Runloop
    RxSwift学习笔记7:buffer/window/map/flatMap/flatMapLatest/flatMapFirst/concatMap/scan/groupBy
    RxSwift学习笔记6:Subjects/PublishSubject/BehaviorSubject/ReplaySubject/Variable
    RxSwift学习笔记5:Binder
    RxSwift学习笔记4:disposeBag/scheduler/AnyObserver/Binder
    RxSwift学习笔记3:生命周期/订阅
    RxSwift学习笔记2:Observable/生命周期/Event/oneNext/onError/onCompleted/
    RxSwift学习笔记1:RxSwift的编程风格
    iOS处理视图上同时添加单击与双击手势的冲突问题
  • 原文地址:https://www.cnblogs.com/floatboy/p/module_4.html
Copyright © 2011-2022 走看看