Js设计模式---策略模式

写在前面:入门介绍,认识策略模式的含义

策略模式属于行为设计模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

该模式主要解决在有多种算法相似的情况下,使用if...else所带来的复杂和难以维护的代码。它的优点是算法可以自由切换,同时可以避免多重if...else判断,且具有良好的拓展性。

设计原理

核心思想:

  • 算法 / 业务逻辑 与其调用逻辑分离,把不同的算法封装成独立的策略类
  • 使得算法可以独立于使用它的客户端变化,客户端可以动态切换不同的策略
  • 避免大量的 if-else/switch 分支判断,让代码更清晰、易扩展

核心角色

  1. 策略接口 (Strategy):定义所有策略必须实现的方法
  2. 具体策略类 (ConcreteStrategy):实现策略接口,封装具体的算法 / 逻辑
  3. 上下文 (Context):持有策略对象的引用,提供统一的调用入口,负责策略的切换和执行

以下代码存在问题:if-else太多,管理混乱

示例一:不同年终奖的计算

```js

function calBonus(level,salary){

if(level=='S'){

return salary*4

}else if(level=='A'){

return salary*3

}else if(level=='B'){

return salary*2

}else{

return salary

}

}

console.log(calBonus('S',10000))

console.log(calBonus('A',8000))

```

使用策略模式进行改进:

```js

var strategies={

'S':function(salary){

return salary*4

},

'A':function(salary){

return salary*3

},

'B':function(salary){

return salary*2

}

//还可以继续拓展,比如C级别

}

function calBonus(level,salary){

return strategies[level](salary)

}

console.log(calBonus('S',10000))

console.log(calBonus('A',8000))

```

示例二:不同审批进度的定制化展示

html 复制代码
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        li{
            display: flex;
            justify-content: space-between;
        }
        .redItem{
            background: red;
        }
        .yellowItem{
            background: yellow;
        }
        .greenItem{
            background: green;
        }
    </style>
</head>

<body>
    <ul id="myList"></ul>
    <script>
        var list = [
            {
                title: "标题1",
                type: 1
            },
            {
                title: "标题2",
                type: 2
            },
            {
                title: "标题3",
                type: 3
            },
            {
                title: "标题4",
                type: 2
            }
        ]
        myList.innerHTML = list.map(item => {
            if (item.type === 1) {
                return `<li>
                <div>${item.title}</div>
                <div class="yellowItem">审核中</div>
            </li>`
            } else if (item.type === 2) {
                 return `<li>
                <div>${item.title}</div>
                <div class="greenItem">已通过</div>
            </li>`
            } else if (item.type === 3) {
                 return `<li>
                <div>${item.title}</div>
                <div class="redItem">被驳回</div>
            </li>`
            }
        }).join("")
    </script>
</body>

使用策略模式进行改进:

javascript 复制代码
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        li{
            display: flex;
            justify-content: space-between;
        }
        .redItem{
            background: red;
        }
        .yellowItem{
            background: yellow;
        }
        .greenItem{
            background: green;
        }
    </style>
</head>

<body>
    <ul id="myList"></ul>
    <script>
        var list = [
            {
                title: "标题1",
                type: 1
            },
            {
                title: "标题2",
                type: 2
            },
            {
                title: "标题3",
                type: 3
            },
            {
                title: "标题4",
                type: 2
            }
        ]

        //策略对象
        let obj = {
            1:{
                content: "审核中",
                className: "yellowItem"
            },
            2:{
                content: "已通过",
                className: "greenItem"
            },
            3:{
                content: "被驳回",
                className: "redItem"
            }
        }
        let myList = document.getElementById("myList")
        myList.innerHTML = list.map(item => `
            <li>
                <div>${item.title}</div>
                <div class="${obj[item.type].className}">${obj[item.type].content}</div>
            </li>`
        ).join("")
    </script>
</body>

相关应用:node中路由的匹配策略,支付方式选择,数据的不同类型格式化

小结:要有一个策略对象。同一目标的不同实现方式,通过切换策略对象完成,替代 if-else 分支。复杂模块可以按照策略接口,具体策略类,上下文进一步拆分。

以node的路由为例:

  • 策略接口(req, res) => {}(所有路由处理函数的统一规范);
  • 具体策略(req, res) => res.end('获取用户信息')(/user 的具体处理逻辑);
  • 上下文router 对象(持有策略、提供 match 方法统一执行)。

三者缺一不可:接口保证 "可替换",具体策略封装 "差异化逻辑",上下文屏蔽 "调用细节",这也是策略模式能解耦、易扩展的核心原因。

相关推荐
geovindu2 小时前
python: Strategy Pattern
python·设计模式·策略模式
sg_knight18 小时前
适配器模式(Adapter)
python·设计模式·适配器模式·adapter
郝学胜-神的一滴1 天前
Effective Modern C++ 条款40:深入理解 Atomic 与 Volatile 的多线程语义
开发语言·c++·学习·算法·设计模式·架构
九狼1 天前
Riverpod 2.0 代码生成与依赖注入
flutter·设计模式·github
geovindu1 天前
python: Visitor Pattern
python·设计模式·访问者模式
五阿哥永琪1 天前
常见设计模式简介
设计模式
资深web全栈开发1 天前
CQS - 命令查询分离:驯服副作用
设计模式
geovindu2 天前
python: Template Method Pattern
开发语言·python·设计模式·模板方法模式
HY小海2 天前
【Unity游戏创作】常见的设计模式
unity·设计模式·c#·游戏程序