策略模式指的是定义一系列算法,把他们一个个封装起来,目的就是将算法的使用和算法的实现分离开来。stragey就是值为函数的变量,同时它还可以用来封装一系列的规则,比如常见的表单验证规则,只要这些规则指向的目标一致,并且可以被替换使用,那么就可以用策略模式来封装它们。
优点
- 算法可以自由切换,避免了使用多层条件判断,增加了扩展性
缺点
例子
- 写表单验证经常无止境的if…else写法,意识到这种写法不靠谱,于是我把检验规则放在一个对象中,在函数中对它进行控制,把规则与实现进行了分离,每次只需要在封装的规则中去修改配置。在后面的多种场景都用这种方法,解决了频繁使用if…else的问题,当第一次接触倒策略模式才知道这种写法也算策略模式。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 
 | const rules = {cover_img: {
 must: false,
 msg: '请上传封面图片',
 val: ''
 },
 name: {
 must: true,
 msg: '姓名不能为空',
 val: ''
 },
 sex: {
 must: true,
 msg: '请填写性别',
 val: ''
 },
 birthday: {
 must: false,
 msg: '请选择生日',
 val: ''
 },
 }
 function verify(){
 for(const key in rules){
 if(rules[key].must&&!rules[key].val){
 console.log(rules[key].msg)
 }
 }
 }
 verify()
 
 | 
对于分支语句的优化,工厂方法模式,状态模式,策略模式。
表单验证例子:高阶函数
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 
 | <form action="http://xxx.com/register" id="registerForm" method="post">请输入用户名:<input type="text" name="userName"></input>
 输入密码:<input type="text" name="password">
 输入手机号码:<input type="text" name="phoneNumber">
 <button>提交</button>
 </form>
 <script>
 //策略对象
 let strategies = {
 isNonEmpty:function(value,errorMsg){
 if(value===''){
 return errorMsg
 }
 },
 minLength:function(value,length,errorMsg){
 if(value.length<length){
 return errorMsg
 }
 },
 isMobile:function(value,errorMsg){
 if(!/(^1[3][5][8][0-9]{9}$)/.test(value)){
 return errorMsg
 }
 }
 }
 //客户调用代码
 let registerForm = documetn.getElementById('registerForm')
 let validatorFunc = function(){
 let validator = new Validator()
 validator.add(registerForm.userName,[{
 strategy:'isNonEmpty',
 errorMsg:'用户名不为空'
 },{
 strategy:'minLength:6',
 errorMsg:'用户名长度不能小于10位'
 }]);
 validator.add(registerForm.password,[{
 strategy:'minLength:6',
 errorMsg:'用户长度不能小于10位'
 }])
 validator.add(registerForm.phoneNumber,[{
 strategy:'isMobile',
 errorMsg:'手机号码格式不正确'
 }])
 }
 //验证类
 Validator = function(){
 this.cache=[];
 }
 Validator.prototype.add = function(dom,rules){
 var self = this
 for(let i=0,rule;rule = rules[i++];){
 let self = this
 (function(rule){
 let strategyAry = rule.strategy.split(':')
 let errorMsg = rule.errorMsg
 self.cache.push(function(){
 let strategy = strategyAry.shift()
 strategyAry.unshift(dom.value)
 strategyAry.push(errorMsg)
 return strategies[strategy].apply(dom,strategyAry)
 })
 })(rule)
 }
 }
 Validator.prototype.start = function(){
 for(let i=0,validatorFunc;validatorFunc = this.caches[i++];){
 let errorMsg = validatorFunc()
 if(errorMsg){
 return errorMsg
 }
 }
 }
 </script>
 
 | 
工厂方法模式:是一种创建型模式,最终目的是创建对象
状态模式和策略模式都是行为性模式,在状态模式中,核心是对状态的控制来决定表现行为,所以状态之间通常不能相互替代,否则将产生不同的行为结果。