iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >为什么web开发中的代码越写越乱
  • 768
分享到

为什么web开发中的代码越写越乱

2024-04-02 19:04:59 768人浏览 独家记忆
摘要

本篇文章为大家展示了为什么web开发中的代码越写越乱,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 目的在开始学习责任链之前,先看一下在开发中常见的问题。

本篇文章为大家展示了为什么web开发中的代码越写越乱,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

 为什么web开发中的代码越写越乱

目的

在开始学习责任链之前,先看一下在开发中常见的问题。下面是前端用来处理 api 错误码的代码:

 const HttpErrorHandler = (error) => {    const errorStatus = error.response.status;    if (errorStatus === 400) {      console.log('你是不是提交了什么奇怪的东西?');    }        if (errorStatus === 401) {      console.log('需要先登陆!');    }        if (errorStatus === 403) {      console.log('是不是想偷摸干坏事?');    }        if (errorStatus === 404) {      console.log('这里什么也没有...');    } };

当然实际项目中不可能只有一行 console,这是为了说明原理的简化版。

代码中的 httpErrorHandler 会接收 API 的响应错误,并对错误的状态码做不同的处理,所以代码中需要很多 if(或者  switch)判断当前需要要执行什么,当你要对新的错误添加处理代码时,就必须要到 httpErrorHandler 中修改代码。

虽然免不了要经常修改代码,但是这样做可能会导致几个问题,下面根据 SOLID 的 单一职责(Single  responsibility)和开放封闭(open/close)这两个原则来说明:

单一职责(Single responsibility)

简单的说,单一职责就是只做一件事情。而前面的 httpErrorHandler  方法以使用的角度来说,是把错误对象交给它,让它按照错误码做对应的处理。看上去好像是在做“错误处理”这个单一的事情,但是从实现的角度上来说,它把不同错误的处理逻辑全部写在了  httpErrorHandler 中,这就会导致可能在只想要修改对错误码为 400 的逻辑时,但是不得不阅读一大堆不相关的代码。

开放封闭原则(open/close)

开放封闭原则是指对已经写好的核心逻辑就不要再去改动,但同时要能够因需求的增加而扩充原本的功能,也就是开放扩充功能,同时封闭修改原本正确的逻辑。再回过头来看  httpErrorHandler,如果需要增加一个对错误码 405 的处理逻辑(要扩充新功能),那就需要修改 httpErrorHandler  中的代码(修改原本正确的逻辑),这也很容易造成原来正确执行的代码出错。

既然 httpErrorHandler 破绽这么多,那该怎么办?

解决问题

分离逻辑

先让 httpErrorHandler 符合单一原则。首先把每个错误的处理逻辑分别拆成方法:

const response400 = () => {   console.log('你是不是提交了什么奇怪的东西?'); };  const response401 = () => {   console.log('需要先登陆!'); };  const response403 = () => {   console.log('是不是想偷摸干坏事?'); };  const response404 = () => {   console.log('这里什么也没有...'); };  const httpErrorHandler = (error) => {   const errorStatus = error.response.status;   if (errorStatus === 400) {     response400();   }       if (errorStatus === 401) {     response401();   }       if (errorStatus === 403) {     response403();   }       if (errorStatus === 404) {     response404();   } };

虽然只是把每个区块的逻辑拆成方法,但这已经可以让我们在修改某个状态码的错误处理时,不用再到 httpErrorHandler 中阅读大量的代码了。

仅仅是分离逻辑这个操作同时也让 httpErrorHandler  符合了开放封闭原则,因为在把错误处理的逻辑各自拆分为方法的时候,就等于对那些已经完成的代码进行了封装,这时当需要再为 httpErrorHandler 增加对  405 的错误处理逻辑时,就不会影响到其他的错误处理逻辑的方法(封闭修改),而是另行创建一个新的 response405 方法,并在  httpErrorHandler 中加上新的条件判断就行了(开放扩充新功能)。

现在的 httpErrorHandler 其实是策略模式(strategy pattern),httpErrorHandler  用了统一的接口(方法)来处理各种不同的错误状态,在本文的最后会再次解释策略模式和责任链之间的区别。

责任链模式(Chain of Responsibility  Pattern)责任链的实现

原理很简单,就是把所有方法串起来一个一个执行,并且每个方法都只做自己要做的事就行了,例如 response400 只在遇到状态码为  400 的时候执行,而 response401 只处理 401 的错误,其他方法也都只在自己该处理的时候执行。每个人各司其职,就是责任链。

接下来开始实现。

增加判断

根据责任链的定义,每个方法都必须要知道当前这件事是不是自己应该处理的,所以要把原本在 httpErrorHandler 实现的 if  判断分散到每个方法中,变成由内部控制自己的责任:

const response400 = (error) => {   if (error.response.status !== 400) return;   console.log('你是不是提交了什么奇怪的东西?'); };  const response401 = (error) => {   if (error.response.status !== 401) return;   console.log('需要先登陆!'); };  const response403 = (error) => {   if (error.response.status !== 403) return;   console.log('是不是想偷摸干坏事?'); };  const response404 = (error) => {   if (error.response.status !== 404) return;   console.log('这里什么也没有...'); };  const httpErrorHandler = (error) => {   response400(error);   response401(error);   response403(error);   response404(error); };

把判断的逻辑放到各自的方法中之后,httpErrorHandler 的代码就精简了很多,也去除了所有在 httpErrorHandler  中的逻辑,现在httpErrorHandler 只需要按照顺序执行 response400 到 response404  就行了,反正该执行就执行,不该执行的也只是直接 return 而已。

实现真正的责任链

虽然只要重构到上一步,所有被分拆的错误处理方法都会自行判断当前是不是自己该做的,但是如果你的代码就这样了,那么将来看到 httpErrorHandler  的其他人只会说:

这是什么神仙代码?API 一遇到错误就执行所有错误处理?

因为他们不知道在每个处理方法里面还有判断,也许过一段时间之后你自己也会忘了这事,因为现在的 httpErrorHandler 看起来就只是从  response400 到 response404,即使我们知道功能正确,但完全看不出是用了责任链。

那到底怎样才能看起来像是个链呢?其实你可以直接用一个数字记录所有要被执行的错误处理方法,并通过命名告诉将来看到这段代码的人这里是责任链:

const httpErrorHandler = (error) => {   const errorHandlerChain = [     response400,     response401,     response403,     response404   ];   errorHandlerChain.forEach((errorHandler) => {     errorHandler(error);   }); };

优化执行

这样一来责任链的目的就有达到了,如果像上面代码中用 forEach 处理的话,那当遇到 400 错误时,实际上是不需要执行后面的 response401  到 response404 的。

所以还要在每个错误处理的方法中加上一些逻辑,让每个方法可以判断,如果是遇到自己处理不了的事情,就丢出一个指定的字符串或布尔值,接收到之后就再接着执行下一个方法,但如果该方法可以处理,则在处理完毕之后直接结束,不需要再继续把整个链跑完。

const response400 = (error) => {   if (error.response.status !== 400) return 'next';   console.log('你是不是提交了什么奇怪的东西?'); };  const response401 = (error) => {   if (error.response.status !== 401) return 'next';   console.log('需要先登陆!'); };  const response403 = (error) => {   if (error.response.status !== 403) return 'next';;   console.log('是不是想偷摸干坏事?'); };  const response404 = (error) => {   if (error.response.status !== 404) return 'next';;   console.log('这里什么都没有...'); };

如果链中某个节点执行结果为 next,则让下后面的方法继续处理:

const httpErrorHandler = (error) => {   const errorHandlerChain = [     response400,     response401,     response403,     response404   ];      for(errorHandler of errorHandlerChain) {     const result = errorHandler(error);     if (result !== 'next') break;   }; };

封装责任链的实现

现在责任链已经实现完成了,但是判断要不要给下一个方法的逻辑(判断 result !== 'next')  ,却暴露在外面,这也许会导致项目中每个链的实现方法都会不一样,其他的链有可能是判断 nextSuccessor 或是  boolean,所以最后还需要封装一下责任链的实现,让团队中的每个人都可以使用并且遵守项目中的规范。

责任链需要:

  1. 当前的执行者。

  2. 下一个的接收者。

  3. 判断当前执行者执行后是否需要交由下一个执行者。

所以封装成类以后应该是这样:

class Chain {   constructor(handler) {     this.handler = handler;     this.successor = null;   }    setSuccessor(successor) {     this.successor = successor;     return this;   }    passRequest(...args) {     const result = this.handler(...args);     if (result === 'next') {       return this.successor && this.successor.passRequest(...args);     }     return result;   } }

用 Chain 创建对象时需要将当前的职责方法传入并设置给 handler,并且可以在新对象上用 setSuccessor 把链中的下一个对象指定给  successor,在 setSuccessor 里返回代表整条链的 this,这样在操作的时候可以直接在 setSuccessor 后面用  setSuccessor 设置下一个接收者。

最后,每个通过 Chain 产生的对象都会有 passRequest 来执行当前的职责方法,…arg 会把传入的所有参数变成一个数组,然后一起交给  handler 也就是当前的职责方法执行,如果返回的结果 result 是 next 的话,就去判断有没有指定 sucessor 如果有的话就继续执行,如果  result 不是 next,则直接返回 result。

