实战中的策略模式(日常笔记)

表单验证的规则的实现

基础实现

  1. 手机号码的校验
  2. 密码的长度的验证不小于6
表单结构
 <form action="http:// xxx.com/register" id="registerForm" method="post">
     请输入手机号码:<input type="text" name="phoneNumber" />
     请输入密码:<input type="text" name="password" />
     <button>提交</button>
 </form>
代码实现
 var registerForm = document.getElementById('registerForm')
 registerForm.onsubmit = function () {
     if (registerForm.password.value.length < 6) {
         alert(`密码长度不能少于 ${registerForm.password.value.length}`)
         return false
     }
     if (!/(^1[3|5|8][0-9]{9}$)/.test(registerForm.phoneNumber.value)) {
         alert('手机号码不正确')
         return false
     }
     console.log('提交成功!!!');
 }
代码问题分析
     *  registerForm.onsubmit 函数比较庞大,包含了很多 if-else 语句,这些语句需要覆盖所有
     *  的校验规则。
     *  registerForm.onsubmit 函数缺乏弹性,如果增加了一种新的校验规则,或者想把密码的长
     *  度校验从 6 改成 8,我们都必须深入 registerForm.onsubmit 函数的内部实现,这是违反开
     *放—封闭原则的。
     *   算法的复用性差,如果在程序中增加了另外一个表单,这个表单也需要进行一些类似的
     * 校验,那我们很可能将这些校验逻辑复制得漫天遍野。

策略模式如何优化表单的验证

策略模式的一些重要实现

1.Context :封装上下文,根据需要调用需要的策略,屏蔽外界对策略的直接调用,只对外提供一个接口,根据需要调用对应的策略;
2.Strategy :策略,含有具体的算法,其方法的外观相同,因此可以互相代替;
3.StrategyMap :所有策略的合集,供封装上下文调用;

封装我们的策略对象
var strategies = {
    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类
var Validator = function () {
    this.cache = [] // 保存校验规则
}
Validator.prototype.add = function (dom, rule, errorMsg) {
    var ary = rule.split(':') //把 strategy 和参数分开
    this.cache.push(function () { // 把校验的步骤用空函数包装起来,并且放入 cache
        var strategy = ary.shift() // 用户挑选的 strategy
        ary.unshift(dom.value); // 把 input 的 value 添加进参数列表
        ary.push(errorMsg); // 把 errorMsg 添加进参数列表
        return strategies[strategy].apply(dom, ary);
    })
}
Validator.prototype.start = function () {
    for (var i = 0, validatorFunc; validatorFunc = this.cache[i++];) {
        var msg = validatorFunc(); // 开始校验,并取得校验后的返回信息
        if (msg) { // 如果有确切的返回值,说明校验没有通过
            return msg;
        }
    }
};

Validator 类在这里作为 Context,负责接收用户的请求并委托给 strategy 对象。

完整的功能实现
<html>

<body>
    <form action="http:// xxx.com/register" id="registerForm" method="post">
        请输入邮箱号码:<input type="text" name="email"/>
        请输入用户名:<input type="text" name="userName" />
        请输入密码:<input type="text" name="password" />
        请输入手机号码:<input type="text" name="phoneNumber" />
        <button>提交</button>
    </form>
    <script>
        /***********************策略对象**************************/
        var strategies = {
            isNonEmpty: 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;
                }
            },
            isEmail:function(value,errorMsg){
                if(!/^[\w.\-]+@(?:[a-z0-9]+(?:-[a-z0-9]+)*\.)+[a-z]{2,3}$/.test(value)){
                    return errorMsg
                }
            }
        };
        /***********************Validator 类**************************/
        var Validator = function () {
            this.cache = [];
        };
        Validator.prototype.add = function (dom, rules) {
            var self = this;
            for (var i = 0, rule; rule = rules[i++];) {
                (function (rule) {
                    var strategyAry = rule.strategy.split(':');
                    var errorMsg = rule.errorMsg;
                    self.cache.push(function () {
                        var strategy = strategyAry.shift();
                        strategyAry.unshift(dom.value);
                        strategyAry.push(errorMsg);
                        return strategies[strategy].apply(dom, strategyAry);
                    });
                })(rule)
            }
        };
        Validator.prototype.start = function () {
            for (var i = 0, validatorFunc; validatorFunc = this.cache[i++];) {
                var errorMsg = validatorFunc();
                if (errorMsg) {
                    return errorMsg;
                }
            }
        };
        /***********************客户调用代码**************************/
        var registerForm = document.getElementById('registerForm');
        var validataFunc = function () {
            var validator = new Validator();
            validator.add(registerForm.userName, [{
                strategy: 'isNonEmpty',
                errorMsg: '用户名不能为空'
            }, {
                strategy: 'minLength:6',
                errorMsg: '用户名长度不能小于 10 位'
            }]);
            validator.add(registerForm.password, [{
                strategy: 'minLength:6',
                errorMsg: '密码长度不能小于 6 位'
            }]);
            validator.add(registerForm.phoneNumber, [{
                strategy: 'isMobile',
                errorMsg: '手机号码格式不正确'
            }]);
            validator.add(registerForm.email, [{
                strategy: 'isEmail',
                errorMsg: '邮箱不正确'
            }]);
            var errorMsg = validator.start();
            return errorMsg;
        }
        registerForm.onsubmit = function () {
            var errorMsg = validataFunc();
            if (errorMsg) {
                alert(errorMsg);
                return false;
            }
        };
    </script>
</body>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值