首页 > 其他分享 >精通前端设计模式:策略模式在代码解耦中的威力

精通前端设计模式:策略模式在代码解耦中的威力

时间:2023-07-19 23:32:32浏览次数:39  
标签:精通 opType 策略 number KV 设计模式 TYPE 耦中 OP

为什么学习和使用设计模式?我认为有两个主要原因:

  1. 解耦:设计模式的目标是将 "不变的" 和 "可变的" 分离,将 "不变的" 封装为统一对象,而在具体实例中实现 "可变的" 部分。
  2. 统一标准:设计模式定义了一套优秀代码的标准,相当于一份实现优秀代码的说明书。

在前端开发中,面对复杂场景,我们可以通过设计模式更清晰地处理代码逻辑。其中,策略模式在前端开发中的应用非常广泛。下面我将详细介绍策略模式在前端开发中的具体应用。

策略模式基础策略模式的含义是:定义了一系列的算法,并将每个算法封装起来,使它们可以互相替换。

个人对策略模式的理解是:将原本写在一个函数中的一整套功能拆分为独立的部分,以达到解耦的目的。因此,策略模式最适用于拆解 if-else 结构,将每个 if 模块封装为独立的算法。

在面向对象的语言中,策略模式通常由三个部分组成:

  1. 策略(Strategy):实现不同算法的接口。
  2. 具体策略(Concrete Strategy):实现策略定义的接口,提供具体的算法实现。
  3. 上下文(Context):持有策略对象的引用,通过一个具体策略对象进行配置,并维护对策略对象的引用。

可能这样的定义不太直观,因此我使用 TypeScript 和面向对象的方式来实现一个计算器的策略模式示例,以便更好地说明。

typescript:

// 第一步:定义策略(Strategy)
interface CalculatorStrategy {
  calculate(a: number, b: number): number;
}




// 第二步:定义具体策略(Concrete Strategy)
class AddStrategy implements CalculatorStrategy {
  calculate(a: number, b: number): number {
    return a + b;
  }
}




class SubtractStrategy implements CalculatorStrategy {
  calculate(a: number, b: number): number {
    return a - b;
  }
}




class MultiplyStrategy implements CalculatorStrategy {
  calculate(a: number, b: number): number {
    return a * b;
  }
}




// 第三步:创建上下文(Context),用于调用不同的策略
class CalculatorContext {
  private strategy: CalculatorStrategy;




  constructor(strategy: CalculatorStrategy) {
    this.strategy = strategy;
  }




  setStrategy(strategy: CalculatorStrategy) {
    this.strategy = strategy;
  }




  calculate(a: number, b: number): number {
    return this.strategy.calculate(a, b);
  }
}




// 使用策略模式进行计算
const addStrategy = new AddStrategy();
const subtractStrategy = new SubtractStrategy();
const multiplyStrategy = new MultiplyStrategy();




const calculator = new CalculatorContext(addStrategy);
console.log(calculator.calculate(5, 3)); // 输出 8




calculator.setStrategy(subtractStrategy);
console.log(calculator.calculate(5, 3)); // 输出 2




calculator.setStrategy(multiplyStrategy);
console.log(calculator.calculate(5, 3)); // 输出 15

前端策略模式应用:

实际上,在前端开发中通常不会直接使用面向对象的模式。在前端中,策略模式可以简化为两个部分:

1. 对象:存储策略算法,并通过键(key)匹配对应的算法。

2. 策略方法:实现键对应的具体策略算法。

我将举一个最近在开发中应用策略模式进行重构的例子。该例子实现了对不同操作的联动字段处理。在原始代码中,针对操作类型 opType 大量使用了 if-else 判断。虽然看起来代码量不多,但每个 if-else 块中可能包含大量处理逻辑,导致整体的可读性变差。


typescript:

export function transferAction() {
  actions.forEach((action) => {
    const { opType } = action;




    // 展示/隐藏字段
    if (opType === OP_TYPE_KV.SHOW) { }
    else if (opType === OP_TYPE_KV.HIDE) { }
    // 启用/禁用字段
    else if (opType === OP_TYPE_KV.ENABLE) { }
    else if (opType === OP_TYPE_KV.DISABLE) { }
    // 必填/非必填字段
    else if (opType === OP_TYPE_KV.REQUIRED) { }
    else if (opType === OP_TYPE_KV.UN_REQUIRED) { }
    // 清空字段值
    else if (opType === OP_TYPE_KV.CLEAR && isSatisfy) { }
  });
}

经过策略模式重构之后,我们将每个操作封装为单独的方法,并将所有算法放入一个对象中,通过触发条件进行匹配。重构后的代码相较于原始的 if-else 结构更加清晰,每次只需找到对应的策略方法实现即可。此外,如果需要扩展功能,只需继续增加策略方法,而不会影响原有代码。


typescript:

