1. 将定义的一组算法封装起来,使其相互之间可以替换,封装的算法具有一定独立性,不会随客户端变化而变化(避免大量的 if elseswith case);

  2. 适用场景:

    • 行为切换:系统有很多类,这些类的区别仅仅在于它们的 行为不同;使用策略模式,可以 动态地用户对象 在这些行为中选择一个行为;
    • 算法选择:系统中需要 动态地几种算法(算法 就是 策略)中 选择一种
  3. 优点:

    • 开闭原则:策略模式 提供了对 开闭原则 的支持,可以在不修改原有系统的基础上,选择不同的行为,也可以 额外扩展其它行为
    • 避免代码冗余:可以 避免使用多重条件判定语句;可以避免出现大量的 if … else … 语句,switch 语句等;
    • 安全保密:策略模式可以 提高算法的 保密性安全性; 在终端使用策略时,只需要知道策略的作用即可,不需要知道策略时如何实现的;
  4. 缺点:

    • 策略类选择:客户端 必须 知道所有的 策略类,并且自行决定 使用哪个策略类
    • 增加复杂性:如果系统很复杂,会 产生很多策略类

类图

bad

class Customer {
  constructor(type) {
    this.type = type;
  }
  pay(amount) {
    if (this.type == '会员顾客') {
      return amount * .9;
    } else if (this.type == 'VIP顾客') {
      return amount * .8;
    }
    return amount;
  }
}

let c1 = new Customer('普通顾客');
console.log(c1.pay(100)); // 100
let c2 = new Customer('会员顾客');
console.log(c2.pay(100)); // 90
let c3 = new Customer('VIP顾客');
console.log(c3.pay(100)); // 80

good

class Customer {
  constructor(kind) {
    this.kind = kind;
  }
  cost(amount) {
    return this.kind.discount(amount);
  }
}

class Normal {
  discount(amount) {
    return amount;
  }
}
class Member {
  discount(amount) {
    return amount * .9;
  }
}
class VIP {
  discount(amount) {
    return amount * .8;
  }
}

let c1 = new Customer(new Normal());
console.log(c1.cost(100));
c1.kind = new Member();
console.log(c1.cost(100));
c1.kind = new VIP();
console.log(c1.cost(100));

better

class Customer {
  constructor() {
    // 把算法封装在策略对象中,指定算法调用即可
    this.kinds = {
      normal: function (price) {
        return price;
      },
      member: function (price) {
        return price * .9;
      },
      vip: function (price) {
        return price * .8;
      }
    }
  }
  cost(kind, amount) {
    return this.kinds[kind](amount);
  }
}

let c = new Customer();
console.log(c.cost('normal', 100));
console.log(c.cost('member', 100));
console.log(c.cost('vip', 100));

应用场景

表单校验

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <form id="userform">
        用户名 <input type="text" name="username" />
        密码 <input type="text" name="password" />
        手机号 <input type="text" name="mobile" />
        <input type="submit">
    </form>
    <script>
        let Validator = (function () {
            let rules = {
                notEmpty(val, msg) {
                    if (val == '') {
                        return msg;
                    }
                },
                minLength(val, length, msg) {
                    if (val == '' || val.length < length) {
                        return msg;
                    }
                },
                maxLength(val, length, msg) {
                    if (val == '' || val.length > length) {
                        return msg;
                    }
                },
                isMobile(val, msg) {
                    if (!/^1\d{10}/.test(val)) {
                        return msg;
                    }
                }
            }

            let checks = [];
            function add(element, rule) {
                checks.push(function () {
                    let fnName = rule.shift();
                    return rules[fnName] && rules[fnName].apply(element, [element.value, rule]);
                });
            }

            function start() {
                for (let i = 0; i < checks.length; i++) {
                    let msg = checks[i]();
                    if (msg) {
                        return msg;
                    }
                }
            }
            return {
                add,
                start,
            }
        })();

        let form = document.getElementById('userform');
        form.onsubmit = function () {
            Validator.add(form.username, ['notEmpty', '用户名不能为空']);
            Validator.add(form.password, ['minLength', 6, '密码小于 6 位最少长度']);
            Validator.add(form.password, ['maxLength', 8, '密码大于 8 位最大长度']);
            Validator.add(form.mobile, ['isMobile', '手机号不合法']);
            let msg = Validator.start();
            if (msg) {
                alert(msg);
                return false;
            }
            alert('校验通过');
            return true;
        }
    </script>

</body>

</html>
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 类图
  2. 2. bad
  3. 3. good
  4. 4. better
  5. 5. 应用场景
    1. 5.1. 表单校验