MIT6.031學習筆記:(一)code review
寫在前面:
這門課程有點像國內的軟體工程課程,而國內的軟體工程課程,一般是講一些軟體工程的哲學…這門課程是將軟體工程的哲學放在 reading 中而專案作業分開。個人認為軟體工程哲學就是一種認同 ,即信則有,不信則無。更多的其實可以在今後工程專案中驗證。所以我的筆記其實就是我所認可的軟體工程哲學
goal
這門課所有的軟體工程哲學都圍繞著3個目標:
- safe from bugs
- easy to understand
- Ready for Change
這和我自己平時所寫的 ACM-ICPC 風格的程式碼有所不同,ACM-ICPC 程式碼只有一下一些目標:
- safe from bugs
- performence
- quick to code
特別是效能,ACMer 為了效能往往寫出很多 geek 風的程式碼
好進入這節reading的主題----code review
完整reading可參見
Style standards
其實關於 程式碼風格 我是並不刻意的,個人認為好的程式碼風格應該是好讀, 但是好讀的標準並不是一致的,因為個人的邏輯和條理性可能不同。但基本的換行空格還是要有的。這個沒啥好說的,各家公司都有自己的程式碼風格,說到某些特別的可能甚至會引起聖戰: 比如 {
的位置該換行還是不換行…,這種是很boring的
DRY(Don’t Repeat Yourself)
這個其實挺好理解的,比如
public static int dayOfYear(int month, int dayOfMonth, int year) {
if (month == 2) {
dayOfMonth += 31;
} else if (month == 3) {
dayOfMonth += 59;
} else if (month == 4) {
dayOfMonth += 90;
} else if (month == 5) {
dayOfMonth += 31 + 28 + 31 + 30;
} else if (month == 6) {
dayOfMonth += 31 + 28 + 31 + 30 + 31;
} else if (month == 7) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30;
} else if (month == 8) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31;
} else if (month == 9) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
} else if (month == 10) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
} else if (month == 11) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
} else if (month == 12) {
dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31;
}
return dayOfMonth;
}
上面重複的程式碼太多了,比如***dayOfMonth***, 以及一些數字.
COP(Copy-on-Paste) 的危害自不用說:
there’s a bug in both copies, and some maintainer fixes the bug in one place but not the othe
Comments Where Needed
適當註釋,這裡面給我們提供了幾個合理的註釋處:
- 函式開頭,有必要寫函式的作用(goal 1&2)
- 寫下程式碼的出處 這一條我以前從沒有注意過,但現在我認可了它: - 版權保護 - 好查詢,比如你去StackOverFlow抄了一段程式碼,但它以後改變了…
- 寫假設,就是某些程式碼段其實是包含了作者的假設的,這個時候寫下假設有助於今後的Test
Fail Fast
static err < dynamic err < wrong answer
static err: 語法錯誤,這個編譯器在語法解析,的時候就能檢查出來,某些IDE甚至能在寫的時候檢查出來 dynamic err: 編譯期出錯 wrong answer: 執行出結果才發現錯誤
Aviod Magic Number
這個應該是人人都知道的, 用常量代替某些 Magic Number
One Purpose For Each Variable
這個是想提醒我們,不要用同一個變量表示多種意義, 這是ACMer 很容易犯的錯誤,記得前天看 Tourist的程式碼,老沒看懂,就是他用了同一個變數前後表示不同的意思 ?, ?, 以及上面的那段程式碼,dayOfMonth,是返回值,又是引數,都是不好的程式碼。好的程式碼應該是易讀的(注意不是可讀)
Use Good Names
這個也是我經常犯的一個錯誤,tmp,data....
這些變數是無意義的,因為所有區域性變數都是tmp,所有變數都是data,用有意義的名字。
其實這一條可能在工作了寫多了之後自然就好了
Use Whitespace to Help the Reader
這個和編輯器有關,並不是叫你不用tab,只是說讓編輯器在按下tab 的時候將其轉化為 whitesapce 而不是\t
Don’t Use Global Variables
這個以前也沒注意,這裡的 Global Variables 是這樣的:
- a variable, a name whose value can be changed
- that is global, accessible and changeable from anywhere in the program.
對應在 java 就是 public static
修飾的,不過如果在後面加個 final 就沒事了
Methods Should Return Results, not Print Them
如題所說
Sumary
The topics of today’s reading connect to our three key properties of good software as follows:
-
Safe from bugs. In general, code review uses human reviewers to find bugs. DRY code lets you fix a bug in only one place, without fear that it has propagated elsewhere. Commenting your assumptions clearly makes it less likely that another programmer will introduce a bug. The Fail Fast principle detects bugs as early as possible. Avoiding global variables makes it easier to localize bugs related to variable values, since non-global variables can be changed in only limited places in the code.
-
Easy to understand. Code review is really the only way to find obscure or confusing code, because other people are reading it and trying to understand it. Using judicious comments, avoiding magic numbers, keeping one purpose for each variable, using good names, and using whitespace well can all improve the understandability of code.
-
Ready for change. Code review helps here when it’s done by experienced software developers who can anticipate what might change and suggest ways to guard against it. DRY code is more ready for change, because a change only needs to be made in one place. Returning results instead of printing them makes it easier to adapt the code to a new purpose.