Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comments #44

Merged
merged 2 commits into from
Sep 29, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 54 additions & 53 deletions 1-js/03-code-quality/03-comments/article.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
# Comments
# 註解

As we know from the chapter <info:structure>, comments can be single-line: starting with `//` and multiline: `/* ... */`.
如我們從章節 <info:structure> 所學,註解可以是由 `//` 開始的單獨一行,或是使用 `/* ... */` 的多行註解。

We normally use them to describe how and why the code works.
我們通常使用它們來描述程式碼是如何與為什麼會運作。

At first sight, commenting might be obvious, but novices in programming often use them wrongly.
第一次寫註解應該會覺得很簡單,但菜鳥程式設計師通常會錯誤地使用它們。

## Bad comments
## 不佳的註解

Novices tend to use comments to explain "what is going on in the code". Like this:
初學者傾向於使用註解來解釋 "程式碼中發生什麼事",像這樣:

```js
// This code will do this thing (...) and that thing (...)
// ...and who knows what else...
// 這段程式碼會這樣 (...) 和那樣 (...)
// ...但誰知道還有什麼其它事...
very;
complex;
code;
```

But in good code, the amount of such "explanatory" comments should be minimal. Seriously, the code should be easy to understand without them.
但在良好的程式碼中,這種 "解釋用途" 註解的數量應該要盡量少。嚴格來說,就算沒有這些註解,程式碼應該也要易於理解。

There's a great rule about that: "if the code is so unclear that it requires a comment, then maybe it should be rewritten instead".
關於這點很棒的規則:"若程式碼不清楚到需要幫它寫註解,那也許它應該要被改寫"。

### Recipe: factor out functions
### 訣竅:分解成函式

Sometimes it's beneficial to replace a code piece with a function, like here:
有時候將一段程式碼片段替換成函式會更有幫助,像這樣:

```js
function showPrimes(n) {
nextPrime:
for (let i = 2; i < n; i++) {

*!*
// check if i is a prime number
// 確認 i 是否為質數
for (let j = 2; j < i; j++) {
if (i % j == 0) continue nextPrime;
}
Expand All @@ -43,7 +43,7 @@ function showPrimes(n) {
}
```

The better variant, with a factored out function `isPrime`:
更好的寫法,使用分解出來的函式 `isPrime`


```js
Expand All @@ -65,21 +65,21 @@ function isPrime(n) {
}
```

Now we can understand the code easily. The function itself becomes the comment. Such code is called *self-descriptive*.
現在我們可以更容易理解程式碼了。此函式本身變成了註解,這種程式碼被稱之為具有 *自我描述性(self-descriptive)*。

### Recipe: create functions
### 訣竅:建立函式

And if we have a long "code sheet" like this:
若我們有一個很長的 "程式碼片段(code sheet)",像這樣:

```js
// here we add whiskey
// 這邊我們加入威士忌
for(let i = 0; i < 10; i++) {
let drop = getWhiskey();
smell(drop);
add(drop, glass);
}

// here we add juice
// 這邊我們加入果汁
for(let t = 0; t < 3; t++) {
let tomato = getTomato();
examine(tomato);
Expand All @@ -90,7 +90,7 @@ for(let t = 0; t < 3; t++) {
// ...
```

Then it might be a better variant to refactor it into functions like:
將它重構成函式會是更好的寫法,就像:

```js
addWhiskey(glass);
Expand All @@ -111,21 +111,21 @@ function addJuice(container) {
}
```

Once again, functions themselves tell what's going on. There's nothing to comment. And also the code structure is better when split. It's clear what every function does, what it takes and what it returns.
再次強調,函式本身就會告訴我們發生什麼事,所以不需要註解。而且拆開後的程式碼結構也變得更好了,它做了什麼、需要什麼和回傳什麼都變得很清楚。

In reality, we can't totally avoid "explanatory" comments. There are complex algorithms. And there are smart "tweaks" for purposes of optimization. But generally we should try to keep the code simple and self-descriptive.
事實上,我們無法完全避免 "解釋用途" 的註解。因為會有一些複雜的演算法,和一些做優化用的聰明 "調整" 存在。但一般來說我們應該試著維持程式碼簡單並具有自我描述性。

## Good comments
## 良好的程式碼

So, explanatory comments are usually bad. Which comments are good?
所以,解釋用途的註解通常不好,那怎樣才算是好?

