设计模式 - 策略模式

Posted wangrenmeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式 - 策略模式相关的知识,希望对你有一定的参考价值。

策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。

策略模式定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。

 将不变的部分和变化的部分隔开是每个设计模式的主题。策略模式的目的就是将算法的实现和算法的使用分离开来。

 

策略模式包含三个角色:

  Context:环境类

  Strategy:抽象策略类

  ConcreteStrategy:具体抽象类

 

例子:

 策略模式在js中最常见、使用最多的就是多重表单校验功能

  1 <html>
  2 <head>
  3     <title>策略模式-校验表单</title>
  4     <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  5 </head>
  6 
  7 <body>
  8     <form id="registerForm" method="post" action="">
  9         用户名:
 10         <input type="text" name="userName"> 密码:
 11         <input type="text" name="password"> 手机号码:
 12         <input type="text" name="phoneNumber">
 13         <button type="submit">提交</button>
 14     </form>
 15 
 16     <script>
 17         // 策略对象
 18         let strategies = 
 19             isNoEmpty: function (value, errorMsg) 
 20                 if (value === ‘‘) 
 21                     return errorMsg;
 22                 
 23             ,
 24             isNoSpace: function (value, errorMsg) 
 25                 if (value.trim() === ‘‘) 
 26                     return errorMsg;
 27                 
 28             ,
 29             minLength: function (value, length, errorMsg) 
 30                 if (value.trim().length < length) 
 31                     return errorMsg;
 32                 
 33             ,
 34             maxLength: function (value, length, errorMsg) 
 35                 if (value.length > length) 
 36                     return errorMsg;
 37                 
 38             ,
 39             isMobile: function (value, errorMsg) 
 40                 if (!/^1[3456789]\d9$/.test(value)) 
 41                     return errorMsg;
 42                 
 43             
 44         
 45 
 46 
 47         class Validator
 48             constructor()
 49                 this.cache = [];
 50             
 51         
 52         
 53 
 54         Validator.prototype.add = function (dom, rules) 
 55             let self = this;
 56             for (let i = 0, rule; rule = rules[i++];) 
 57                 (function (rule) 
 58                     var strategyAry = rule.strategy.split(‘:‘);
 59                     var errorMsg = rule.errorMsg;
 60                     self.cache.push(function () 
 61                         var strategy = strategyAry.shift();
 62                         strategyAry.unshift(dom.value);
 63                         strategyAry.push(errorMsg);
 64                         return strategies[strategy].apply(dom, strategyAry);
 65                     )
 66                 )(rule)
 67             
 68         ;
 69 
 70         Validator.prototype.start = function () 
 71             for (let i = 0, validatorFunc; validatorFunc = this.cache[i++];) 
 72                 let errorMsg = validatorFunc();
 73                 if (errorMsg) 
 74                     return errorMsg;
 75                 
 76             
 77         ;
 78 
 79         
 80         let validataFunc = function () 
 81             var validator = new Validator();
 82             // 用户名
 83             validator.add(registerForm.userName, [
 84                 strategy: ‘isNoEmpty‘,
 85                 errorMsg: ‘用户名不可为空‘
 86             , 
 87                 strategy: ‘isNoSpace‘,
 88                 errorMsg: ‘不允许以空白字符命名‘
 89             , 
 90                 strategy: ‘minLength:2‘,
 91                 errorMsg: ‘用户名长度不能小于2位‘
 92             ]);
 93 
 94             //密码
 95             validator.add(registerForm.password, [
 96                 strategy: ‘minLength:6‘,
 97                 errorMsg: ‘密码长度不能小于6位‘
 98             ]);
 99 
100             //手机号
101             validator.add(registerForm.phoneNumber, [
102                 strategy: ‘isMobile‘,
103                 errorMsg: ‘请输入正确的手机号码格式‘
104             ]);
105             let errorMsg = validator.start();
106             return errorMsg;
107         
108 
109 
110         // 调用代码
111         let registerForm = document.getElementById(‘registerForm‘);
112         registerForm.onsubmit = function () 
113             let errorMsg = validataFunc();
114             if (errorMsg) 
115                 alert(errorMsg);
116                 return false;
117             
118         
119     </script>
120 </body>
121 
122 </html>

 

优点

  1.策略模式可以有效的避免多层判断语句

  2.策略模式讲每个算法独立封装,易于理解和拓展,对"开闭原则"完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。

  3.策略模式中的算法也可以复用在系统的其它地方,从而避免许多重复的复制粘贴工作。

缺点

  1.要使用策略模式,必须要知道全部的策略类,这样才能找到合适的策略类

  2.策略模式会定义很多策略对象和策略类

 

策略模式与js

  在JS中除了使用类来封装算法之外,也可以通过函数来实现。实际上在JS中,策略模式已经融合到了语言本身当中,我们经常使用函数来封装不同的行为和算法,并且将他传入到另一个函数中。没当我们调用这些函数的时候,不同的函数会返回不同的结果,所以其实策略模式在JS中就成了一种隐形的模式。

以上是关于设计模式 - 策略模式的主要内容,如果未能解决你的问题,请参考以下文章

策略模式(Strategy Pattern)

设计模式中的多态——策略模式详解

spring中如何使用策略模式

设计模式——策略模式

java设计模式---策略模式(案例解析)

设计模式策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )