扫描功能代码编写
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/b9d129120bce919a324d9bc7f01d5aa4.png)
This article is the second of a clean code series, you can find the first part about Clean Code Naming Conventions. Let’s jump in and learn how to code clean functions!
本文是简洁代码系列的第二篇,您可以找到关于简洁代码命名约定的第一部分。 让我们开始学习如何编写清理函数!
The quality of code is critical if the application is to be stable and easily extensible. Apparently nearly every developer, including myself, faced low-quality code in his career. So they’re a marsh. That kind of code has the following negative properties:
如果应用程序要稳定且易于扩展,则代码质量至关重要。 显然,几乎每个开发人员,包括我自己,在职业生涯中都面临着低质量的代码。 所以他们是沼泽。 这种代码具有以下负面特性 :
Functions are too lengthy and do too much
功能太冗长,功能太多
Functions also have side effects that are difficult to comprehend or even test
函数还具有难以理解甚至无法测试的副作用
The naming of functions and variables are vague
函数和变量的命名含糊不清
Fragile code: a small improvement unexpectedly damages certain components of the program
易碎的代码:微小的改进会意外损坏程序的某些组件
Bad or incomplete coverage of the code
代码覆盖范围错误或不完整
If you hear phrases like: “I don’t understand how this code works”, “this code is a mess”, “it’s hard to modify this code” and, that means your code has these negative properties.
如果您听到诸如以下的短语: “我不理解此代码的工作方式” , “此代码是一团糟” , “很难修改此代码” ,这意味着您的代码具有这些负面特性。
This article covers several best practices on how to write plain, understandable, and easy to test functions. Those are:
本文介绍了有关如何编写简单,可理解和易于测试的功能的几种最佳实践 。 那些是:
1. Functions should be small !!! Really2. Block and indenting3. Do one thing! (Single Responsibility Principle)4. Function names should say what they do5. Remove duplicate code6. Avoid Side Effects7. Remove dead code
1.功能应该很小! 真的2。 阻止和缩进3。 做一件事! (单一责任原则)4。 函数名称应说明其作用5。 删除重复的代码6。 避免副作用7。 删除无效代码
1.功能应该很小! 真 (1. Functions should be small !!! Really)
“The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that.” — Robert C. Martin
“功能的首要规则是它们应该很小。 功能的第二条规则是,它们应该小于该值。” -罗伯特·马丁
The first rule of writing functions is functions should be small. The second rule for writing functions is that they should be even smaller. Functions that have 200 or 300 lines are kind of messy functions. They should not be longer than 20 lines and mostly less than 10 lines. Functions should be making as few arguments as possible, ideally none. Small functions are easy to understand and their intention is clear.
编写函数的第一个规则是函数应该很小。 编写函数的第二条规则是它们应该更小 。 具有200或300行的函数有点杂乱。 它们不应超过20行,并且大多数情况下应少于10行。 函数应该使参数尽可能少,理想情况下应该没有参数。 小型功能易于理解,用途明确。
“Coding like poetry should be short and concise.”
“像诗歌这样的编码应该简短而简洁。”
― Santosh Kalwar
― Santosh Kalwar
There are some important rules in Refactoring in Large Software Projects by Martin Lippert and Stephen Roock. According to this, there are 2 more rules related to methods/functions. They are:
Martin Lippert和Stephen Roock 在大型软件项目中的重构中有一些重要规则。 据此,还有2条与方法/功能有关的规则。 他们是:
They should not have more than an average of 30 code lines (not counting line spaces and comments).
它们的平均不应超过30条代码行(不计算行空间和注释)。
A class should contain an average of fewer than 30 methods/functions, resulting in up to 900 lines of code.
一个类平均应包含少于30个方法/函数,从而导致多达900行代码。
Many people are so enamored of small functions that a strongly promoted idea of abstracting any and every piece of logic that may even are nominally complex into a separate function is something.
许多人迷恋小型功能,以至于强烈提倡将名义上甚至可能很复杂的任何逻辑抽象为单独的功能。
As an example:
举个例子:
function greetings() {console.log(“Hello World”);}// callinggreetings();
函数greetings(){console.log(“ Hello World”);} // callinggreetings();
There is a Visual Studio Code Extension ("CodeMetrics") which can automatically calculate the complexity in TypeScript / JavaScript / Lua files.
有一个Visual Studio代码扩展(“ CodeMetrics”),可以自动计算TypeScript / JavaScript / Lua文件中的复杂度。
If You want to know the causes You can click on the code lens to list all the entries for a given method or class. (This also allows You to quickly navigate to the corresponding code)
如果您想知道原因,则可以单击代码透镜以列出给定方法或类的所有条目。 (这也使您可以快速导航到相应的代码)
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/9755b92c298ef325beafe3d200fbcfd2.png)
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/53af49a7824447b771bc702dab17cffa.png)
2.阻止和缩进 (2. Block and indenting)
The rule of keeping the functions small also implies that we keep the code blocks inside if
, else
and while
statements minimal, preferably up to one line and that one line should be a function call. Similarly, we should avoid nesting such structures inside functions by moving the nested logic into another function.
保持函数较小的规则还意味着我们将代码块保留在if
, else
和while
语句最小的内部,最好最多一行,并且一行应该是一个函数调用。 同样,我们应避免通过将嵌套的逻辑移到另一个函数中来在函数内部嵌套此类结构。
Don't use long if, else, switch and while statements, because sometimes they make functions too big and messy.
不要长时间使用if,else,switch和while语句,因为有时它们会使函数变得太大和混乱。
If it is necessary to use if, else, switch and while statements, try to use only one or two lines and that line should be a function call.
如果有必要使用if,否则使用switch和while语句,请尝试仅使用一两行,并且该行应该是函数调用。
As below example;
如下面的例子;
function greetings(timePhase:string) {if (timePhase === “morning”) { console.log(“Good Morning”);} else if (timePhase === “afternoon”) { console.log(“Good Afternoon”);} else if (timePhase === “evening”) { console.log(“Good Evening”);} else { console.log(“Good Night”);}}// callinggreetings();
函数greetings(timePhase:string){ if(timePhase ===“ morning”){console.log(“ Good Morning”);} else if(timePhase ===“ Afternoon”){console.log(“ Good Afternoon” );} else if(timePhase ===“ evening”){console.log(“ Good Night”);} else {console.log(“ Good Night”);}} // callgreetings();
You can write this;
你可以写这个;
function printGreeting(greeting:string) {console.log(greeting);}
函数printGreeting(greeting:string){console.log(greeting);}
function greetings(timePhase: string) {let greeting = ‘Good’ + timePhase;printGreeting(greeting);}
函数greetings(timePhase:字符串){let greeting ='Good'+ timePhase; printGreeting(greeting);}
According to this example, it is simple, small, and easy to read and understand the code.
根据此示例,它简单,小巧并且易于阅读和理解代码。
![Image for post](https://miro.medium.com/max/9999/1*YnoOdG6gLD0Vw2B0MgQPfA.jpeg)
3.做一件事! (单一责任原则) (3. Do one thing! (Single Responsibility Principle))
“Functions should do one thing. They should do it well. They should do it only”.
“功能应该做一件事。 他们应该做好。 他们应该只做”。
DOTADIW: Do One Thing and Do It Well — Unix philosophy
DOTADIW: 做一件事情并做得很好— Unix哲学
![Image for post](https://miro.medium.com/max/9999/1*WOFx4BfwKU-DwGL0rgZbTg.png)
One function must do only one thing. If a function is doing more than one thing, the function should be split up into more functions.
一个功能只能做一件事。 如果一个功能要做的不止一件事情,则应将该功能拆分为更多的功能。
The Curly Rule, Do One Thing, is expressed in many key concepts of modern software development:
现代软件开发的许多关键概念都表达了“一条规则,做一件事情”:
Don’t Repeat Yourself
不要重复自己
If there is more than one way to express the same thing, it is likely that at some point the two or three different representations will be out of step. But if they don’t, you’ve guaranteed that if a transition happens, you have them in tandem. And a change is going to occur. Do not repeat yourself is important if you want flexible and maintainable software.
如果表达同一事物的方式不止一种,那么在某些时候,这两种或三种不同的表示可能会失调。 但是,如果不这样做,则可以保证如果发生过渡,则可以将它们串联在一起。 并且将发生变化。 如果您想要灵活且可维护的软件,请不要重复自己的做法,这一点很重要。
Once and Only Once
一次也只有一次
Both statements of conduct take effect once and only once. This is one of the key purposes when the code is restored if not the main goal. The design aims to eliminate duplicated behavioral statements by merging or replacing them with a unifying abstraction.
两种行为声明仅一次生效。 如果不是主要目的,则这是恢复代码时的主要目的之一。 该设计旨在通过合并或替换统一的抽象来消除重复的行为陈述。
Single Point of Truth
单点真理
Repetition leads to confusion and subtly broken codes because only a few repetitions were updated as expected. Sometimes that also means you didn’t think properly of your code. When you see duplicate code, this is a danger sign. Integrity is a cost, do not pay twice.
重复会导致混乱和巧妙地破坏代码,因为只有少数重复按预期进行了更新。 有时这也意味着您没有正确考虑您的代码。 当您看到重复的代码时,这是一个危险信号。 诚信是有代价的,不交两次。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/db923080003135024c0ad26696dd5198.png)
A class should have one and only one justification to alter, the Single Responsibility principle (SRP). To put this differently, for the same reasons the practices of a class should change; different factors that change at different levels should not be affected.
一类应该只有一个改变理由,即单一责任原则(SRP) 。 换句话说,出于相同的原因,班级的做法应该改变; 在不同级别上变化的不同因素不应受到影响。
4. 使用描述性名称 (4. Use Descriptive Names)
A function‘s name should explain what exactly it is doing. Nothing less, no more. Functions with names like “DO,” “ACTION,” for example, are not very useful, because we don’t know what their reach is.
函数名称应说明其确切功能。 没有少,没有更多。 例如,名称如“ DO”,“ ACTION”之类的功能不是很有用,因为我们不知道它们的作用范围。
The name of a variable, function, or class, should answer all the big questions. It should tell you;
变量,函数或类的名称应回答所有大问题。 它应该告诉你;
- Why it exists? 为什么存在?
- What does it do? 它有什么作用?
- How it is used? 如何使用?
If a name requires a comment, then the name does not reveal its intent.
如果名称需要注释,则该名称不会显示其意图。
Remember Ward’s principle: “You know you are working on clean code when each routine turns out to be pretty much what you expected.”
请记住Ward的原则:“ 当每个例程实际上都符合您的期望时,您知道您正在使用干净的代码。 ”
Half the difficulty for this is for good names to be selected for little roles. The smaller a feature is and the more centered the simpler a descriptive name is to pick.
困难的一半是为小角色选择好名字。 功能越小,居中越集中,描述性名称就越简单。
Don’t be scared about having a long name. It is easier to have a long descriptive name than a brick name. A name with a long description is better than a shorter description. Use a naming convention that allows multiple terms to be read easily in feature names, and then use the multiple words to name a feature.
不要害怕拥有一个长名字。 具有长描述性名称比使用砖名容易。 具有较长描述的名称比具有较短描述的名称更好。 使用一种命名约定,该约定允许在功能名称中轻松阅读多个术语,然后使用多个单词来命名功能。
Don’t be afraid to spend time choosing a name. Indeed, you should try several different names and read the code with each in place. Selecting descriptive names will help you clarify the module’s nature and develop it. It is not rare for a code to be restructured favorably by looking for a good name.
不要害怕花时间选择一个名字。 确实,您应该尝试几种不同的名称,并在适当的位置阅读代码。 选择描述性名称将有助于您阐明模块的性质并加以开发。 通过寻找好名字来对代码进行良好的重组并不罕见。
A few examples of good descriptive method names:
好的描述性方法名称的一些示例:
- WriteToOrderXmlFile() WriteToOrderXmlFile()
- CreateNewCustomer() CreateNewCustomer()
- CreateDeduplicatedListOfShippingContacts() CreateDeduplicatedListOfShippingContacts()
- GetListOfPartProductsNotInSalesforce() GetListOfPartProductsNotInSalesforce()
- CreateNewPartProduct() CreateNewPartProduct()
You can read my first article regarding naming conventions (Clean Code Naming Conventions) to get a better idea.
您可以阅读有关命名约定( Clean Code Naming Conventions )的第一篇文章,以获得更好的主意。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/49bb32721fab89788430368e1215d198.png)
5.删除重复的代码 (5. Remove duplicate code)
Make every attempt to prevent duplication of code. Duplication of the code is bad since it means that if you need to change a concept, there is more than one place to change things.
尽一切努力防止代码重复。 代码的重复是不好的,因为这意味着如果您需要更改概念,则可以在多个地方进行更改。
Just imagine running a restaurant and keeping an inventory track: all your tomatoes, onions, garlic, spices, etc. If you have several lists, everything must be revised when you serve a dish containing tomatoes. There is only one place to update if you have only one list!
想象一下经营一家餐馆并保持库存跟踪:您所有的西红柿,洋葱,大蒜,香料等。如果您有多个清单,则在提供含西红柿的菜肴时都必须修改所有内容。 如果只有一个列表,则只有一个地方可以更新!
Bad code:
错误代码:
public void method() {int a = 1;int b = 2;int c = a+b; // duplicateint d = b+c; // duplicate
}
...private int add(int a, int b) {return a+b;
}
After removing duplicate codes:
删除重复的代码后:
public void method() {int a = 1;int b = 2;int c = add(a,b);int d = add(b,c);
}
...private int add(int a, int b) {return a+b;
}
6.避免副作用 (6. Avoid Side Effects)
If a function does nothing other than entering a value and return other values or values, it creates a side effect. A side effect may be to write to a file, change a global variable, or by mistake to a stranger.
如果一个函数除了输入一个值并返回其他值或其他值外什么也不做,则会产生副作用。 副作用可能是写入文件,更改全局变量或错误地给陌生人。
Today, in the software you may also have side effects. You will need to write in a file, as in the previous example. It’s centralizing where you want to do this. Don’t have several features and classes to write a file. Have a program to do it. Just one. Just one.Side effects are mutations or actions that happen in our code environment that we cannot make an account of. It could result in pollution of the global scope.
今天,在软件中,您可能还会有副作用。 如上例所示,您将需要写入文件。 它集中在您要执行此操作的位置。 没有几个功能和类来写入文件。 有一个程序可以做到这一点。 只有一个。 副作用是我们无法解释的在代码环境中发生的变异或动作。 它可能导致全球范围的污染。
Bad Code:
错误代码:
// Global variable referenced by following function.
// If we had another function that used this name, now it'd be an array and it could break it.
let name = "Ryan McDermott";
function splitIntoFirstAndLastName() {
name = name.split(" ");
}
splitIntoFirstAndLastName();
console.log(name); // ['Ryan', 'McDermott'];
Good Code:
好代码:
function splitIntoFirstAndLastName(name) {
return name.split(" ");
}
const name = "Ryan McDermott";
const newName = splitIntoFirstAndLastName(name);
console.log(name); // 'Ryan McDermott';
console.log(newName); // ['Ryan', 'McDermott'];
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/29d9f5d65d4cbcbbae7ebbde105314d8.png)
7.删除无效代码 (7. Remove dead code)
Dead code is as poor as double code. There’s nothing in the coding base to hold it. Get rid of it if it’s not named! If you ever need it, it will remain secure in your version history.
无效代码和双重代码一样糟糕。 编码库中没有任何东西可以保留它。 如果它没有命名,请摆脱它! 如果您需要它,它将在您的版本历史记录中保持安全。
Nobody had the time to clean up the old code when the program specifications changed or corrections were made.
更改程序规范或进行更正时,没有人有时间清理旧代码。
The code can also be found in complicated situations if one of the branches (due to error or other circumstances) becomes inaccessible.
如果分支之一(由于错误或其他情况)变得不可访问,则在复杂情况下也可以找到该代码。
Visual Code extension (ESLint) can analyze your code to quickly find problems such as unused variables, functions, and classes, etc.
可视代码扩展( ESLint )可以分析您的代码以快速发现问题,例如未使用的变量,函数和类等。
Variables that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such variables take up space in the code and can lead to confusion by readers.
由于重构不完全,在代码中任何地方声明并没有使用的变量很可能是错误。 这样的变量会占用代码中的空间,并可能引起读者的困惑。
Bad Code:
错误代码:
/*eslint no-unused-vars: "error"*//*global some_unused_var*/// It checks variables you have defined as global
some_unused_var = 42;var x;// Write-only variables are not considered as used.var y = 10;
y = 5;// A read for a modification of itself is not considered as used.var z = 0;
z = z + 1;// By default, unused arguments cause warnings.
(function(foo) {return 5;
})();// Unused recursive functions also cause warnings.function fact(n) {if (n < 2) return 1;return n * fact(n - 1);
}// When a function definition destructures an array, unused entries from the array also cause warnings.function getY([x, y]) {return y;
}
Good Code:
好代码:
/*eslint no-unused-vars: "error"*/var x = 10;
alert(x);// foo is considered used here
myFunc(function foo() {// ...
}.bind(this));
(function(foo) {return foo;
})();var myFunc;
myFunc = setTimeout(function() {// myFunc is considered used
myFunc();
}, 50);// Only the second argument from the descructured array is used.function getY([, y]) {return y;
}
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/eed79eb2828b94d6e39de7c3ef25fa0b.png)
结论 (Conclusion)
The basic building blocks of any system are functions. These are device verbs, while classes are the substantives. This post focused on writing the functions so that they can be interpreted, understood, updated, and revised. It should be applied when taking into consideration the idea of DRY (Don’t Repeat Yourself). You would have descriptive, pure, and beautifully structured functions by following the above concepts and practices.
任何系统的基本构件都是功能。 这些是设备动词,而类是实体。 这篇文章着重于编写函数,以便可以对其进行解释,理解,更新和修订。 当考虑到DRY(不要重复自己)的想法时,应该使用它。 通过遵循上述概念和实践,您将获得描述性,纯净且结构精美的功能。
Previously they come out long and complicated when I write functions. They have plenty of nesting loops. You have long lists of arguments. The names are arbitrary and the code is doubled. However, now I like to refactor my code according to the standards.
以前,当我编写函数时,它们冗长而复杂。 它们具有大量的嵌套循环。 您的参数列表很长。 名称是任意的,并且代码已加倍。 但是,现在我喜欢根据标准重构代码。
It’s hard to think of those who apply business logic. There are plenty of guidelines to follow. No one can get their first attempt all right. Functions are like writing a story. There is a first draft, a second draft … and a final draft likewise, there can be a lot of drafts. Don’t be afraid to compose long, messy functions. When it works, improving it and restoring it until it sounds like a Harry Potter novel.
很难想到那些应用业务逻辑的人。 有很多指南可以遵循。 没有人能完成他们的第一次尝试。 功能就像写一个故事。 有一个初稿,一个第二稿……和一个最终稿,同样可以有很多草稿。 不要害怕编写冗长而混乱的函数。 当它起作用时,对其进行改进和恢复,直到听起来像一部哈利·波特小说为止。
When you are writing clean functions with descriptive names, you better to read my first article regarding naming conventions;
当您使用描述性名称编写简洁的函数时,最好阅读有关命名约定的第一篇文章;
“O-Robert C. Martin-
“ O- Robert C. Martin-
翻译自: https://medium.com/swlh/clean-code-writing-functions-or-methods-4e6e53ff4ac2
扫描功能代码编写