• Javascript设计模式学习三(策略模式)


    定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。
    目的:将算法的使用和算法的实现分离开来。
    比如:

    if(input == 'A'){
        return 1;
    }
    if(input == 'B'){
        return 2;
    }
    if(input == 'C'){
        return 3;
    }
    //或者
    switch(input){
        case 'A':
            console.log(1);
            break;
        case 'B':
            console.log(2);
            break;
        case 'C':
            console.log(3);
            break;
    }

    对于这种有多个if-else和switch语句的情况,可以使用策略模式来处理。


    策略模式有两部分组成:
    一、策略类:封装了具体的算法,并负责具体计算过程。
    二、环境类:接受客户的请求,然后将请求委托给某个策略类

    //策略类Strategy
    var strategies = {
        "A": function(num){
            return 1 + num;
        },
        "B": function(num){
            return 2 + num;
        },
        "C": function(num){
            return 3 + num;
        }
    };
    //环境类Context
    var calculate = function(level,num){
        return strategies[level](num);
    };
    //调用
    result = calculate('A',10);


    使用策略模式也可以用来封装一系列的业务规则,只要这些业务规则指向的目标一致,并且可以被替换使用,我们就可以用策略模式来封装它们。

    表单校验:
    一般写法:

    function checkForm(){
        if($("#name").val()==''){
            alert('用户名不能为空!');
            return false;
        }
        if($("#password").val().length<6){
            alert('密码长度不能少于6位!');
            return false;
        }
        if(!/(^1[3|5|8][0-9]{9}$)/.test($("#phone").val())){
            alert('手机号格式不正确!');
            return false;
        }
    }

    使用“策略模式”:

    /***********************策略对象Strategy***********************/
    var strategise={
        isEmpty: function(value,errorMsg){
            if(value === ''){
                return errorMsg;
            }
        },
        minLength: function (value,length,errorMsg) {
            if(value.length<length){
                return errorMsg;
            }
        },
        isMobile: function (value,errorMsg) {
            if(!/(^1[3|5|8][0-9]{9}$)/.test(value)){
                return errorMsg;
            }
        }
    };
    
    /***********************Validator类Context***********************/
    var Validator= function () {
        this.cache=[]; //保存校验规则
    };
    
    Validator.prototype.add = function(dom,rules){
        var self = this;
        for(var i=0, rule; rule=rules.strategy.split(":")){
            (function(rule){
                var strateAry = rule.strategy.split(":");
                var errorMsg = rule.errorMsg;
                
                self.cache.push(function(){
                    var strategy = strateAry.shift();//把数组的第一个元素从其中删除。
                    strateAry.unshift(dom.val());    //向数组的开头添加input元素的值。
                    strateAry.push(errorMsg);    //在数组尾部添加error信息
                    return strategies[strategy].apply(dom,strateAry);
                });
            })(rule)
        }
    };
    
    Validator.prototype.start = function(){
        for(var i=0, Func; Func=this.cache[i];i++){
            var errorMsg = Func();
            if(errorMsg){
                return errorMsg;
            }
        }
    };
    
    /***********************调用***********************/
    var checkForm = function(){
        var validator = new Validator();
        
        validator.add($("#name"),[{
            strategy: 'isEmpty',
            errorMsg: '用户名不能为空!'
        },{
            strategy: 'minLength:6',
            errorMsg: '用户名长度不能小于6位'
        }]);
        validator.add($("#password"),[{
            strategy: 'minLength:6',
            errorMsg: '密码长度不能小于6位'
        }]);
        validator.add($("#phone"),[{
            strategy: 'isMobile',
            errorMsg: '手机号格式不正确!'
        }]);
        
        var errorMsg = validator.start();
        return errorMsg;
    }
    $("form").submit(function(){
        var errorMsg = checkForm();
        if(errorMsg){
            alert(errorMsg);
            return fasle;
        }
    });

    优点:
    1、采用组合、委托和多态等技术和思想,有效地避免多重条件选择语句。
    2、对“开放封闭原则”完美支持,将算法独立封装在strategy,使得它们易于切换、理解和扩展。
    3、策略模式中的算法也可以复用在系统的其他地方,从而避免重复的复制粘贴工作。
    4、利用组合和委托让Context拥有执行算法的能力,这也是继承的一种轻便替代方案。

  • 相关阅读:
    强化学习快速入门
    Spark GraphX图计算简单案例【代码实现,源码分析】
    CDA数据分析【第二章:数据收集与导入】
    CDA数据分析实务【第一章:营销决策分析概述】
    CDA数据分析【第一章:数据分析概述】
    BLAS快速入门
    Tachyon内存文件系统快速入门
    Solr新特性【4.x,5.x,6.x,7.x】
    利用Redis keyspace notification(键空间通知)实现过期提醒
    设计模式 行为型
  • 原文地址:https://www.cnblogs.com/boliang/p/4820015.html
Copyright © 2020-2023  润新知