天天看点

为什么要代码重构_为什么要重构代码

为什么要代码重构

Raise your hand if any of the following sounds familiar: Think about code formatting. Get rid of unnecessary

<div>

's and

<span>

's. Use functional React components. Try to avoid arrow function in render. And do not repeat yourself!

如果您熟悉以下任何一种情况,请举手:考虑代码格式化。 摆脱不必要的

<div>

<span>

。 使用功能性的React组件。 尽量避免在渲染中使用箭头功能。 而且不要重复自己!

Before I go straight to refactoring, I need you to answer one simple question: What does it mean to develop an application? Usually, this means producing a piece of software that meets requirements by implementing certain features.

在我直接进行重构之前,我需要您回答一个简单的问题:开发应用程序意味着什么? 通常,这意味着通过实施某些功能来生产满足要求的软件。

And how do we do that? We collect customer requirements, estimate them, and develop features one by one, right? Almost.

我们该怎么做? 我们收集客户需求,进行估算,然后逐一开发功能,对吗? 几乎。

不要忘记错误 (Do Not Forget About Bugs)

Yes, errors do occur. Depending on the development process, software complexity, technical stack, and many other parameters, the number of bugs may vary.

是的,确实会发生错误。 根据开发过程,软件复杂性,技术堆栈和许多其他参数,错误的数量可能会有所不同。

A business cannot afford critical issues in production. To minimize problems, you should pay particular attention to the QA process. But QA theory claims that it is usually impossible to run 100% test coverage of your apps and prepare for all possible scenarios.

企业无法承受生产中的关键问题。 为了最大程度地减少问题,您应该特别注意质量检查流程 。 但是质量检查理论声称,通常不可能对应用程序进行100%的测试覆盖率并为所有可能的情况做准备。

Still, to achieve optimal results, teams spend a lot of time testing software and fixing issues. This is a necessary part of the process that each customer should understand and prioritize.

尽管如此,为了获得最佳结果,团队仍然花费大量时间来测试软件和解决问题。 这是每个客户都应该理解并确定优先顺序的过程的必要部分。

注意技术债务 (Mind the Technical Debt)

Yet, this coin has a flip side. The longer the development and testing process takes, the more technical debt you incur.

然而,这种硬币有另一面。 开发和测试过程花费的时间越长,您承担的技术债务就越多。

So, what does "technical debt" mean? Technical debt refers to all the quality-related issues you have in your code. Issues which will require spending additional resources in the future.

那么,“技术债务”是什么意思呢? 技术债务是指代码中存在的所有与质量相关的问题。 将来需要花费更多资源的问题。

You incur technical debt for a variety of reasons, such as:

您由于各种原因而招致技术债务,例如:

  1. The business pushes to release new features faster.

    该业务推动更快地发布新功能。

  2. Testing is insufficient.

    测试不足。

  3. The requirements are changing rapidly.

    需求在Swift变化。

  4. The developers are inexperienced.

    开发人员没有经验。

Technical debt should be documented. If you do not leave to-do's in the code, you will most likely forget about the issue. And even if you have time for it in the future, you will not remember to fix it.

技术债务应记录在案。 如果您没有在代码中保留待办事项,则很可能会忘记该问题。 即使将来有时间,也不会记得进行修复。

了解重构的重要性 (Understand the Importance of Refactoring)

Usually, you need to spend some time refactoring the existing code in order to solve code quality issues and thus lower technical debt.

通常,您需要花费一些时间来重构现有代码,以解决代码质量问题,从而降低技术负担。

But what is refactoring? It is the process of restructuring the existing code without changing its external behavior. And that is actually something that might be difficult to understand for business people managing the project.

但是什么是重构? 这是在不更改其外部行为的情况下重组现有代码的过程。 对于管理项目的业务人员来说,这实际上可能是很难理解的。

– Will we get any new features?

–我们会获得任何新功能吗?

– Will we get any new features?

–我们会获得任何新功能吗?

– No.

–没有

– No.

–没有

– Will we at least fix some bugs?

–我们至少会修复一些错误吗?

– Will we at least fix some bugs?

–我们至少会修复一些错误吗?

