设计模式学习(三):策略模式
策略模式
就是定义一系列算法,将他们封装起来,这些算法对应不同的策略实现。基于策略模式的程序,一般至少两部分组成,一部分是一组策略类,里面是具体的算法;第二个部分是环境类Context,Context接受客户的请求,随后把请求委托给某一个策略类。
策略模式的优缺点
优点:
-
策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重条件选择语句。
-
策略模式提供了对开放—封闭原则的完美支持,将算法封装在独立的strategy 中,使得它们易于切换,易于理解,易于扩展。
-
策略模式中的算法也可以复用在系统的其他地方,从而避免许多重复的复制粘贴工作。
缺点:
- 要使用策略模式,必须了解所有的策略,必须了解各个策略 之间的不同点,这样才能选择一个合适的策略,这是违反最少知识原则的。
举个例子:用策略模式实现一个表单校验
<html>
<body>
<section>
请输入用户名:<input type="text" name="userName" id="userName"/>
请输入密码:<input type="text" name="password" id="passWord"/>
请输入手机号码:<input type="text" name="phoneNumber" id="phoneNumber"/>
<button id="submit">提交</button>
</section>
</body>
<script>
// 1、将校验逻辑封装成策略对象
let strategies = {
// 不为空
isNonEmpty: (value, errorMsg) => {
if (!value) {
return errorMsg
}
},
// 限制最小长度
minLength: (value, length, errorMsg) => {
if ( value.length < length ){
return errorMsg
}
},
// 是否是手机号
isMobile: (value, errorMsg) => {
if (!/(^1[0-9][0-9]{9}$)/.test( value )){
return errorMsg
}
}
}
// 2、维护一个实施校验规则的类
class Validator {
constructor () {
// 保存校验规则
this.validList = []
}
add (value, rules, errorMsg) {
let self = this
rules.forEach(ele => {
let strategyAry = ele.strategy.split( ':' )
let errorMsg = ele.errorMsg
self.validList.push(function(){
let strategy = strategyAry.shift()
strategyAry.unshift(value)
strategyAry.push( errorMsg )
const msg = strategies[strategy].apply(self, strategyAry)
return msg
})
})
}
start () {
let errorMsg
this.validList.some(ele => {
let msg = ele()
if ( msg ){
return errorMsg = msg
}
})
return errorMsg
}
}
// 调用校验规则
const userName = document.getElementById('userName')
const passWord = document.getElementById('passWord')
const phoneNumber = document.getElementById('phoneNumber')
const submit = document.getElementById('submit')
let validataFunc = function(){
let validator = new Validator()
validator.add(userName.value, [{
strategy: 'isNonEmpty',
errorMsg: '用户名不能为空'
}, {
strategy: 'minLength:2',
errorMsg: '用户名长度不能小于2位'
}])
validator.add(passWord.value, [{
strategy: 'minLength:6',
errorMsg: '密码长度不能小于6位'
}])
validator.add(phoneNumber.value, [{
strategy: 'isMobile',
errorMsg: '手机号码格式不正确'
}])
let errorMsg = validator.start()
return errorMsg
}
submit.onclick = function(){
let errorMsg = validataFunc()
if ( errorMsg ){
alert ( errorMsg )
return false
}
}
</script>
</html>
浙公网安备 33010602011771号