前端开发设计模式——策略模式

news2024/9/30 7:19:54

目录

一、策略模式的定义和特点

1.定义:

2.特点:

二、策略模式的实现方式

1.定义策略接口:

2.创建具体策略类:

3.定义上下文类:

三、策略模式的应用场景

1.表单验证场景:

2.动画效果切换场景:

3.数据处理和格式化场景:

四、策略模式的优点

1.可维护性:

2.可扩展性:

3.灵活性:

五、策略模式的缺点

1.增加代码复杂度:

2.性能开销:

六、策略模式的注意事项

1.策略命名规范:

2.策略的选择逻辑:

3.策略的可测试性:


一、策略模式的定义和特点

1.定义:

        策略模式是一种行为设计模式,它定义了一系列的算法,并将每个算法封装起来,使它们可以相互替换。在前端开发中,策略模式允许根据不同的情况动态地选择和应用不同的算法或行为,而无需修改使用这些算法的主体代码。

2.特点:

        算法封装:将不同的算法封装在独立的策略类中,每个策略类实现特定的行为逻辑。

        可替换性:不同的策略可以在运行时相互替换,使得系统更加灵活。

        解耦性:策略模式将算法的实现与使用算法的主体代码解耦,提高了代码的可维护性和可扩展性。

二、策略模式的实现方式

1.定义策略接口:

        首先,定义一个策略接口,该接口声明了所有具体策略类必须实现的方法。例如:

   interface Strategy {
     execute(): void;
   }

2.创建具体策略类:

        实现具体的策略类,每个策略类实现策略接口中的方法,并提供特定的算法实现。例如:

   class ConcreteStrategyA implements Strategy {
     execute() {
       console.log('Executing strategy A.');
     }
   }

   class ConcreteStrategyB implements Strategy {
     execute() {
       console.log('Executing strategy B.');
     }
   }

3.定义上下文类:

        上下文类持有一个策略对象的引用,并通过该引用调用策略对象的方法。上下文类可以在运行时设置不同的策略对象。例如:

   class Context {
     private strategy: Strategy;

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

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

     executeStrategy() {
       this.strategy.execute();
     }
   }

三、策略模式的应用场景

1.表单验证场景:

        根据不同的表单字段类型和需求,可以使用不同的验证策略。例如,对于电子邮件字段,可以使用一个验证电子邮件格式的策略;对于密码字段,可以使用一个验证密码强度的策略.

        示例:

                (1)定义策略接口:

interface ValidationStrategy {
  validate(value): boolean;
}

                (2)创建具体策略类:

                        邮箱验证策略:

   class EmailValidationStrategy implements ValidationStrategy {
     validate(value) {
       const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
       return emailRegex.test(value);
     }
   }

                        密码长度验证策略:

   class PasswordLengthValidationStrategy implements ValidationStrategy {
     validate(value) {
       return value.length >= 8;
     }
   }

                (3)定义上下文类(表单组件):

class FormComponent {
  private validationStrategy: ValidationStrategy;

  constructor(strategy: ValidationStrategy) {
    this.validationStrategy = strategy;
  }

  setValidationStrategy(strategy: ValidationStrategy) {
    this.validationStrategy = strategy;
  }

  validateInput(value) {
    return this.validationStrategy.validate(value);
  }
}

                (4)使用示例:

// 使用邮箱验证策略
const emailFormComponent = new FormComponent(new EmailValidationStrategy());
const isEmailValid = emailFormComponent.validateInput('test@example.com');
console.log('Email is valid:', isEmailValid);

// 切换为密码长度验证策略
emailFormComponent.setValidationStrategy(new PasswordLengthValidationStrategy());
const isPasswordValid = emailFormComponent.validateInput('12345678');
console.log('Password is valid:', isPasswordValid);

2.动画效果切换场景:

        在前端动画中,可以根据不同的场景和用户交互选择不同的动画效果策略。例如,在页面加载时可以使用一种淡入效果,在用户点击按钮时可以使用一种弹出效果。

        示例:

                (1)定义策略接口:

interface AnimationStrategy {
  animate(element): void;
}

                (2)创建具体策略类:

                        淡入动画策略:

   class FadeInAnimationStrategy implements AnimationStrategy {
     animate(element) {
       element.style.opacity = '0';
       let opacity = 0;
       const interval = setInterval(() => {
         opacity += 0.1;
         element.style.opacity = opacity.toString();
         if (opacity >= 1) {
           clearInterval(interval);
         }
       }, 100);
     }
   }

                         弹出动画策略:

   class PopupAnimationStrategy implements AnimationStrategy {
     animate(element) {
       element.style.transform = 'scale(0)';
       let scale = 0;
       const interval = setInterval(() => {
         scale += 0.1;
         element.style.transform = `scale(${scale})`;
         if (scale >= 1) {
           clearInterval(interval);
         }
       }, 100);
     }
   }

                (3)定义上下文类(动画控制器):

