可以这样写:
var pS = function() {}
pS.prototype.calculate = function(salary) {
return salary * 4
}
var pA = function() {}
pA.prototype.calculate = function(salary) {
return salary * 3
}
var pB = function() {}
pB.prototype.calculate = function(salary) {
return salary * 2
}
var Bonus = function() {
this.salary = null // 初始薪水
this.strategy = null // 绩效等级的策略对象
}
Bonus.prototype.setSalary = function(salary) {
this.salary = salary
}
Bonus.prototype.setStrategy = function(strategy) {
this.strategy = strategy
}
Bonus.prototype.getBonus = function() {
return this.strategy.calculate(this.salary)
}
var bonus = new Bonus()
bonus.setSalary(10000)
bonus.setStrategy(new pS())
console.log(bonus.getBonus())
由于在js中,函数也是对象,所以还可以简写成这样:
var strategies = {
'S': function(salary) {
return salary * 4
},
'A': function(salary) {
return salary * 3
},
'B': function(salary) {
return salary * 2
},
}
var getBonus = function(level, salary) {
return strategies[level](salary)
}
console.log(getBonus('S', 10000))
我们接着通过写一个表单验证功能来体会一下策略模式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js策略模式2</title>
</head>
<body>
<form action="www.google.co.uk" method="post" id="registerForm">
Username: <input type="text" name="username">
Password: <input type="password" name="password">
Phone: <input type="text" name="phoneNumber">
<button>Submit</button>
</form>
<script type="text/javascript">
var registerForm = document.getElementById('registerForm')
registerForm.onsubmit = function () {
if (registerForm.username.value === '') {
alert('username required!')
return false
}
if (registerForm.password.value.length < 6) {
alert('password length less than 6 not allowed')
return false
}
if (!/^1[3|5|7|8][0-9]{9}$/.test(registerForm.phoneNumber.value)) {
alert('phone number not valid')
return false
}
}
</script>
</body>
</html>
上述代码可以完成功能,但是不够优雅,并且可扩展性不强,我们下面用策略模式来改造一下:
1.首先要有策略对象:
// 1.策略对象 一系列算法一系列业务逻辑
var strategies = {
isNotEmpty: function(value, errMsg) {
if (value == '') {
return errMsg
}
},
minLength: function(value, length, errMsg) {
if (value.length <= 6) {
return errMsg
}
},
isMobile: function(value, errMsg) {
if (!/^1[3|5|7|8][0-9]{9}$/.test(value)) {
return errMsg
}
}
}
我们假设现在有一个封装好的验证类Validator(其实还没有,我们现在先假设有:
var registerForm = document.getElementById('registerForm')
// 验证方法
var validateFun = function() {
var validator = new Validator()
// 添加验证规则
validator.add(registerForm.username, 'isNotEmpty', 'username is required!')
validator.add(registerForm.password, 'minLength:6', 'password length less than 6 not allowed!')
validator.add(registerForm.phoneNumber, 'isMobile', 'phone number not valid!')
// 开启验证
var errMsg = validator.start()
return errMsg
}
registerForm.onsubmit = function() {
var errMsg = validateFun()
if (errMsg) {
alert(errMsg)
return false
}
}
我们封装一个验证器对象:
// 2. 封装验证器对象
var Validator = function() {
// 保存验证规则的数组
this.cache = []
}
Validator.prototype.add = function(dom, rule, errMsg) {
var array = rule.split(':')
this.cache.push(function() {
// 取出验证规则
var strategy = array.shift()
array.unshift(dom.value)
array.push(errMsg)
return strategies[strategy].apply(null, array)
// return strategies[strategy](...array) es6写法 也可以
})
}
Validator.prototype.start = function() {
for (var i = 0, vaFunc; vaFunc = this.cache[i++];) {
var msg = vaFunc()
if (msg) {
return msg
}
}
}
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js策略模式2</title>
</head>
<body>
<form action="www.google.co.uk" method="post" id="registerForm">
Username: <input type="text" name="username">
Password: <input type="password" name="password">
Phone: <input type="text" name="phoneNumber">
<button>Submit</button>
</form>
<script type="text/javascript">
var registerForm = document.getElementById('registerForm')
// 1.策略对象 一系列算法一系列业务逻辑
var strategies = {
isNotEmpty: function (value, errMsg) {
if (value == '') {
return errMsg
}
},
minLength: function (value, length, errMsg) {
if (value.length <= 6) {
return errMsg
}
},
isMobile: function (value, errMsg) {
if (!/^1[3|5|7|8][0-9]{9}$/.test(value)) {
return errMsg
}
}
}
// 2. 封装验证器对象
var Validator = function () {
// 保存验证规则的数组
this.cache = []
}
Validator.prototype.add = function (dom, rule, errMsg) {
var array = rule.split(':')
this.cache.push(function () {
// 取出验证规则
var strategy = array.shift()
array.unshift(dom.value)
array.push(errMsg)
// return strategies[strategy].apply(null, array)
return strategies[strategy](...array) // es6写法 也可以
})
}
Validator.prototype.start = function () {
for (var i=0, vaFunc; vaFunc = this.cache[i++];) {
var msg = vaFunc()
if (msg) {
return msg
}
}
}
// 验证方法
var validateFun = function () {
var validator = new Validator()
// 添加验证规则
validator.add(registerForm.username, 'isNotEmpty', 'username is required!')
validator.add(registerForm.password, 'minLength:6', 'password length less than 6 not allowed!')
validator.add(registerForm.phoneNumber, 'isMobile', 'phone number not valid!')
// 开启验证
var errMsg = validator.start()
return errMsg
}
registerForm.onsubmit = function () {
var errMsg = validateFun()
if (errMsg) {
alert(errMsg)
return false
}
}
</script>
</body>
</html>