Describe the architecture
: Provide a high-level overview of components, how they interact, what's the control flow in various situations... In short -- the bird's eye view of the code. There's a special language [UML](http://wikipedia.org/wiki/Unified_Modeling_Language) to build high-level architecture diagrams explaining the code. Definitely worth studying.
描述架構
: 提供一個組件之間的高層次概況,它們是如何互動的,不同情況的控制流程是什麼... 簡單來說 -- 程式碼的鳥瞰圖。有種特殊的語言 [UML](http://wikipedia.org/wiki/Unified_Modeling_Language) 可建立高層次架構圖用以解釋程式碼,值得一讀。

Document function parameters and usage
: There's a special syntax [JSDoc](http://en.wikipedia.org/wiki/JSDoc) to document a function: usage, parameters, returned value.
將函式參數和用途寫入文件
: 有個特殊的語法 [JSDoc](http://en.wikipedia.org/wiki/JSDoc) 可以幫函式寫文件:用途、參數和回傳值。

For instance:
舉個例:
```js
/**
* Returns x raised to the n-th power.
Expand All @@ -139,42 +139,43 @@ Document function parameters and usage
}
```

Such comments allow us to understand the purpose of the function and use it the right way without looking in its code.
這種註解讓我們理解函式的用途,並且不用看內部的程式碼就可以正確地使用它們。

By the way, many editors like [WebStorm](https://www.jetbrains.com/webstorm/) can understand them as well and use them to provide autocomplete and some automatic code-checking.
對了,很多編輯器如 [WebStorm](https://www.jetbrains.com/webstorm/) 也可以看懂它們,並且提供自動完成和一些自動程式碼檢查。

Also, there are tools like [JSDoc 3](https://github.com/jsdoc3/jsdoc) that can generate HTML-documentation from the comments. You can read more information about JSDoc at <http://usejsdoc.org/>.
同樣的,有些工具像是 [JSDoc 3](https://github.com/jsdoc3/jsdoc) 可以由註解產生 HTML 文件,你可以在 <http://usejsdoc.org/> 閱讀更多 JSDoc 的資訊。

Why is the task solved this way?
: What's written is important. But what's *not* written may be even more important to understand what's going on. Why is the task solved exactly this way? The code gives no answer.
為什麼任務要用這種方式處理?
: 寫下了什麼是很重要的,但什麼 *沒被* 寫下的東西可能對於想理解發生什麼事來說更為重要。為什麼這個任務一定得使用這種方式處理?程式碼中可能得不到答案。

If there are many ways to solve the task, why this one? Especially when it's not the most obvious one.
若有多種解決任務的方法,為什麼選了這種?尤其當它並非是最明顯的一個時。

Without such comments the following situation is possible:
1. You (or your colleague) open the code written some time ago, and see that it's "suboptimal".
2. You think: "How stupid I was then, and how much smarter I'm now", and rewrite using the "more obvious and correct" variant.
3. ...The urge to rewrite was good. But in the process you see that the "more obvious" solution is actually lacking. You even dimly remember why, because you already tried it long ago. You revert to the correct variant, but the time was wasted.
沒有這種註解的話,底下這些情況就可能會發生:
1. 你(或你同事)打開一段時間前寫的程式碼,並發現它 "並非最佳解"。
2. 你想著:"我當初怎麼這麼蠢,還好我現在聰明多了",並且使用 "更明顯且正確" 的寫法改寫它。
3. ...改寫的衝勁是好的,但在過程中你發現 "更明顯" 的解法其實有所不足,甚至你依稀想起為什麼不行,因為你很久之前早就試過了。接著你把程式碼恢復原樣,但時間早已被浪費掉。

Comments that explain the solution are very important. They help to continue development the right way.
解釋解法的註解是非常重要的,它們有助於在正確的道路上開發。

Any subtle features of the code? Where they are used?
: If the code has anything subtle and counter-intuitive, it's definitely worth commenting.
程式碼中有著微妙的功能?它們被用在哪?
: 若程式碼內有任何微妙且違反直覺的東西,那就值得註解下來。

## Summary
## 總結

An important sign of a good developer is comments: their presence and even their absence.
一個良好開發者的重要指標之一就是其所寫的註解:知道何時該寫註解,何時不必寫。

Good comments allow us to maintain the code well, come back to it after a delay and use it more effectively.
良好的註解讓我們更好維護程式碼,在隔段時間後回來看它依然可以有效率的使用。

**Comment this:**
**註解這些:**

- Overall architecture, high-level view.
- Function usage.
- Important solutions, especially when not immediately obvious.
- 整體架構,高層次觀點。
- 函式的使用。
- 重要的解法,特別是那些不那麼立即明顯的。

**Avoid comments:**
**避免註解這些:**

- That tell "how code works" and "what it does".
- Put them in only if it's impossible to make the code so simple and self-descriptive that it doesn't require them.
- 告訴你 "程式碼如何運作" 和 "它做了什麼"。
- 只有在沒辦法讓程式碼夠簡單並具有自我描述性質的時候,才需要使用註解。

註解也可以被像是 JSDoc3 之類的自動文件工具所使用:可以讀懂註解並生成 HTML 文件(或其它格式)。

Comments are also used for auto-documenting tools like JSDoc3: they read them and generate HTML-docs (or docs in another format).