【Javascript】策略模式

定义:定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。

解决的问题:在多重算法相似的情况下,使用if...else或单纯使用硬编码方式导致新增一种方法都需要修改封装算法类的源代码,更换查找方法也需要修改客户端调用的代码,维护较为困难。

何时使用:系统中有许多类,而区分它们的只是它们的直接行为,算法需要自由切换。

如何实现:将这些算法封装成一个一个的类,任意地替换。

优点:算法可以自由切换;消除了一些if...else语句  扩展性良好;增加一个策略只需要实现接口。

缺点:策略类会增多;所有策略类都需要对外暴露;通信开销大,耦合度高。


示例:使用策略模式来实现表单验证

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>策略模式</title>
</head>
<body>
    <form action="xxx.com" method="post" id="registerForm">
        请输入用户名:<input type="text" name="userName">
        请输入密码:<input type="password" name="password">
        请输入手机号码:<input type="text" name="phoneNumber">
        <button>提交</button>
    </form>
<script>
    var registerForm = document.getElementById('registerForm')
    //  使用策略模式封装
    var strategies = {
        isNonEmpty: function (value, errorMsg) {
            if (value == '') {
                return errorMsg
            }
        },
        minLength: function (value, length, errorMsg) {
            if (value.length < 6) {
                return errorMsg
            }
        },
        isMobile: function (value, errorMsg) {
            if (!/^1[3|5|8][0-9]{9}$/.test(value)) {
                return errorMsg
            }
        }
    }

    //假设有一个验证类 Validator new Validator()
    var validateFun = function () {
        var validator = new Validator()
        //添加验证规则
        validator.add(registerForm.userName, 'isNonEmpty', '用户名不能为空')
        validator.add(registerForm.password, 'minLength:6', '密码不能小于6位')
        validator.add(registerForm.phoneNumber, 'isMobile', '手机号码格式不正确')
        //开启验证
        var errorMsg = validator.start()
        return errorMsg
    }

    registerForm.onsubmit = function () {
        var errorMsg = validateFun()
        if (errorMsg) {
            alert(errorMsg)
            return false
        }
    }

    //封装策略类
    var Validator = function () {
        //保存验证规则的数组
        this.cache = []
    }

    Validator.prototype.add = function (dom, rule, errorMsg) {
        var ary = rule.split(':')
        this.cache.push(function () {
            var strategy = ary.shift() //弹出用户选择的验证规则
            ary.unshift(dom.value)  //把dom的值放在首位
            ary.push(errorMsg)
            //ES5写法  return strategies[strategy].apply(dom, ary)
            return strategies[strategy](...ary)
        })
    }

    Validator.prototype.start = function () {
        for (var i = 0, vaFunc; vaFunc = this.cache[i++];) {
            var msg = vaFunc()
            if (msg) {
                return msg
            }
        }
    }

</script>
</body>
</html>

 

 

以上仅作为个人学习笔记。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值