JS设计模式之 ------ 策略模式

将不变的部分和变化的部分隔开是每个设计模式的主题

什么是策略模式?
策略模式是将不同算法进行合理的分类与单独封装,从而让不同算法之间可以互相替换而不会影响到算法的使用者。

接下来我们用一个简单的例子来说明下策略模式:
eg: 根据传入的分数来判断当前分数的状态是不及格,及格了,还是优秀。

// 一般写法
const score1 = 59;
function judgeScore(score) {
    if(score < 60 ) {
        return '不及格'
    }else if(score > 60 && score < 85) {
        return '及格了'
    }else if(score >= 85) {        
    	return '优秀'
    }
}

judgeScore(58); // 不及格
judgeScore(66);	// 及格
judgeScore(88);	// 优秀

如上所示:
我们需要通过多个if…else…对传进来的分数进行判断,如果分的更细的话, 那代码就会显的非常冗余,不好维护。

接下来我们看看用策略模式实现的效果:

// 策略模式
let strategies = {
    noPass: function(score, tipText) {
        if(score < 60) {
            return tipText;
        }
    },

    pass: function(score, tipText) {
        if(score > 60 && score < 85) {
            return tipText
        }    
    },

    excellent: function(score, tipText) {
        if(score >= 85) {
            return tipText;
        }
    }
}

function judgeScore(score) {
    let noPass = strategies['noPass'](score, '不及格');
    let pass = strategies['pass'](score, '及格');
    let excellent = strategies['excellent'](score, '优秀');
    let res = noPass || excellent || pass;
    return res;
}

judgeScore(58); // 不及格
judgeScore(66);	// 及格
judgeScore(88);	// 优秀

策略模式最经典的是应用在表单验证上:

// 一般写法
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <form action="xxxx" id="myForm">
        <input type="text" placeholder="userName" name="userName" />
        <input type="text" placeholder="password" name="password"/>
        <button>登录</button>
    </form>
    <script>
        const myForm = document.getElementById('myForm');
        myForm.onsubmit = function () {
            if(myForm.telephone.value === '') {
                console.log('电话号码不能为空');
                return false;
            }else if(myForm.userName.password === '') {
                console.log('密码不能为空');
                return false;
            }
        }
    </script>
</body>

</html>

如上述代码:
同样代码很好理解, 但是每增加一个表单项,我们就需要增加一个if语句。

接下里我们应用策略模式来改造一下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <form action="xxxx" id="myForm">
        <input type="text" placeholder="telephone" name="telephone" />
        <input type="text" placeholder="至少8位数" name="password"/>
        <button>登录</button>
    </form>
    <script>
        const myForm = document.getElementById('myForm');
        let strategies = {
            isNotEmpty: function(value, tipText) {
                if(vlaue === '') {
                    return tipText;
                }
            },
            minLength: function(value, length, tipText) {
                debugger
                if(value.length < length) {
                    return tipText;
                }
            },
            matchTelephone: function(value, tipText) {
                if(!/^1[3|4|5|7|8|9][0-9]{9}$/.test(value)) {
                    return tipText;
                }
            }
        }

        class Validator {
            constructor(strategies) {
                this.strategies = strategies;
                this.cache = [];
            }

            add(dom, rule, tipText) {  // add(dom, 'minLength:8', '***')
                this.cache.push(function() {
                    const r = rule.split(':');
                    const strategy = r.shift();
                    const params = [...r, tipText];
                    return strategies[strategy](dom, ...params);
                })
            }

            startValidate() {
                for(let i = 0; i < this.cache.length; i++) {
                    let msg = this.cache[i]();
                    if(msg) {
                        return msg;
                    }
                }
            }
        }

        let validateFunc = function() {
            let validator = new Validator();
            validator.add(myForm.telephone.value, 'matchTelephone', '请输入正确的手机号格式');
            validator.add(myForm.password.value, 'minLength:8', '密码至少8位数');
            let tipText = validator.startValidate();
            return tipText;
        }

        myForm.onsubmit = function(e) {
            const tipText = validateFunc();
            if(tipText) {
                console.log(tipText);
                return false // 有错误,阻止表单提交
            }
        }


    </script>
</body>

</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值