微信开发者平台如何编写代码
Writing code is one thing, but writing clean, readable code is another thing. But what is “clean code?” I’ve created this short clean code for beginners guide to help you on your way to mastering and understanding the art of clean code.
编写代码是一回事,但是编写清晰易读的代码是另一回事。 但是什么是“干净代码”? 我已经创建了这个简短的干净代码供初学者使用,以帮助您掌握和理解干净代码的技巧。
Imagine you are reading an article. There’s an opening paragraph, which gives you a brief overview of what the article is about. There are headings, each with a bunch of paragraphs. The paragraphs are structured with the relevant bits of information grouped together and ordered so that the article “flows” and reads nicely.
想象一下您正在阅读一篇文章。 有一个开始的段落,为您简要介绍了本文的内容。 有一些标题,每个标题都有许多段。 这些段落的结构是将相关的信息进行分组和排序,以便使文章“顺畅”地阅读。
Now, image the article didn’t have any headings. There are paragraphs, but they are long and in a confusing order. You can’t skim read the article, and have to really dive into the content to get a feel for what the article is about. This can be quite frustrating!
现在,图片上的文章没有任何标题。 有几段,但是很长,而且顺序混乱。 您不能略读文章,而必须真正深入研究内容才能了解文章的内容。 这可能非常令人沮丧!
Your code should read like a good article. Think of your classes/files as headings, and your methods as paragraphs. Sentences are the statements in your code. Here are some of the characteristics of clean code:
您的代码应该读起来像一篇好文章。 将您的类/文件视为标题,并将您的方法视为段落。 句子是代码中的语句。 以下是干净代码的一些特征:
- Clean code is focused — Each function, each class, and module should do one thing and do it well. 干净的代码侧重于每个函数,每个类和模块应该做的一件事情,并且做得很好。
It should be elegant — Clean code should be simple to read. Reading it should make you smile. It should leave you thinking “I know exactly what this code is doing”
它应该优雅-干净的代码应该易于阅读。 读它应该使你微笑。 它应该让您思考“我完全知道此代码在做什么”
- Clean code is taken care of. Someone has taken the time to keep it simple and orderly. They have paid appropriate attention to details. They have cared. 干净的代码已处理完毕。 有人花了一些时间使它保持简单和有序。 他们已经适当注意细节。 他们关心。
- The tests should pass — Broken code isn’t clean! 测试应该通过-损坏的代码不干净!
On to the big question of the day — how do you actually write clean code as a junior developer? Here’s my top tips to get started.
面对当今的一个大问题-作为初级开发人员,您实际上如何编写干净的代码? 这是我入门的主要技巧。
使用一致的格式和缩进 (Use consistent formatting & indentation)
Books would be hard to read if the line spacing was inconsistent, the font sizes were different, and the line breaks were all over the place. The same goes for your code.
如果行间距不一致,字体大小不同并且换行符到处都是,则很难阅读书籍。 您的代码也是如此。
To make your code clear and easy to read, make sure the indentation, line breaks, and formatting are consistent. Here’s a good and bad example:
为了使代码清晰易读,请确保缩进,换行符和格式一致。 这是一个好与坏的例子:
善良 (The Good)
function getStudents(id) {
if (id !== null) {
go_and_get_the_student();
} else {
abort_mission();
}
}
At a glance, you can tell there is an
if/else
statement within the function乍一看,您可以知道函数中是否包含
if/else
语句- Braces and consistent indentation make it easy to see where the code blocks start and end 大括号和一致的缩进使您可以轻松查看代码块的开始和结束位置
Braces are consistent — Notice how the opening brace for the
function
and for theif
are on the same line大括号是一致的—请注意该
function
和if
的开括号在同一行
坏人 (The Bad)
function getStudents(id) {
if (id !== null) {
go_and_get_the_student();}
else
{
abort_mission();
}
}
Woah! So much wrong here.
哇! 这里太错了。
The indentation is all over the place — you can’t tell where the function ends, or where the
if/else
block starts (yes there is an if/else block in there!)缩进无处不在–您无法确定函数在哪里结束,或者
if/else
块在哪里开始(是的,那里有一个if / else块!)- The braces are confusing and are not consistent 大括号令人困惑并且不一致
- The line spacing is inconsistent 行距不一致
This is a bit of an exaggerated example, but it shows the benefit of using consistent indentation and formatting. I don’t know about you, but the “good” example was much easier on the eyes for me!
这是一个夸张的示例,但是它显示了使用一致的缩进和格式的好处。 我不认识你,但是对我来说,“好”榜样要容易得多!
The good news is that there are many IDE plugins you can use to automatically format code for you. Hallelujah!
好消息是,您可以使用许多IDE插件来自动为您设置代码格式。 哈利路亚!
使用明确的变量和方法名称 (Use clear variable and method names)
In the beginning, I talked about how it’s important that your code is easy to read. A big aspect of this is the naming you choose (this is one of the mistakes I made when I was a junior developer). Let’s look at an example of good naming:
一开始,我谈到了易于阅读的代码的重要性。 其中一个很大的方面就是您选择的命名(这是我初级开发人员时犯的错误之一)。 让我们看一个好的命名示例:
function changeStudentLabelText(studentId){
const studentNameLabel = getStudentName(studentId);
}
function getStudentName(studentId){
const student = api.getStudentById(studentId);
return student.name;
}
This code snippet is good for a number of ways:
此代码段在许多方面都有好处:
The functions are named clearly with well-named arguments. When a developer is reading this, it’s clear in their mind, “If I call the
getStudentName()
method with astudentId
, I will get a student name back" - they don't have to navigate to thegetStudentName()
method if they don't need to!这些函数使用命名良好的参数明确命名。 当开发人员阅读
studentId
,他们的头脑很清楚:“如果我使用某个studentId
调用getStudentName()
方法,我将获得一个学生姓名” –如果他们使用导航器,则不必导航至getStudentName()
方法不需要!Within the
getStudentName()
method, the variables and method calls are again clearly named - it's easy to see that the method calls anapi
, get's astudent
object, and returns thename
property. Easy!在
getStudentName()
方法中,变量和方法调用再次被明确命名-很容易看出该方法调用了api
,得到了一个student
对象,并返回了name
属性。 简单!
Choosing good names when writing clean code for beginners is harder than you think. As your app grows, use these conventions to ensure your code is easy to read:
为初学者编写简洁的代码时,选择好名字比您想象的要难。 随着您的应用程序的增长,请使用以下约定来确保您的代码易于阅读:
Choose a naming style and be consistent. Either
camelCase
orunder_scores
but not both!选择一个命名样式并保持一致。
camelCase
或under_scores
但不能两者都选!Name your function, methods, and variables by what that thing does, or what that thing is. If your method get’s something, put
get
in the name. If your variable stores a color of a car, call itcarColour
, for example.通过功能或名称来命名函数,方法和变量。 如果你的方法获取的东西,把
get
的名称。 如果变量存储了汽车的颜色,则将其carColour
。
BONUS TIP — if you can’t name your function or method, then that function is doing too much. Go ahead and break it up into smaller functions! E.g if you end up calling your function updateCarAndSave()
, create 2 methods updateCar()
and saveCar()
.
奖金提示 -如果您不能命名您的函数或方法,则该函数做得太多。 继续并将其分解为较小的功能! 例如,如果最终调用函数updateCarAndSave()
,则创建2个方法updateCar()
和saveCar()
。
必要时使用评论 (Use comments where necessary)
There is a saying, “code should be self-documenting”, which basically means, instead of using comments, your code should read well enough reducing the need for comments. This is a valid point, and I guess this makes sense in a perfect world. Yet, the world of coding is far from perfect, so sometimes comments are necessary.
有一种说法,“代码应该是自我记录的”,这基本上意味着,除了使用注释,您的代码还应该阅读得足够好,从而减少了注释的需要。 这是一个正确的观点,我想这在一个完美的世界中是有道理的。 但是,编码的世界还远远不够完善,因此有时需要注释。
Documentation comments are comments that describe what a particular function or class does. If you’re writing a library, this will be helpful for developers who are using your library. Here’s an example from useJSDoc:
文档注释是描述特定功能或类功能的注释。 如果您正在编写库,这将对使用您的库的开发人员有所帮助。 这是useJSDoc的示例:
/** * Solves equations of the form a * x = b
* @example *
// returns 2 * globalNS.method1(5, 10);
* @example *
// returns 3 * globalNS.method(5, 15);
* @returns {Number} Returns the value of x for the equation. */ globalNS.method1 = function (a, b) { return b / a; };
Clarification comments are intended for anyone (including your future self) who may need to maintain, refactor, or extend your code. More often than not, clarification comments could be avoided, in favor of “self-documenting code”. Here’s an example of a clarification comment:
澄清注释适用于可能需要维护,重构或扩展您的代码的任何人(包括您将来的自己)。 通常,可以避免使用“自记录代码”的澄清注释。 这是一个澄清注释的示例:
/* This function calls a third party API. Due to some issue with the API vender, the response returns "BAD REQUEST" at times. If it does, we need to retry */
function getImageLinks(){
const imageLinks = makeApiCall();
if(imageLinks === null){
retryApiCall();
} else {
doSomeOtherStuff();
}
}
Here’s some comments you should try and avoid. They don’t offer much value, can be misleading and simply clutter the code.
这是您应该避免的一些评论。 它们提供的价值不高,可能会引起误解,并且只会使代码混乱。
Redundant comments that don’t add value:
不会增加价值的冗余注释:
// this sets the students age
function setStudentAge();
Misleading comments:
误导性评论:
//this sets the fullname of the student
function setLastName();
Funny or insulting comments:
有趣或侮辱性的评论:
// this method is 5000 lines long but it's impossible to refactor so don't try
function reallyLongFunction();
记住DRY原则(不要重复自己) (Remember the DRY principle (Don’t Repeat Yourself))
The DRY principle is stated as:
DRY原理表示为:
“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”
“每条知识都必须在系统中具有单一,明确,权威的表示形式。”
At its simplest level, this basically means that you should aim to reduce the amount of duplicated code that exists. (Note that I said “reduce” and not “eliminate” — There are some instances where duplicated code isn’t the end of the world!)
从最简单的角度讲,这基本上意味着您应该致力于减少重复代码的数量。 (请注意,我说的是“ 减少”而不是“消除” —在某些情况下,重复的代码并不是世界末日!)
Duplicated code can be a nightmare to maintain and alter. Let’s look at an example:
重复的代码可能是维护和更改的噩梦。 让我们看一个例子:
function addEmployee(){
// create the user object and give the role
const user = {
firstName: 'Rory',
lastName: 'Millar',
role: 'Admin'
}
// add the new user to the database - and log out the response or error
axios.post('/user', user)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
function addManager(){
// create the user object and give the role
const user = {
firstName: 'James',
lastName: 'Marley',
role: 'Admin'
}
// add the new user to the database - and log out the response or error
axios.post('/user', user)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
function addAdmin(){
// create the user object and give the role
const user = {
firstName: 'Gary',
lastName: 'Judge',
role: 'Admin'
}
// add the new user to the database - and log out the response or error
axios.post('/user', user)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
Imagine you are creating a human resources web app for a client. This app allows admins to add users with roles to a database via an API. There are 3 roles; employee, manager, and admin. Let’s look at some of the functions that might exist:
假设您正在为客户创建人力资源Web应用程序。 该应用程序允许管理员通过API将具有角色的用户添加到数据库中。 有3个角色; 员工,经理和管理员。 让我们看一下可能存在的一些功能:
Cool! The code works and all is well in the world. After a while, our client comes along and says:
凉! 该代码有效,世界上一切都很好。 过了一会儿,我们的客户说:
Hey! We would like the error message that is displayed to contain the sentence “there was an error”. Also, to be extra annoying, we want to change the API endpoint from
/user
to/users
. Thanks!嘿! 我们希望显示的错误消息包含句子“存在错误”。 另外,要使人烦恼的是,我们想将API端点从
/user
更改为/users
。 谢谢!
So before we jump in and start coding, let’s step back. Remember at the beginning of this clean code for beginners article, when I said “Clean code should be focused”. i.e, do one thing and do it well? This is where our current code has a small issue. The code that makes the API call and handles the error is repeated — which means we have to change the code in 3 places to meet the new requirements. Annoying!
因此,在我们开始编码之前,让我们退后一步。 请记住,在这篇针对初学者的干净代码的开头,当我说“应该重点关注干净代码”时。 即 一件事做得好吗? 这是我们当前代码存在一个小问题的地方。 重复进行API调用和处理错误的代码-这意味着我们必须在3个地方更改代码以满足新的要求。 烦人!
So, what if we refactored this to be more focused? Have a look at the following:
那么,如果我们将其重构为更加专注呢? 看看以下内容:
function addEmployee(){
// create the user object and give the role
const user = {
firstName: 'Rory',
lastName: 'Millar',
role: 'Admin'
}
// add the new user to the database - and log out the response or error
saveUserToDatabase(user);
}
function addManager(){
// create the user object and give the role
const user = {
firstName: 'James',
lastName: 'Marley',
role: 'Admin'
}
// add the new user to the database - and log out the response or error
saveUserToDatabase(user);
}
function addAdmin(){
// create the user object and give the role
const user = {
firstName: 'Gary',
lastName: 'Judge',
role: 'Admin'
}
// add the new user to the database - and log out the response or error
saveUserToDatabase(user);
}
function saveUserToDatabase(user){
axios.post('/users', user)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log("there was an error " + error);
});
}
We’ve moved the logic that creates an API call into its own method saveUserToDatabase(user)
(is that a good name? You decide!) which the other methods will call to save the user. Now, if we need to change the API logic again, we only have to update 1 method. Likewise, if we have to add another method that creates users, the method to save the user to the database via api already exists. Hurray!
我们已经将创建API调用的逻辑移到其自己的方法saveUserToDatabase(user)
(这是一个好名字吗?您决定!),其他方法将调用该方法来保存用户。 现在,如果我们需要再次更改API逻辑,则只需更新1个方法。 同样,如果我们必须添加另一个创建用户的方法,则已经存在通过api将用户保存到数据库的方法。 欢呼!
使用到目前为止所学知识进行重构的示例 (An example of refactoring using what we learned so far)
Let’s close our eyes and pretend really hard that we’re making a calculator app. There are functions that are used which allows us to add, subtract, multiply and divide respectively. The result is outputted to the console.
让我们闭上眼睛,非常假装自己正在制作计算器应用程序。 使用的函数使我们可以分别进行加,减,乘和除。 结果输出到控制台。
Here’s what we have so far. See if you can spot the issues before moving on:
到目前为止,这是我们所拥有的。 在继续之前,请先查看是否可以发现问题:
function addNumbers(number1, number2)
{
const result = number1 + number2;
const output = 'The result is ' + result;
console.log(output);
}
// this function substracts 2 numbers
function substractNumbers(number1, number2){
//store the result in a variable called result
const result = number1 - number2;
const output = 'The result is ' + result;
console.log(output);
}
function doStuffWithNumbers(number1, number2){
const result = number1 * number2;
const output = 'The result is ' + result;
console.log(output);
}
function divideNumbers(x, y){
const result = number1 / number2;
const output = 'The result is ' + result;
console.log(output);
}
What are the issues?
有什么问题?
- The indentation is inconsistent — it doesn’t matter too much what indentation format we use, just as long as it’s consistent 缩进不一致-只要一致,我们使用哪种缩进格式都没关系
- The 2nd function has some redundant comments — we can tell what’s going on by reading the function name and the code within the function, so do we really need a comment here? 第二个函数有一些多余的注释-我们可以通过读取函数名称和函数中的代码来了解发生了什么,所以我们在这里真的需要注释吗?
The 3rd and 4th functions don’t use good naming —
doStuffWithNumbers()
isn't the best function name as it doesn't state what it does.(x, y)
aren't descriptive variables either - arex & y
functions? numbers? bananas?第3和第4个函数的名称不好用
doStuffWithNumbers()
并不是最佳的函数名称,因为它没有说明其功能。(x, y)
也不是描述性变量-是x & y
函数吗? 数字? 香蕉?The methods do more than one thing — performs the calculation, but also displays the output. We can split the display logic out to a separate method — as per the DRY principle
这些方法不仅做一件事-执行计算,还显示输出。 我们可以按照DRY原理将显示逻辑拆分为单独的方法
Now we’ll use what we learned in this clean code for beginners guide to refactor everything so that our new code looks like:
现在,我们将使用在这段干净的代码中学到的内容供初学者使用,以重构所有内容,以便我们的新代码如下所示:
function addNumbers(number1, number2){
const result = number1 + number2;
displayOutput(result)
}
function substractNumbers(number1, number2){
const result = number1 - number2;
displayOutput(result)
}
function multiplyNumbers(number1, number2){
const result = number1 * number2;
displayOutput(result)
}
function divideNumbers(number1, number2){
const result = number1 * number2;
displayOutput(result)
}
function displayOutput(result){
const output = 'The result is ' + result;
console.log(output);
}
- We’ve fixed the indentation so that it's consistent 我们已经修复了缩进,使其一致
- Adjusted the naming of the functions and variables 调整了函数和变量的命名
- Removed the unneeded comments 删除了不必要的评论
Moved the
displayOutput()
logic into its own method - if the output needs to change, we only need to change it one place将
displayOutput()
逻辑移到了自己的方法中-如果需要更改输出,我们只需要将其更改一处
Congrats! You can now talk about how you know clean code principles in your interviews and when writing your killer resume!
恭喜! 现在,您可以在面试中以及撰写杀手级简历时谈论如何了解清晰的代码原理!
不要“过度清理”您的代码 (Don’t “over clean” your code)
I often see developers go over the top when it comes to clean code. Be careful not to try and clean your code too much, as it can have the opposite effect, and actually make your code harder to read and maintain. It can also have an impact on productivity, if a developer has to constantly jump between many files/methods in order to make a simple change.
我经常看到开发人员在编写干净代码方面越走越好。 注意不要尝试过多地清理代码,因为它会产生相反的效果,并实际上使您的代码难以阅读和维护。 如果开发人员必须不断在许多文件/方法之间进行跳转以进行简单的更改,那么它也可能会影响生产率。
Be mindful of clean code, but do not overthink it at the early stages of your projects. Make sure your code works, and is well tested. During the refactoring stage is when you should really think about how to clean up your code using the DRY principle etc.
请注意干净的代码,但不要在项目的早期阶段就过分考虑。 确保您的代码有效,并且已经过测试。 在重构阶段,您应该真正考虑如何使用DRY原理等清理代码。
In this clean code for beginners guide, we learned how to:
在这份干净的初学者代码指南中,我们学习了如何:
- Use consistent formatting & indentation 使用一致的格式和缩进
- Use clear variable and method names 使用明确的变量和方法名称
- Use comments where necessary 必要时使用评论
- Use the DRY principle (Don’t Repeat Yourself) 使用DRY原则(请勿重复)
If you enjoyed this guide, make sure to check out Clean Code: A Handbook of Agile Software Craftsmanship by Robert C Martin. If you are serious about writing clean code and breaking out of the junior developer level, I highly recommend this book.
如果您喜欢本指南,请确保阅读《 干净代码: Robert C Martin 的敏捷软件Craft.io手册》 。 如果您真的想编写干净的代码并突破初级开发人员的水平,我强烈推荐这本书。
Thanks for reading!
谢谢阅读!
To get the latest guides and courses for junior developers straight to your inbox, make sure to join the mailing list at www.chrisblakely.dev!
要直接为您的收件箱获取面向初级开发人员的最新指南和课程,请确保加入www.chrisblakely.dev的邮件列表!
微信开发者平台如何编写代码