js设计模式总结-策略模式

策略模式

要解决的问题

当解决一个问题有多种方法时,选择使用哪种方法时就少不了要用大量的if语句进行判断,如果将这些方法的实现和判断语句放在一起实现就会产生问题,
比如增加一种的新的方法时,就不得不再去写一条if语句,这不符合开闭原则,也不方便复用,因此策略模式主要解决的是算法的实现算法的使用的过度耦合问题。

实现原理

将每个算法的实现封装起来,并可以相互替换(因为它们有共同的目的),通过统一的上下文调用,一方面解决了耦合问题,另一方面增强了代码的复用能力

实践中的应用

表单的验证

表单验证涉及到多个判断语句,一般我们会这样实现

    var form = document.getElementById('myform')
    form.onsubmit = function() {
        if (form.username.value === '') {
            alert('请输入用户名')
            return false
        }
        if (form.password.value === '') {
            alert('请输入密码')
            return false
        }

        if (form.password.value.length < 8) {
            alert('密码不小于8位')
            return false
        }
    }

当增加新的字段或者变换新的验证规则时就不得不去修改if语句或者增加新的if语句,而且当别的表单也需要这样验证时没法复用。
所以采用策略模式来实现

    // 策略对象,封装一系列的策略
    var rules = {
        NOT_EMPTY: function(value, errorMsg) {
            value = '' + value
            if (value === '') {
                return errorMsg
            }
        },
        NOT_LESS: function(value, length, errorMsg) {
            value = '' + value
            if (value.length < length) {
                return errorMsg
            }
        }
    }

    // 验证器的实现
    var Validator = function(rules) {
        this.rules = rules
        // 保存着验证规则
        this.cache = []
    }
    // 添加规则
    Validator.prototype.add = function(value, rule, errorMsg) {
        var ruleArray = rule.split(':')
        var self = this
        if (ruleArray.length === 1) {
            // 利用闭包来保存外部的值
            this.cache.push(function() {
                return self.rules[rule](value, errorMsg)
            })
        } else if (ruleArray.length === 2) {
            this.cache.push(function() {
                return self.rules[ruleArray[0]](value, ruleArray[1], errorMsg)
            })
        }
    }

    Validator.prototype.start = function() {
        var errorMsg = ''
        for (var r = 0; r < this.cache.length; r++) {
            var errorMsg = this.cache[r]()
            if (errorMsg) {
                return errorMsg
            }
        }
    }
    var form = document.getElementById('myform')
    form.onsubmit = function() {
        var v = new Validator(rules)
        v.add(form.username.value, 'NOT_EMPTY', '请输入用户名')
        v.add(form.password.value, 'NOT_LESS:8', '密码不少于8位')
        var errorMsg = v.start()
        if (errorMsg) {
            alert(errorMsg)
            return false
        }
    }
    

根据上述代码,如果我们添加新的验证规则,只需要在rules添加新的验证函数就可,如果添加新的字段,只需要add进Validator中即可,实现了算法的实现与使用的分离,符合开闭原则。

posted @ 2016-11-07 14:49  Xinyu520  阅读(213)  评论(0)    收藏  举报