– Also no.  

–也没有。

– Also no.  

–也没有。

– What will we get then?

–那我们将得到什么?

– What will we get then?

–那我们将得到什么?

Working with technical debt helps to avoid bugs. And to add fixes or changes to the project, we always need to read the old code.

处理技术债务有助于避免错误。 为了向项目添加修订或更改,我们总是需要阅读旧代码。

Therefore, refactoring and maintaining good code quality will help us keep development at a good pace.

因此,重构和保持良好的代码质量将有助于我们保持良好的开发速度。

Sometimes a business might not need it. For instance, if you're working on a prototype or Proof of Concept, or if there are business priorities that cannot be adjusted, you can do without refactoring.

有时企业可能不需要它。 例如,如果您正在开发原型或概念证明 ,或者如果有无法调整的业务优先级,则可以不进行重构。

But in most cases, cutting out refactoring is not a wise thing to do. You might spend a huge amount of time on refactoring if your developers are perfectionists, but this makes no sense either.

但是在大多数情况下,减少重构并不是明智的选择。 如果您的开发人员是完美主义者,那么您可能会花费大量时间进行重构,但这也没有道理。

Therefore, you need to strike a balance. You should not spend more time refactoring than you will save in the future.

因此,您需要保持平衡。 您重构所花费的时间不应超过将来节省的时间。

如何开始重构您的React代码 (How to Start Refactoring Your React Code)

考虑一下代码格式 (Think about code formatting)

Some people add trailing commas, and some don't. Some use single quotes, while others use double quotes for a string.

有些人添加尾随逗号,有些则没有。 有些使用单引号,而另一些使用双引号表示字符串。

If you work in a team, maintaining the common code style can be really difficult. And inconsistency in code style can make your code look dirty and hard to read.

如果您在团队中工作,维护通用代码样式可能真的很困难。 而且,代码风格的不一致会使您的代码看起来肮脏且难以阅读。

So if you haven’t thought about using code formatting tools before, it’s high time to do so. One of the most popular and easy-to-use React refactoring tools is Prettier. You can just add it to the project and it will take care of formatting for you.

因此,如果您以前从未考虑过使用代码格式化工具,那么该是时候了。 其中最流行的和易于使用的阵营重构工具是更漂亮 。 您只需将其添加到项目中,它将为您进行格式化。

Prettier has some default style settings, but you can change them according to your preferences by adding a

.prettierrc

file with your formatting rules.

Prettier具有一些默认样式设置,但是您可以根据喜好通过添加带有格式设置规则的

.prettierrc

文件来更改它们。

A good setup of

.prettierrc

may look like this:

.prettierrc

的良好设置可能如下所示:

{ "printWidth": 120,  "singleQuote": true, “trailingComma”: “none” }
           

You can also automatically reformat the code before committing with pre-commit hooks.

您还可以在使用pre-commit hook提交之前自动重新格式化代码。

摆脱不必要的<div>和<span> (Get rid of unnecessary <div>’s and <span>’s)

When React 16.2 was released in November 2017, a lot of React developers sighed in relief. Prior to that, for a component to return a list of children, it was necessary to wrap the children in an extra element, such as

<div>

or

<span>

.

当React 16.2在2017年11月发布时,许多React开发人员都松了一口气。 在此之前,要使组件返回子级列表,必须将子级包装在额外的元素中,例如

<div>

<span>

But with React 16.2 we received improved support for returning components’ children. Now developers can use so-called fragments. They look like empty JSX tags (

<> … </>

). With the help of fragments, you can pass a list of children to the component without adding extra nodes to the DOM.

但是通过React 16.2,我们得到了对返回组件子级的改进支持。 现在,开发人员可以使用所谓的片段。 它们看起来像空的JSX标记(

<> … </>

)。 借助片段,您可以将子代列表传递给组件,而无需向DOM添加额外的节点。

考虑名字 (Think about names)

Don’t be lazy when you're thinking about names for components and variables. Every name should be self-explanatory.

在考虑组件和变量的名称时,请不要偷懒。 每个名称都应不言自明。

Have you ever seen code snippets like this?