class AnimationController {
  private animationStrategy: AnimationStrategy;

  constructor(strategy: AnimationStrategy) {
    this.animationStrategy = strategy;
  }

  setAnimationStrategy(strategy: AnimationStrategy) {
    this.animationStrategy = strategy;
  }

  startAnimation(element) {
    this.animationStrategy.animate(element);
  }
}

                 (4)使用示例:

// 使用淡入动画策略
const fadeInController = new AnimationController(new FadeInAnimationStrategy());
const elementToAnimate = document.createElement('div');
document.body.appendChild(elementToAnimate);
fadeInController.startAnimation(elementToAnimate);

// 切换为弹出动画策略
fadeInController.setAnimationStrategy(new PopupAnimationStrategy());
const anotherElementToAnimate = document.createElement('div');
document.body.appendChild(anotherElementToAnimate);
fadeInController.startAnimation(anotherElementToAnimate);

3.数据处理和格式化场景:

        对于不同类型的数据,可以使用不同的数据处理和格式化策略。例如,对于日期数据,可以使用不同的日期格式化策略;对于数字数据,可以使用不同的数字格式化策略。

        这个就不举例了......

四、策略模式的优点

1.可维护性:

        将不同的算法封装在独立的策略类中,使得代码更加清晰、易于维护。当需要修改某个算法时,只需修改相应的策略类,而不会影响其他部分的代码。

2.可扩展性:

        可以方便地添加新的策略类,实现新的算法或行为,而无需修改现有的代码。这使得系统具有良好的可扩展性。

3.灵活性:

        策略模式允许在运行时根据不同的情况选择不同的策略,使得系统更加灵活。可以根据用户的输入、系统状态或其他条件动态地切换策略。

五、策略模式的缺点

1.增加代码复杂度:

        引入策略模式会增加代码的复杂度,特别是当有多个策略类时。需要更多的类和接口,以及更多的代码来管理策略的选择和切换。

2.性能开销:

        在运行时动态地选择策略可能会带来一定的性能开销。特别是当策略的选择和切换比较频繁时,可能会影响系统的性能。

六、策略模式的注意事项

1.策略命名规范:

        为了提高代码的可读性和可维护性,应该为策略类和方法使用清晰、有意义的命名规范。这样可以更容易地理解每个策略的作用和用途。

2.策略的选择逻辑:

        在上下文类中,应该有明确的逻辑来选择合适的策略。可以根据用户的输入、系统状态或其他条件来选择策略。同时,应该考虑策略的优先级和适用性,以确保选择的策略是最合适的。

3.策略的可测试性:

        由于策略模式将算法的实现与使用算法的主体代码解耦,因此策略类通常比较容易进行单元测试。可以为每个策略类编写独立的测试用例,确保它们的行为符合预期。同时,也应该测试上下文类对策略的选择和切换逻辑。

        

        对于前端开发设计模式中的策略模式就分享到这,如果对设计模式中的其他模式有兴趣的话,可以点开主页看看相关文章。码字不易,点个赞再走吧        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2179030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

调试分析:[跳数度量]更改为[距离度量]后的 routing_bellmanford 算法

回顾复习2023年8月的《★修改Exata6.2源码:〔修改Bellmanford最短路径路由的衡量标准从【路由跳数】改为【“路由器节点间的物理距离”】,并动画演示〕》,VS2015调试Exata,跟踪调试修改后的[ routing_bellmanford.cpp ]源码&#…

AgentScope : 与CodeAct智能体对话

参考: 非一般程序猿第六季Agent入门实战篇(三)–CodeActAgent篇 Conversation with CodeAct Agent 0,简介 CodeAct Agent是一个Agent,它不仅可以聊天,还可以为你编写和执行Python代码。在本示例中,将介绍另一种赋予Agent调用工具能力的方法,特别是通过…

Mac 卸载 IDEA 流程

1、现在应用程序中删除Idea 2、进入Library目录 cd /Users/zhengzhaoxiang/Library 3、删除IntelliJIdea2023.3(根据自己的版本而定)记得进去看下是否删除干净了 rm -rf Logs/JetBrains/IntelliJIdea2023.3 rm -rf Preferences/com.jetbrains.intel…

项目学习笔记

Downloads – Oracle VirtualBoxhttps://www.virtualbox.org/wiki/Downloads

启动hadoop集群出现there is no HDFS_NAMENODE_USER defined.Aborting operation

解决方案 在hadoop-env.sh中添加 export HDFS_DATANODE_USERroot export HDFS_NAMENODE_USERroot export HDFS_SECONDARYNAMENODE_USERroot export YARN_RESOURCEMANAGER_USERroot export YARN_NODEMANAGER_USERroot 再次运行即可。

Candance仿真电流镜OTA

1.电路图搭建 图1 上面那层不能直接一横直接连过来,图2只能这样连。但是,图2的M1和M0的电压已经超过了VDD的1.8V。是不行的,需要调整,主要增大M1和M0的宽长比以减小电压。 图2 candance电流镜OTA电路实现 下面这篇文章讲了电流镜…

