查看原文
其他

策略模式原来这么简单!

阿宝哥 全栈修仙之路 2023-03-11
前言
策略模式属于行为模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。我们将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。

欢迎你阅读 「《重学 TypeScript 3.0》」 系列教程,本系列教程会包含 TypeScript 基础知识、进阶知识、类型体操(精选)、设计模式、核心特性实战和开源项目源码解析 「6」 大专题的内容。

近期团队内招聘高级前端,阿宝哥跟挺多候选人聊过,发现大多数候选人对前端常用设计模式的理解还不够深,所以阿宝哥决定先更新 「TypeScript 设计模式」 专题。本文阿宝哥将带大家一起来学习工作中,非常有用的设计模式 —— 「策略模式」

在 Web 应用中,注册和登录是很重要的功能。在注册 Web 应用的账号时,主流的 Web 应用一般会提供不同的注册方式。比如,用户名/密码、邮箱、手机号码或第三方账号(微信/微博账号等)。当你成功注册账号之后,大多数 Web 应用还会引导你完善个人资料。在此期间,如果你绑定了其它的登录方式,那么在登录时你就可以选择不同的登录方式。要实现登录时,支持切换不同登录方式的功能,我们可以定义一个 login 函数:

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

但如果 Web 应用还要支持微信、微博或 Github 等第三方平台的登录方式。我们就需要修改前面定义的 login 函数:

function login(mode) {
  if (mode === "account") {
    loginWithAccount(); // 账号/密码
  } else if (mode === "email") {
    loginWithEmail(); // 邮箱/密码
  } else if (mode === "mobile") {
    loginWithMobile(); // 手机号/验证码
  } else if (mode === "wechat") {
    loginWithWechat(); // 微信账号
  } else if (mode === "weibo") {
    loginWithWeibo(); // 微博账号
  } else if (mode === "github") {
    loginWithGithub(); // Github 账号
  } else {
    throw new Error(`Unsupported login mode: ${mode}`);
  }
}

之后,我们可能还要添加其它的登录方式或修改原有的登录方式,这时我们就会发现 login 函数变得越来越臃肿。针对这个问题,我们可以使用策略模式,将不同的登录方式封装成不同的登录策略。这样不仅可以避免使用一堆的 if...else 语句,同时还能满足后期不断扩展的需求。

下面阿宝哥将使用 TypeScript 来演示如何利用 「策略模式」 来解决上述的问题。策略模式主要由以下 3 个角色组成:

  • Context:持有策略类的引用,提供给客户端使用;
  • Strategy:抽象的角色,通常是一个接口或抽象类;
  • ConcreteStrategy:具体策略角色,封装了相关的算法和行为。

在前面的登录场景中,阿宝哥将定义一个 Authenticator 类来管理不同的登录策略,它对应于策略模式中的 Context 角色。接着使用 interface 定义一个 Strategy 接口,然后基于该接口实现 「账号/密码」「微信登录」 两种不同的登录策略。

为了更好的理解下面的代码,我们先来看一下对应的 UML 图:

提示:Android 平台 1 元 10 个微豆,iOS 平台 1 元 7 个微豆,购买时可切换平台充值。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存