★策略模式★

策略模式

我们在编程的时候,经常会遇到一套算法,具体使用哪个算法需要看情况。但是即使不用这一套算法,也要预先定义。此时为了是这一套算法易于维护,可以使用策略模式

比如说用户输入购买的汽油编号和加油升数,用来显示实时价格

  • 89号汽油   5.35元/升
  • 92号汽油   5.55元/升
  • 95号汽油   5.75元/升
  • 0号柴油    5.2元/升

先看非设计模式的算法

 1 <script>
 2 function calc(type, amount) {
 3     if (type == 89) {
 4         return amount * 5.3-+5;
 5     } else if (type == 92) {
 6         return amount * 5.55;
 7     } else if (type == 95) {
 8         return amount * 5.75;
 9     } else if (type == 0) {
10         return amount * 5.2
11     }
12 }
13 var jiage = calc(0, 100)
14 console.log(jiage)
15 </script>

 

 

 

 

此时我们想一下,这就是所谓的一套算法,算的是什么,算的是价格。根据型优品型号号来算钱。所以我们可以以这个为出发点来设计策略模式

 1 <script>
 2     // 策略清单
 3     var stra = {
 4         "89": function(amount) {
 5             return amount * 5.35;
 6         },
 7         "92": function(amount) {
 8             return amount * 5.55;
 9         },
10         "95": function(amount) {
11             return amount * 5.75;
12         },
13         "0": function(amount) {
14             return amount * 5.2;
15         },
16     };
17     // 选择一种策略
18     var jiage = stra['92'](100)
19     console.log(jiage)
20 </script>

 

 

 

 

策略模式可以用于组合一系列算法,也可以组合一系列业务

比如我们需要通过成绩等级来计算学生的最终得分:

 1 <script>
 2     // 映射关系
 3     var levelMap = {
 4         S: 10,
 5         A: 8,
 6         B: 6,
 7         C: 4
 8     };
 9     // 组策略
10     var scoreLevel = {
11         // 基础分数值
12         baseScore: 80,
13         S: function() {
14             return this.baseScore + levelMap['S']
15         },
16         A: function() {
17             return this.baseScore + levelMap['A']
18         },
19         B: function() {
20             return this.baseScore + levelMap['B']
21         },
22         C: function() {
23             return this.baseScore + levelMap['C']
24         }
25     };
26     //获取策略
27     function getScore(level) {
28         // 返回的成绩
29         return scoreLevel[level] ? scoreLevel[level]() : 0;
30     }
31     console.log(getScore("S"))    //90
32     console.log(getScore("A"))    //88
33     console.log(getScore("B"))    //86
34     console.log(getScore("C"))    //84
35     console.log(getScore("D"))    //0
36 </script>

 

 

 

比较经典的策略者模式就是关于表单校验的逻辑

 1 <script>
 2     // 错误信息
 3     var errorMessage = {
 4         default: "当前的输入格式不正确",
 5         minLength: "输入的数据长度不够",
 6         isNumber: "输入数据类型不是数字",
 7         required: "内容不能为空"
 8     }
 9     // 规则集合
10     var rules = {
11         // 最大长度
12         minLength: function(value, length, errorMsg) {
13             if (value.length < length) {
14                 return errorMsg || errorMessage['minLength'];
15             }
16         },
17         // 数字类型的校验
18         isNumber: function(value, errorMsg) {
19             if (!/\d+/.test(value)) {
20                 return errorMsg || errorMessage("isNumber")
21             }
22         },
23         // 内容不能为空
24         required: function(value, errorMsg) {
25             if (value == '') {
26                 return errorMsg || errorMessage("required")
27             }
28         }
29     };
30     // 校验构造函数
31     function Validator() {
32         this.items = []
33     };
34     Validator.prototype.add = function(value, rule, errorMsg) {
35             // 接受参数
36             var arg = [value];
37             // 超出length的提示语信息内容
38             if (rule.indexOf('minLength') !== -1) {
39                 var temp = rule.split(":");
40                 arg.push(temp[1]);
41                 // 强行给rule赋值为temp第0项的逻辑
42                 rule = temp[0]
43             };
44             arg.push(errorMsg);
45             // 存储校验参数
46             this.items.push(function() {
47                 // rules是外面的规则集合,rule是函数的形参
48                 return rules[rule].apply(null, arg)
49             })
50 
51         }
52         // 执行校验
53     Validator.prototype.start = function() {
54         for (var i = 0; i < this.items.length; i++) {
55             // 执行校验逻辑
56             var ret = this.items[i]()
57             if (ret) {
58                 console.log(ret)
59             }
60         }
61     }
62     var validate = new Validator();
63     validate.add("ccc", "isNumber", "数据类型为数字")
64     validate.add("123", "minLength:5", '最少输入5位')
65     var ret = validate.start()
66 </script>

 

 

posted @ 2021-09-24 16:45  keyeking  阅读(29)  评论(0编辑  收藏  举报