ROS与无人驾驶学习笔记(一)——ROS基本操作

文章目录 ※ 安装ubuntu 下载 创建虚拟机 安装系统 安装vmware tool 更新源 安装常用软件 ※ 安装ROS 设置软件更新 使用清华源安装 ros测试 认识ROS ROS特点 ROS系统实现 ROS安装 工作需要,转行做码农了。。。 大概是无人驾驶相关的,啥都不会。。。 看成…

JS设计模式之状态模式:优雅地管理应用中产生的不同状态

一. 前言 在过去,我们经常使用条件语句(if-else 语句)来处理应用程序中的不同状态。然而,这种方式往往会让代码变得冗长、难以维护,并可能引入潜在的 bug。而状态模式则提供了一种更加结构化和可扩展的方法来处理状态…

支持超高分辨率图片生成,UltraPixel模型分享

UltraPixel是一种由华为诺亚方舟实验室联合香港科技大学共同开发的超高清图像合成架构,旨在生成具有丰富细节的高质量图像,其分辨率可以从1K一直延伸至6K。 UltraPixel不仅仅是一个图像放大工具,它还能在生成过程中优化细节,提升…

Golang | Leetcode Golang题解之第447题回旋镖的数量

题目: 题解: func numberOfBoomerangs(points [][]int) (ans int) {for _, p : range points {cnt : map[int]int{}for _, q : range points {dis : (p[0]-q[0])*(p[0]-q[0]) (p[1]-q[1])*(p[1]-q[1])cnt[dis]}for _, m : range cnt {ans m * (m - 1)…

Go实现RabbitMQ消息模式

【目标】 go实现RabbitMQ简单模式和work工作模式 go实现RabbitMQ 消息持久化和手动应答 go实现RabbitMQ 发布订阅模式 go使用MQ实现评论后排行榜更新 1. go实现简单模式 编写路由实现生产消息 实现生产消息 MQ消息执行为命令行执行,所以创建命令行执行函数mai…

react-native-Windows配置

一:官网: React Native for Windows macOS Build native Windows & macOS apps with Javascript and React 二:安装依赖 需要以管理员身份运行powershell,然后粘贴下面代码,注意:要安装淘宝镜像,要…

JAVA线程基础二——锁的概述之乐观锁与悲观锁

乐观锁与悲观锁 乐观锁和悲观锁是在数据库中引入的名词,但是在并发包锁里面也引入了类似的思想,所以这里还是有必要讲解下。 悲观锁指对数据被外界修改持保守态度,认为数据很容易就会被其他线程修改,所以在数据被处理前先对数据进行加锁&…

[Redis][典型运用][分布式锁]详细讲解

目录 0.什么是分布式锁1.分布式锁的基础实现2.引入过期时间3.引入校验ID4.引入Lua5.引入Watch Dog(看门狗)6.引入Redlock算法7.其他功能 0.什么是分布式锁 在⼀个分布式的系统中,也会涉及到多个节点访问同⼀个公共资源的情况,此时就需要通过锁来做互斥控…

一拖二快充线:单接与双接的多场景应用

在当代社会,随着智能手机等电子设备的普及,充电问题成为了人们关注的焦点。一拖二快充线作为一种创新的充电解决方案,因其便捷性与高效性而受到广泛关注。本文将深入探讨一拖二快充线的定义、原理以及在单接与双接手机场景下的应用&#xff0…

数字图像处理:空间域滤波

1.数字图像处理:空间域滤波 1.1 滤波器核(相关核)与卷积 图像上的邻域计算 线性空间滤波的原理 滤波器核(相关核)是如何得到的? 空间域的卷积 卷积:滤波器核与window中的对应值相乘后所有…

touch命令:创建文件,更新时间戳

一、命令简介 ​touch​ 命令在 Linux 和其他类 Unix 系统中用于创建空白文件或者更新已存在文件的时间戳。如果指定的文件不存在,touch​ 命令会创建一个空白文件;如果文件已经存在,touch​ 命令会更新文件的访问时间和修改时间&#xff0c…

誉天Linux云计算课程学什么?为什么保障就业?

一个IT工程师相当于干了哪些职业? 其中置顶回答生动而形象地描绘道: 一个IT工程师宛如一个超级多面手,相当于——加班狂程序员测试工程师实施工程师网络工程师电工装卸工搬运工超人。 此中酸甜苦辣咸,相信很多小伙伴们都深有体会。除了典…

用开源软件制作出精美的短视频#视频编辑

从前,有一个叫做创意森林的地方,住着各种各样的编辑精灵。一天,视频编辑精灵们发现了一本神秘的论文,里面写满了如何利用前沿的AI技术来提升他们的工作效率。于是,精灵们开始学习使用LLM和LLaVA,像魔法一样…

《企业实战分享 · 开发技术栈选型》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…