有了 Chain 后代码就会变成:

const httpErrorHandler = (error) => {   const chainRequest400 = new Chain(response400);   const chainRequest401 = new Chain(response401);   const chainRequest403 = new Chain(response403);   const chainRequest404 = new Chain(response404);    chainRequest400.setSuccessor(chainRequest401);   chainRequest401.setSuccessor(chainRequest403);   chainRequest403.setSuccessor(chainRequest404);    chainRequest400.passRequest(error); };

这时就很有链的感觉了,大家还可以再继续根据自己的需求做调整,或是也不一定要使用类,因为设计模式的使用并不需要局限于如何实现,只要有表达出该模式的意图就够了。

责任链的优缺点

优点:

符合单一职责,使每个方法中都只有一个职责。

符合开放封闭原则,在需求增加时可以很方便的扩充新的责任。

使用时候不需要知道谁才是真正处理方法,减少大量的 if 或 switch 语法。

缺点:

团队成员需要对责任链存在共识,否则当看到一个方法莫名其妙的返回一个 next 时一定会很奇怪。

出错时不好排查问题,因为不知道到底在哪个责任中出的错,需要从链头开始往后找。

就算是不需要做任何处理的方法也会执行到,因为它在同一个链中,文中的例子都是同步执行的,如果有异步请求的话,执行时间也许就会比较长。

与策略模式的不同

在前面我还提到过策略模式,先说说两个模式之间的相似处,那就是都可以替多个同一个行为(response400、response401  等)定义一个接口(httpErrorHandler),而且在使用时不需要知道最后是谁执行的。在实现上策略模式比较简单。

由于策略模式直接用 if 或 switch  来控制谁该做这件事情,比较适合一个萝卜一个坑的状况。而策略模式虽然在例子中也是针对错误的状态码做各自的事,都在不归自己管的时候直接把事交给下一位处理,但是在责任链中的每个节点仍然可以在不归自己管的时候先做些什么,然后再交给下个节点:

