微信開發者平臺如何編寫代碼
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插件來自動為您設置代碼格式。 哈利路亞!
VS Code: Prettier
VS代碼: 更漂亮
Atom: Atom Beautify
原子: 原子美化
Sublime Text: Prettify
崇高文字: 美化
使用明確的變量和方法名稱 (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 roleconst user = {firstName: 'Rory',lastName: 'Millar',role: 'Admin'}// add the new user to the database - and log out the response or erroraxios.post('/user', user).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});
}function addManager(){ // create the user object and give the roleconst user = {firstName: 'James',lastName: 'Marley',role: 'Admin'}// add the new user to the database - and log out the response or erroraxios.post('/user', user).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});
}function addAdmin(){ // create the user object and give the roleconst user = {firstName: 'Gary',lastName: 'Judge',role: 'Admin'}// add the new user to the database - and log out the response or erroraxios.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 roleconst user = {firstName: 'Rory',lastName: 'Millar',role: 'Admin'}// add the new user to the database - and log out the response or errorsaveUserToDatabase(user);
}function addManager(){ // create the user object and give the roleconst user = {firstName: 'James',lastName: 'Marley',role: 'Admin'}// add the new user to the database - and log out the response or errorsaveUserToDatabase(user);
}function addAdmin(){ // create the user object and give the roleconst user = {firstName: 'Gary',lastName: 'Judge',role: 'Admin'}// add the new user to the database - and log out the response or errorsaveUserToDatabase(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 resultconst 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的郵件列表!
翻譯自: https://www.freecodecamp.org/news/the-junior-developers-guide-to-writing-super-clean-and-readable-code-cd2568e08aae/
微信開發者平臺如何編寫代碼