export function transferAction(/* 参数 */) {
  /**
   * @description 处理字段显示和隐藏
   */
  const handleShowAndHide = ({ opType, relativeGroupCode, relativeCode }) => {};




  /**
   * @description 启用/禁用字段(支持表格行字段的联动)
   */
  const handleEnableAndDisable = ({ opType, relativeGroupCode, relativeCode }) => {};




  /**
   * @description 必填/非必填字段(支持表格行字段联动)
const handleRequiredAndUnrequired = ({ opType, relativeGroupCode, relativeCode }) => {};
/**
@description 清空字段值
*/
const handleClear = ({ opType, relativeGroupCode, relativeCode }) => {};
// 联动策略
const strategyMap = {
// 显示/隐藏
[OP_TYPE_KV.SHOW]: handleShowAndHide,
[OP_TYPE_KV.HIDE]: handleShowAndHide,
// 启用/禁用
[OP_TYPE_KV.ENABLE]: handleEnableAndDisable,
[OP_TYPE_KV.DISABLE]: handleEnableAndDisable,
// 必填/非必填
[OP_TYPE_KV.REQUIRED]: handleRequiredAndUnrequired,
[OP_TYPE_KV.UN_REQUIRED]: handleRequiredAndUnrequired,
// 清空字段值
[OP_TYPE_KV.CLEAR]: handleClear,
};
// 遍历执行联动策略
actions.forEach((action) => {
const { opType, relativeGroupCode, relativeCode, value } = action;
if (strategyMap[opType]) {
  strategyMap[opType]({ /* 入参 */ });
}
});
}


总结:

策略模式的优点在于,代码逻辑更清晰,每个策略对应一个实现方法,并且遵循开闭原则。新的策略方法无需改变已有代码,因此非常适合处理或重构复杂逻辑中的 if-else 结构。

在前端开发过程中,并不需要完全遵循面向对象的应用方式。我们只需通过对象存储策略算法,并通过键进行匹配,即可实现基础的策略模式。

通过学习和应用设计模式,我们能够提高代码的可维护性和扩展性,使代码更加灵活和清晰。策略模式是前端开发中常用的设计模式之一,它能帮助我们处理复杂的代码逻辑,提升开发效率。

通过深入理解和灵活运用设计模式,我们可以成为精通前端设计模式的开发者,从而编写出高质量的代码并更好地应对复杂的开发场景。

感谢阅读本文,如果对你有帮助,请点赞和收藏

标签:精通,opType,策略,number,KV,设计模式,TYPE,耦中,OP
From: https://blog.51cto.com/u_7669561/6781321

相关文章

  • 设计模式-享元模式在Java中的使用示例-围棋软件
    场景享元模式简介当一个软件系统在运行时产生的对象数量太多,将导致运行代价过高,带来系统性能下降等问题。例如在一个文本字符串中存在很多重复的字符,如果每一个字符都用一个单独的对象来表示,将会占用较多的内存空间,那么我们如何去避免系统中出现大量相同或相似的对象,同时又不......
  • 设计模式-外观模式在Java中的使用示例
    场景外观模式外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。示例自己泡茶和去茶馆喝茶的区别,如果是自己泡茶需要自行准备茶叶、......
  • Python单元测试之道:从入门到精通的全面指南
    在这篇文章中,我们会深入探讨Python单元测试的各个方面,包括它的基本概念、基础知识、实践方法、高级话题,如何在实际项目中进行单元测试,单元测试的最佳实践,以及一些有用的工具和资源一、单元测试重要性测试是软件开发中不可或缺的一部分,它能够帮助我们保证代码的质量,减少bug,提高系......
  • 设计模式-组合模式在Java中的使用示例-杀毒软件针对文件和文件夹进行杀毒
    场景组合模式组合模式(CompositePattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。在组合模式中引......
  • Spring框架中的设计模式(重点学习!!!)
    Spring中的设计模式Spring框架中用到的设计模式有很多,以下是一些常见的设计模式:依赖注入(DI)和控制反转(IoC):这是Spring框架最核心的设计模式,它允许开发人员将对象之间的依赖关系从代码中抽离出来,由Spring容器负责管理和注入对象之间的依赖关系。工厂模式:Spring框架中的BeanFactor......
  • 设计模式-法则大全
    SOLID原则:单一职责原则SRP:一个类只负责完成一个职责或功能;要设计粒度小、功能单一的类开闭原则OCP:对扩展开放、对修改关闭;在已有基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等);里式替换LSP:父类定义了函数的“约定”(或者协议),那子类可以改变函数的内......
  • 02-设计模式-观察者模式
    观察者模式涉及的对象:观察者接口、观察者接口的实现类被观察者接口、被观察者接口的实现类1、观察者接口-代码:publicinterfaceObserver{voidupdate(Stringmsg);}2、观察者接口的实现类-代码:publicclassObserverImplimplementsObserver{privateSt......
  • 01-设计模式-代理模式
    1、代理模式的分类代理模式分为:静态代理:在编译阶段确定了被代理对象的类型,简单。动态代理:在运行阶段确定了被代理对象的类型,复杂。2、静态代理静态代理涉及的类:一个接口,下面的例子中命名为Subject实现了接口的被代理对象RealSubject实现了接口的代理对象StaticProxy......
  • JAVA设计模式之责任链模式
    设计模式设计模式(DesignPattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、......
  • java设计模式实现结论
    Java设计模式实现结论场景描述在软件开发过程中,我们经常会遇到一些常见的问题和需求。为了提高代码的复用性、可维护性和可扩展性,使用设计模式是一个非常好的选择。设计模式是一种被反复验证的、经过优化的解决方案,可以解决特定问题的代码设计问题。流程概述为了实现设计模式,我......