const response400 = (error) => {   if (error.response.status !== 400) {     // 先做点什么...     return 'next';   }   console.log('你是不是提交了什么奇怪的东西?'); };

那在什么场景下使用呢?

为什么web开发中的代码越写越乱

比如在离职时需要走一个签字流程:你自己、你的 Leader  还有人资都需要做签字这件事,所以责任链就可以把这三个角色的签字过程串成一个流程,每个人签过后都会交给下面一位,一直到人资签完后才完成整个流程。而且如果通过责任链处理这个流程,不论之后流程怎样变动或增加,都有办法进行弹性处理。

上面的需求是策略模式所无法胜任的。

上述内容就是为什么WEB开发中的代码越写越乱,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网JavaScript频道。

--结束END--

本文标题: 为什么web开发中的代码越写越乱

本文链接: https://www.lsjlt.com/news/81650.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 为什么web开发中的代码越写越乱
    本篇文章为大家展示了为什么web开发中的代码越写越乱,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 目的在开始学习责任链之前,先看一下在开发中常见的问题。...
    99+
    2024-04-02
  • 为什么 Node.js 的 NPM 框架在 Java 开发中变得越来越受欢迎?
    在现代的Web开发领域中,Node.js已经成为了一种非常流行的开发框架。同时,Node.js的NPM框架也因其强大的包管理能力和丰富的资源库而受到了广泛的欢迎。但是,在Java开发领域中,为什么Node.js的NPM框架也变得越来越受欢迎...
    99+
    2023-07-08
    容器 npm 框架
  • 为什么越来越多的 Django 开发者选择 Go 存储缓存?
    随着 Web 应用程序的发展,数据缓存已经成为了一项至关重要的技术。在 Django 开发中,缓存可以显著提高 Web 应用程序的性能和可伸缩性。然而,传统的缓存存储技术比如 Memcached 和 Redis,虽然功能强大,但是它们也存...
    99+
    2023-11-08
    存储 django 缓存
  • 为什么越来越多的 Python 开发者正在转向 npm 函数?
    Python 一直以来是编程领域中备受欢迎的语言,它具有易读易写、开发效率高等特点,被广泛应用于 Web 开发、数据分析、人工智能等领域。但是,随着 Node.js 的出现和 npm 生态系统的日益完善,越来越多的 Python 开发者开...
    99+
    2023-09-01
    开发技术 npm 函数
  • 为什么越来越多的开发者选择使用 ASP 日志 api 接口?
    ASP日志API接口是一种用于记录服务器日志的接口,它可以帮助开发者更方便地记录服务器的运行情况,提高服务器的可靠性和稳定性。在近年来,越来越多的开发者开始选择使用ASP日志API接口,而不是传统的日志记录方式。那么,为什么越来越多的开发者...
    99+
    2023-06-19
    日志 api 接口
  • 为什么越来越多的开发者选择使用 Python 异步编程和 JavaScript 开发技术?
    随着互联网技术的不断发展,越来越多的开发者开始选择使用 Python 异步编程和 JavaScript 开发技术。那么,为什么会出现这种趋势呢?本文将从多个方面进行解析。 一、异步编程的优势 提高并发处理能力 异步编程的最大优势就是可以...
    99+
    2023-10-02
    异步编程 开发技术 javascript
  • 为什么越来越多的ASP开发者选择使用Spring Shell作为前端框架?
    随着互联网的迅速发展,Web应用程序的开发越来越受到广泛关注。对于ASP.NET开发人员而言,选择一个优秀的前端框架是非常重要的,因为这直接影响到应用程序的质量和性能。在这篇文章中,我们将探讨为什么越来越多的ASP.NET开发人员选择使用S...
    99+
    2023-08-17
    响应 spring shell
  • 为什么越来越多的互联网大厂开始使用Go语言了
    越来越多的互联网大厂开始使用Go语言了,譬如腾讯、美团、滴滴、百度、Google、bilibili...还有最初使用Python的字节跳动,甚至已经全面拥向Go了。这么多国内外首屈一指的公司,都在开始使用它了,它到底有什么优势呢?这就得谈谈...
    99+
    2023-05-14
    go语言 Golang
  • 为什么越来越多的开发者选择使用 Go 语言构建分布式实时 API?
    随着云计算和大数据技术的不断发展,分布式系统的应用场景越来越广泛。而在分布式系统中,API(Application Programming Interface)的作用越来越重要,它是各个服务之间进行数据交互和通讯的重要手段。 在构建分布式实...
    99+
    2023-11-05
    分布式 api 实时
  • web开发中怎么编写可读代码
    今天小编给大家分享一下web开发中怎么编写可读代码的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。代码为什么要易于理解“Cod...
    99+
    2023-06-17
  • 为什么越来越多的开发者选择使用 ASP 框架来实现分布式应用?
    随着分布式系统的发展和应用场景的不断扩大,越来越多的开发者选择使用ASP框架来实现分布式应用。为什么会出现这种趋势呢?在本文中,我们将深入探讨ASP框架的优势和特点,以及它在分布式应用中的应用。 首先,让我们了解一下ASP框架。ASP(Ac...
    99+
    2023-10-19
    框架 path 分布式
  • web开发中怎么写出优质干净的代码
    这篇文章主要介绍“web开发中怎么写出优质干净的代码”,在日常操作中,相信很多人在web开发中怎么写出优质干净的代码问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”web开发中...
    99+
    2024-04-02
  • 怎么编写高质量的web开发代码
    本文小编为大家详细介绍“怎么编写高质量的web开发代码”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么编写高质量的web开发代码”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Spring、Apache Com...
    99+
    2023-06-17
  • web开发中什么是URL编码
    这篇文章给大家分享的是有关web开发中什么是URL编码的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 根据RFC 3986,URL中的字符仅限于已定义的一组保留和未保留的US-...
    99+
    2024-04-02
  • web开发中Tab导航的示例代码
    这篇文章主要介绍web开发中Tab导航的示例代码,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! 在网页中应用选项卡可以使网页显得更紧凑,结合AJAX技术可以使页面在有限的空间内展现...
    99+
    2024-04-02
  • web开发中怎么用代码编制情书
    这篇文章主要讲解了“web开发中怎么用代码编制情书”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“web开发中怎么用代码编制情书”吧!感谢各位的阅读,以上就是“web开发中怎么用代码编制情书”...
    99+
    2023-06-03
  • 为什么代码重构在软件开发中很重要
    这篇文章主要讲解了“为什么代码重构在软件开发中很重要”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“为什么代码重构在软件开发中很重要”吧! 什么是代...
    99+
    2024-04-02
  • web开发中css样式代码的示例分析
    小编给大家分享一下web开发中css样式代码的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一.文本设置  1...
    99+
    2024-04-02
  • web开发中为什么要用语义化标签
    这篇文章将为大家详细讲解有关web开发中为什么要用语义化标签,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 语义化是给其他程序猿,更是给搜索引擎。 比如我一个页面可以...
    99+
    2024-04-02
  • web开发中低代码开发会带来怎样的安全风险
    今天就跟大家聊聊有关web开发中低代码开发会带来怎样的安全风险,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Gartner 还预测,在疫情期间远程开...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作