翼度科技»论坛 编程开发 JavaScript 查看内容

结构型:策略模式

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
定义


  定义一系列的算法,将他们一个个封装起来,使他们直接可以相互替换。 

  • 算法:就是写的逻辑可以是你任何一个功能函数的逻辑
  • 封装:就是把某一功能点对应的逻辑给抽出来
  • 可替换:建立在封装的基础上,这些独立的算法可以很方便的替换
通俗的理解就是,把你的算法(逻辑)封装到不同的策略中,在不同的策略中是互相独立的,这样我们封装的每一个算法是可以很方便的复用。策略模式主要解决在有多种情况下,使用 if...else 所带来的复杂和难以维护
它的优点是算法可以自由切换,同时可以避免多重if...else判断,且具有良好的扩展性。
看一个真实场景--最简单的策略模式

我们有一个根据不同的类型返回不同价格的一个方法
  1. function getPrice (type) {
  2.   if (type === 1) {
  3.     // code 或许每个分支要处理很多逻辑
  4.   }
  5.   if (type === 2) {
  6.     // code
  7.   }
  8.   if (type === 3) {
  9.     // code
  10.   }
  11.   if (type === 4) {
  12.     // code
  13.   }
  14.   if (type === 5) {
  15.     // code
  16.   }
  17.   if (type === 6) {
  18.     // code
  19.   }
  20.   if (type === 7) {
  21.     // code
  22.   }
  23. }
复制代码
从代码上看确实没有什么问题,但是如果需要增加一种新的类型,我们就会一个if判断,导致这个方法可能会过于庞大,后期不太好维护。
其次代码每次都是从上往下走,可能存在前面某个判断出现问题(如某个 && 的判断变量null 之类),导致后面的代码没有走,所以这种影响还是挺大的。
用了这么多 if-else,我们的目的是什么?是不是就是为了把传进来的参数的值-对应的处理函数,这个映射关系给明确下来?在 JS 中我们可以通过对象映射的形式来做,如下代码
  1. /*
  2. 1、把 if else 的代码快优化为一个一个的映射
  3. 2、把if else 里面的逻辑抽离成一个独立的函数,这样方便其他模块或者分支使用
  4. */
  5. function getPrice (type) {
  6.   const actionMap = {
  7.     '1': action1,
  8.     '2': action2,
  9.     '3': action3,
  10.     '4': action4,
  11.     '5': action5,
  12.     '6': action6,
  13.     '7': action7,
  14.   }
  15.   const params = {}
  16. return  actionMap[type](params)
  17. }
复制代码
这种代码结构变得易读、易维护。
这就是最简单的策略模式
模拟表单校验逻辑

如果不把逻辑封装起来,那么我们在判断的时候会写很多的if else,如写一个很简单的表单的校验
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
  6.   <meta content="yes" name="apple-mobile-web-app-capable">
  7.   <meta content="black" name="apple-mobile-web-app-status-bar-style">
  8.   <meta content="telephone=no,email=no" name="format-detection">
  9.   <meta name="App-Config" content="fullscreen=yes,useHistoryState=yes,transition=yes">
  10.   <meta name="viewport" content="width=device-width, initial-scale=1">
  11.   <title></title>
  12.   <link href="css/style.css" rel="stylesheet">
  13. </head>
  14. <body>
  15.   
  16.     <form action="" id="form">
  17.       姓名:<input type="text" id="username">
  18.       密码:<input type="password" id="password1">
  19.       确认密码:<input type="password" id="password2">
  20.       手机号:<input type="text" id="phone">
  21.       <input type="submit" value="提交">
  22.     </form>
  23.   
  24.   
  25. </body>
  26. </html>
复制代码
只是4个字段,我们用了 6个if判断来做相关的逻辑校验。
仔细观察发现很多校验的逻辑是一致的,所以我们可以把他封装起来,用策略模式修改成如下
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
  6.   <meta content="yes" name="apple-mobile-web-app-capable">
  7.   <meta content="black" name="apple-mobile-web-app-status-bar-style">
  8.   <meta content="telephone=no,email=no" name="format-detection">
  9.   <meta name="App-Config" content="fullscreen=yes,useHistoryState=yes,transition=yes">
  10.   <meta name="viewport" content="width=device-width, initial-scale=1">
  11.   <title></title>
  12.   <link href="css/style.css" rel="stylesheet">
  13. </head>
  14. <body>
  15.   
  16.     <form action="" id="form">
  17.       姓名:<input type="text" id="username">
  18.       密码:<input type="password" id="password1">
  19.       确认密码:<input type="password" id="password2">
  20.       手机号:<input type="text" id="phone">
  21.       <input type="submit" value="提交">
  22.     </form>
  23.   
  24.   
  25. </body>
  26. </html>
复制代码
下次我们增加其他的字段也只是增加规则而已,而不会去修改判断的业务逻辑。
小结



  • 将一个个算法封装起来,提高代码复用率,减少代码冗余
  • 策略模式可看作为if/else判断的另一种表现形式,在达到相同目的的同时,极大的减少了代码量以及代码维护成本
  • 策略模式有效避免多重条件选择语句,将算法封装在策略中 

来源:https://www.cnblogs.com/longbensong/p/17260684.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具