设计模式 - JavaScript 中的策略模式

2025-05-24

设计模式 - JavaScript 中的策略模式

原著中描述了23种经典的设计模式
Design Patterns: Elements of Reusable Object-Oriented Software。这些模式为软件开发中反复出现的特定问题提供了解决方案



在本文中,我将描述策略模式的工作原理、应用方式和时机。在其他情况下,
该模式也称为策略

策略模式:基本思想

策略模式是一种行为设计模式,可以
在运行时选择算法——维基百科

定义一系列算法,封装每个算法,并使它们
可互换。策略允许算法独立于
使用它的客户端而变化——设计模式:可复用面向对象软件的元素

该模式的主要特点是客户端拥有一组算法,其中
会在运行时选择使用特定的算法。这些
算法之间可以互换。

以下代码展示了一个经典问题,你需要
在应用程序中选择一个具体的算法。在此代码中,你可以使用 任何编程语言的switch控制结构。

然而,使用策略模式可以更加灵活,
结构如下:

该模式的 UML 图如下:

每个策略都用一个具体的对象来表示。因此,客户端/上下文
包含一个 实现了接口的Strategy对象(concreteStrategyAconcreteStrategyB、...)。策略间交互的关键 在于在上下文中实现一个可以改变策略的方法, 例如
Strategy

setStrategy

策略模式:何时使用

  1. 策略模式的问题是,当你需要使用几种具有不同变体的算法时,你需要创建一个具体的类来实现你的算法(它可以包含一个或多个函数)。
  2. 另一个有趣的时刻是,当围绕几个算法存在相互关联的条件语句时,您会发现需要这种模式。
  3. 最后,当大多数类都有相关行为时,您必须使用此模式。

策略模式:优势

策略模式有几个优点,可以概括为
以下几点:

  • 由于您使用接口实现了多态性,因此在运行时可以轻松地在不同的算法(策略)之间切换。
  • 干净的代码,因为您避免了条件泛滥的代码(并不复杂)。
  • 代码更加干净,因为您将关注点分成了不同的类(每个策略对应一个类)。

策略模式:使用 JavaScript 的基本实现

现在,我将向您展示如何使用 JavaScript 实现此模式,
您必须记住,JavaScript 缺少接口。因此,您需要编写一个
名为的类StrategyManager,用作接口:

此类包含一个名为 的私有属性_strategy,它表示
当前将使用的策略。该方法doAction是每个具体策略中将要实现的方法。 由于 JavaScript 语言缺乏面向对象编程 (OOP) 特性,因此
策略模式与 UML 模式有所不同。

各个具体策略的实现如下:

注意具体方法doAction是在每个具体
策略中实现的。

最后,上下文/客户端必须包含StrategyManager(或策略
接口,如果语言是面向对象的)才能使用具体的策略:

策略模式:一组使用 JavaScript 的策略

在以下实现中,我们的StrategyManager可以更复杂,
包含一个算法列表。在这种情况下,您可以更改 属性,
_strategy而不是名为 的数组_strategies

最后,您可以使用方法 在我们的策略列表中添加新策略
addStrategy。该类Strategy有两个属性:1)策略名称;2)
算法(称为handler)。方法doAction用于调用
具体的算法。

最后,我们使用具体策略的客户端/上下文代码如下

第一部分是创建具体的策略(可以使用
单例模式或工厂模式构建),并将其添加到我们的
策略管理器(可以作为我们的接口)中。客户端的下一部分
是选择要使用的策略,您可以使用应用程序中的GUI
CLI来选择该策略。

最后,请注意,如果选择了不受支持的策略,系统
会返回错误。当您想为
系统提供高级算法时,可以使用此功能。

结论

策略模式是一种在需要选择具体算法时避免代码复杂度的模式
。本文中,你可以
使用缺乏接口的 JavaScript 语言获得一个简单的实现。如果
你使用具有接口的编程语言,则可以遵循该
模式的 UML。

最重要的不是实现我向您展示的模式,而是您需要
知道该模式解决了什么问题以及为什么必须使用,因为
实现会因编程语言的不同而不同。



大家好!我叫卡洛斯·卡瓦列罗,来自
西班牙马拉加,拥有计算机科学博士学位。我致力于教授开发人员和计算机科学本科/硕士生如何成为专家。

文章来源:https://dev.to/carlillo/design-patterns---strategy-pattern-in-javascript-2hg3
PREV
想成为顶尖开发者吗?你必须开发应用!——7 款值得开发的应用
NEXT
干净代码应用于 JavaScript — 第六部分:避免条件复杂性