设计模式:TypeScript中的策略模式

​如何在 TypeScript 中使用和实现 Strategy 模式来解决 Web 项目中的实际问题。

欢迎来到 TypeScript 设计模式系列,该系列介绍了使用 TypeScript 进行 Web 开发的一些有用的设计模式。

每个工程师都应该知道的9种设计模式icon-default.png?t=N7T8https://blog.csdn.net/wannianchuan/article/details/135565734

设计模式对于 web 开发人员来说非常重要,掌握它们可以让我们写出更好的代码。在本文中,我将使用 TypeScript 来介绍策略模式。

注册和登录是Web应用程序中的重要功能。在注册Web应用程序时,更常见的注册方式是使用帐户/密码、电子邮件或手机号码。一旦您成功注册,就可以使用相应的方法登录。

function login(mode) {  if (mode === "account") {    loginWithPassword();  } else if (mode === "email") {    loginWithEmail();  } else if (mode === "mobile") {    loginWithMobile();  }}

当web应用需要支持其他登录方式时,例如,除了email登录方式外,Medium登录页面还支持第三方平台如Google、Facebook、Apple和Twitter的登录方式。

然后为了支持多个第三方登录方法,我们需要修改前面的  login  函数:

function login(mode) {  if (mode === "account") {    loginWithPassword();  } else if (mode === "email") {    loginWithEmail();  } else if (mode === "mobile") {    loginWithMobile();  } else if (mode === "google") {    loginWithGoogle();  } else if (mode === "facebook") {    loginWithFacebook();  } else if (mode === "apple") {    loginWithApple();  } else if (mode === "twitter") {    loginWithTwitter();  }}

如果我们以后继续添加或修改登录方法,我们会发现  login  函数变得越来越难以维护,针对这个问题,我们可以使用策略模式将不同的登录方法封装到不同的登录策略中。

为了更好地理解下面的代码,让我们先看看相应的 UML 图:

在上面的图中,我们定义了一个  Strategy  接口,然后基于这个接口实现了 Twitter 和帐户/密码两种登录策略。

策略接口

interface Strategy {  authenticate(args: any[]): boolean;}


TwitterStrategy类

class TwitterStrategy implements Strategy {  authenticate(args: any[]) {    const [token] = args;    if (token !== "tw123") {      console.error("Twitter account authentication failed!");      return false;    }    console.log("Twitter account authentication succeeded!");    return true;  }}


LocalStrategy类

class LocalStrategy implements Strategy {  authenticate(args: any[]) {    const [username, password] = args;    if (username !== "bytefer" || password !== "666") {      console.log("Incorrect username or password!");      return false;    }    console.log("Account and password authentication succeeded!");    return true;  }}


在拥有不同的登录策略之后,我们定义了一个 Authenticator 类来在不同的登录策略之间切换,并执行相应的身份验证操作。

Authenticator类

class Authenticator {  strategies: Record<string, Strategy> = {};  use(name: string, strategy: Strategy) {    this.strategies[name] = strategy;  }  authenticate(name: string, ...args: any) {    if (!this.strategies[name]) {      console.error("Authentication policy has not been set!");      return false;    }    return this.strategies[name].authenticate.apply(null, args);  }}


之后,我们可以使用不同的登录方法,以以下方式实现用户身份验证:

const auth = new Authenticator();
auth.use("twitter", new TwitterStrategy());auth.use("local", new LocalStrategy());
function login(mode: string, ...args: any) {  return auth.authenticate(mode, args);}
login("twitter", "123");login("local", "bytefer", "666");

当你成功运行上述代码时,相应的输出如下图所示:

除了登录身份验证场景,策略模式还可以用于表单字段验证场景,还可以用于优化 if else 分支过多的问题。

如果你使用 Node.js 开发身份验证服务,你可以看看 passport.js 模块:

Passport是Node.js的身份验证中间件,非常灵活和模块化,可以被轻易地添加到任何基于Express的Web应用中。它提供了一组全面的策略,支持使用用户名和密码、Facebook、Twitter等进行身份验证。

https://www.passportjs.org/

这个模块非常强大,目前支持多达538种策略:

最后,让我们总结一下策略模式的使用场景:

  • 当系统需要动态地从几个算法中选择一个时,每个算法都可以封装到策略类中。

  • 多个类只是在行为上不同,您可以使用策略模式来动态选择在运行时执行的特定行为。
     

如果您有任何问题,请随时给我留言。我以后会继续介绍其他的模式,如果您感兴趣,您可以关注文本魔术公众号以便能第一时间收到更新。

 

  • 31
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在TypeScript,可以使用类和多态性来实现策略模式。 以下是一个使用TypeScript实现策略模式的示例: ```typescript // 定义一个策略接口 interface FlyStrategy { fly(): void; } // 实现具体的飞行策略类 class FlyWithWings implements FlyStrategy { fly() { console.log("用翅膀飞行"); } } class FlyNoWay implements FlyStrategy { fly() { console.log("无法飞行"); } } // 定义一个鸭子类 class Duck { private flyStrategy: FlyStrategy; constructor(flyStrategy: FlyStrategy) { this.flyStrategy = flyStrategy; } // 设置飞行策略 setFlyStrategy(flyStrategy: FlyStrategy) { this.flyStrategy = flyStrategy; } // 执行飞行 performFly() { this.flyStrategy.fly(); } } // 使用策略模式 const duck = new Duck(new FlyWithWings()); duck.performFly(); // 输出:用翅膀飞行 duck.setFlyStrategy(new FlyNoWay()); duck.performFly(); // 输出:无法飞行 ``` 在上面的示例,我们定义了一个`FlyStrategy`接口,它包含一个`fly`方法。然后,我们实现了两个具体的飞行策略类`FlyWithWings`和`FlyNoWay`,它们分别实现了`FlyStrategy`接口。接下来,我们定义了一个`Duck`类,它包含一个`flyStrategy`属性,用于存储当前的飞行策略。`Duck`类还包含了`setFlyStrategy`和`performFly`方法,用于设置和执行飞行策略。 通过使用策略模式,我们可以在运行时选择不同的飞行策略,而不需要修改`Duck`类的代码。这样,我们可以实现算法的变化独立于使用算法的客户。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值