您见过这样的代码片段吗?

const modifyData = data.map(x => [x.a, x.b]))
           

What does it do? If you cannot understand the purpose of a variable from its name, it is time to rename it!

它有什么作用? 如果您不能从其名称中了解变量的用途,那么就该重命名它了!

This will help you and your team understand the logic more easily. It will also eliminate the time spent making changes to existing components in the future.

这将帮助您和您的团队更轻松地理解逻辑。 它还将消除将来在更改现有组件上花费的时间。

不要重复自己 (Don’t Repeat Yourself)

The DRY principle was first formulated in the book The Pragmatic Programmer. It states that "every piece of knowledge must have a single, unambiguous, authoritative representation within a system". In other words, you need to put repetitive code blocks into separate reusable components.

DRY原则首先在“实用程序员 ”一书中提出。 它指出:“每条知识都必须在系统中具有单一,明确,权威的表示形式”。 换句话说,您需要将重复的代码块放入单独的可重用组件中。

Making your code DRY has a lot of benefits. It can save you a lot of time. If you need to change this code in the future, you will only do that in one place. Also, you will never have to worry that you forgot to make changes in some places. Furthermore, you will keep the components cleaner and increase the readability of code.

使您的代码DRY有很多好处。 它可以节省您很多时间。 如果将来需要更改此代码,则只能在一个地方进行。 此外,您将不必担心忘记在某些地方进行更改。 此外,您将使组件更清洁,并提高代码的可读性。

To keep your components DRY and small, you can follow two simple rules:

为了使组件保持干燥和小巧,可以遵循两个简单的规则:

  1. If you use a code block more than two times, it’s time to extract it.

    如果您使用一个代码块两次以上,那么该提取它了。

  2. If you exceed a predefined number of lines in a component (e.g. 100 lines), there is probably logic that can be extracted. Divide it into smaller components by functionality.

    如果组件中的行数超出了预定义的数量(例如100条线),则可能存在可以提取的逻辑。 按功能将其分为较小的组件。

在类组件上使用功能 (Use functional over class components)

With the introduction of Hooks in React 16.8, we received access to React class features in functional components. Hooks solve a bunch of problems frequently encountered by developers over the past few years.

随着React 16.8中Hooks的引入,我们可以访问功能组件中的React类功能。 挂钩解决了开发人员在过去几年中经常遇到的一系列问题。

For example, the

useEffect

hook, as the React docs suggest, allows us to group the component logic into small functions based on what pieces are related (instead of grouping the logic based on life-cycle methods). This helps us to better restructure our logic.

例如,正如React文档所建议的,

useEffect

钩子允许我们分组 根据相关的部分将组件逻辑分解为小功能(而不是根据生命周期方法对逻辑进行分组)。 这有助于我们更好地重组逻辑。

All in all, refactoring React components with the help of hooks makes the code cleaner and reduces the amount of code you need to write.

总而言之,借助钩子重构React组件可以使代码更整洁并减少您需要编写的代码量。

Here is a very basic example: fetching the data after the component has mounted and re-fetching it based on the updated props.

这是一个非常基本的示例:在组件安装后获取数据,然后根据更新的道具重新获取数据。

In a class component, we would write something like this:

在类组件中,我们将编写如下内容:

class BookList extends React.Component {
  componentDidMount() {
    this.props.fetchBooks(this.props.bookGenre);
  }
  componentDidUpdate(prevProps) {
    if (prevProps.bookGenre !== this.props.booksGenre) {
      this.props.fetchBooks(this.props.bookGenre);
    }
  } 
// ... }
           

With React hooks it will look like this:

使用React钩子,它将看起来像这样:

const BookList = ({ bookGenre, fetchBooks }) => {
  useEffect(() => {
    fetchBooks(bookGenre);
  }, [bookGenre]);
// ... }
           

The books fetching logic is now gathered in one place. The

useEffect

hook will run after mount each time the props

[bookGenre]

in square brackets change. Much cleaner, isn’t it?

现在,取书逻辑聚集在一个地方。

useEffect

方括号中的props

[bookGenre]

更改时,

useEffect

挂钩将在安装后运行。 清洁得多,不是吗?

Also, you can extract similar stateful logic and reuse it in different components by creating your custom hooks. You can read more about custom hooks in the official React documentation.

另外,您可以提取相似的状态逻辑,并通过创建自定义的钩子在不同的组件中重用它。 您可以在React官方文档中阅读有关自定义钩子的更多信息。

尽量避免在渲染中使用箭头功能 (Try to avoid arrow functions in render)

Have you ever seen code like this?:

您见过这样的代码吗?:

render() {    
  return (
    <div>
      <button onClick={() => this.setState({ flag: true })} />
      ...      
    </div>    
  );  
}
           

Sure you have. What is the problem with it? Every time a component is rendered, a new instance of such a function is created.

当然可以。 有什么问题吗? 每次渲染组件时,都会创建该函数的新实例。

It is not a big deal if the component is rendered one or two times. But in other cases, it can really affect performance. So, if you care about performance, declare the function before using it in render:

如果组件渲染一两次,这没什么大不了的。 但是在其他情况下,它确实会影响性能。 因此,如果您关心性能,请在render中使用该函数之前先声明该函数:

changeFlag = () => this.setState({ flag: true })
render() {    
  return (      
    <div> 
      <button onClick={this.changeFlag} />        
      ...      
    </div>    
  );  
}
           

缩小包装 (Make the bundle smaller)

If you are using a third-party library, you should not load the entire thing if it isn't necessary. Sometimes you can stumble upon an import which uses only one method from the library, such as:

如果您使用的是第三方库,则不必加载整个库。 有时,您可能会偶然发现仅使用库中一种方法的导入,例如:

import lodash form 'lodash'  
...  
const certainProps = lodash.pick(userObject, ['name', 'email']);  ...
           

Instead, it is better to use the following:

相反,最好使用以下命令:

import pick from 'lodash/pick' 
... 
const certainProps = pick(userObject, ['name', 'email']); ...
           

Now you do not load the whole library, just the method you need.

现在,您无需加载整个库,只需加载所需的方法即可。

总结 (To Wrap Up)

Let's review the steps you should take to refactor your React code:

让我们回顾一下重构React代码应该采取的步骤:

  • Think about code formatting

    考虑一下代码格式

  • Get rid of unnecessary

    <div>

    's and

    <span>

    's

    摆脱不必要的

    <div>

    <span>

  • Think about names

    考虑名字

  • Don’t Repeat Yourself

    不要重复自己

  • Use functional over class components

    在类组件上使用功能

  • Try to avoid arrow functions in render

    尽量避免在渲染中使用箭头功能

  • Make the bundle smaller

    缩小包装

Yet, ideal refactoring is refactoring that does not occur. As a developer and especially as a tech lead, you should think many steps ahead and try to produce high-quality code. You should also carry out regular code reviews, not only within one team but also between teams.

但是,理想的重构是不会发生的重构。 作为开发人员,尤其是作为技术主管,您应该考虑很多步骤,然后尝试生成高质量的代码。 您还应该不仅在一个团队中而且在团队之间进行常规代码审查。

您对React项目有想法吗? (Do you have an idea for a React project?)

My company KeenEthics is an experienced React development company. If you are ready to change the game with your software project, feel free to request an estimate.

我的公司KeenEthics是经验丰富的React 开发公司 。 如果您准备使用软件项目来改变游戏规则,请随时提出估算 。

You can read more similar articles on my Keen Blog. Allow me to suggest The Value of User Testing or Angular vs React: What to Choose for Your App?

您可以在我的Keen博客上阅读更多类似的文章。 请允许我提出用户测试或Angular vs React 的价值 :为您的应用选择什么?

Most importantly, I would like to say "thank you" to Yaryna Korduba and Max Fedas, both outstanding React developers, for coauthoring this article as well as the readers for making it to the end!

最重要的是,我想对两位杰出的React开发人员Yaryna Korduba和Max Fedas表示感谢,感谢他们共同撰写了这篇文章,并感谢读者们写这篇文章到最后!

翻译自: https://www.freecodecamp.org/news/why-you-should-refactor-your-code/

为什么要代码重构