Clean code第一章
clean code
程式品質:每分鐘罵髒話的次數
劣質的程式碼
有時候常常想快點、很趕的狀況下完成工作項目,而我們盯著我們自行造成的 雜亂程式碼,若看到可以執行,就會留著他,待會有空再來整理程式。待會等於永不。
雜亂程式的代價
如果你是一位2~3年工程師,也許有被別人設計拖累牽絆的經驗, 程式品質好壞拖累的非常顯著。該團隊可能於初期開發迅速,但後期開發速度如蝸牛一般的速度前進,每次修改都非常困難、都需花費大量時間去了解混亂、曲折與打結的程式碼,時間越來越長,該專案已無法整理簡化。
最根本的難題
程式開發師面臨一個基本價值的難題,有著數年以上經驗開發者,都知道爛程式會降低他們效率,然而,開發者都感受到截止期限的壓力,所以只好產生爛程式以達到目標,但他們並沒有花費時間讓開發速度變更快。
真正的專家知道撰寫爛程式並不會趕上截止,事實上爛程式只能馬上讓開發速度變得更慢,讓你錯誤截止時間,唯一讓開發速度變快的方法,就是隨時隨地,讓程式碼盡可能保持整齊潔淨。
甚麼事clean code
減少重複
具有高度表達力
及早建立簡單抽象改念
有意義的命名
命名無所不在,我們替變數、函數、參數、類別與套件命名以下介紹簡單規則
讓名稱代表意圖--名符其實
名稱d沒有傳達任何意義,無法關聯跟消逝天數或天數有任何聯想
// bad
int d;//消逝的天數
選擇有意圖的名稱
int elapsedTimeInDays;
public List<int[]>getThem(){
List<int[]>list1=new ArrayList<>();
for(int[]x:theList){
if(x[0]==4){
list1.add(x);
}
}
return list1;
}
以上程式目的為何?
public List<int[]>getFlaggedCells(){
List<int[]>flaggedCells=new ArrayList<>();
for(int[]cell:gameBoard){
if(cell[STATUS_VALUE]==FLAGGED){
flaggedCells.add(cell);
}
}
return flaggedCells;
}
進一步
public List<Cell>getFlaggedCells(){
List<Cell>flaggedCells=new ArrayList<>();
for(cell cell:gameBoard){
if(cell.isFlagged()){
flaggedCells.add(cell);
}
}
return flaggedCells;
}
避免誤導
不要使用accountList,若型態非List,會有認知錯誤,否則改用 accountGroup、bunchOfAcounts。
拼字太過接近,容易無法辨識。
產生有意義的區別
public static void copyChar(char a1[],char[]a2){
//略
}
public static void copyChar(char source[],char[]destinaction){
//略
}
能夠唸出來的名稱
建立能溝通之語言,方便於專案內討論
使用可搜尋的名字
定義可以容易找到文字 MAX_CLASSES_PER_STUDENT (每學生最大修課次數) VS 7
若要定義短名稱如 i、j僅能出現於區域變數內
若常數與變數不少地方使用到,最好取容易搜尋名稱
成員的字首
不用對於成員變數,名稱增加m_xxxx
class Student{
private String id;
public Student(String id){
this.id=id;
}
}
介面和實作
介面與實作,常常根據專案架構而規定
MVC:介面 BillService、實作:BillServiceImpl clean architecture :介面 IBillService、實作:BillServiceByDB
類別的命名
應該使用名詞或名詞片語來命名
Customer顧客、Account(帳號)
方法的命名
應該使用動詞或動詞片語來命名
save、delete..等
Acccount.save(..);
每一種概念使用一種詞句
需統一專案概念名稱,常見元件結尾文字
MVC:Controller、Service、DAO、DTO、VO MVC:Controller、UseCase、Service、Repository、DTO、Command、Event
統一行為用詞:fetch、retrieve、get,需統一專案名詞
使用解決方案領域的命名
類似JobQueue,Factory
別說雙關語
add、insert、append差異要區別。
AcoountGroup acccounts=new AcoountGroup();
acccounts=acccounts.add(acccount);//? 加入原本帳號、產生新的帳號
使用問題領域命名
使用專案內定義之英文名稱,方便溝通
添加有意義的上下文
一般若看到id變數名稱,可能有無限猜測,可透過增加上下文提升可讀性 或是建立新該類別,將提供更帶概念SkillMessage。 ex:id > skillId
//含糊不清變數名稱
public void printName(String id) {
String name = "";
if (StringUtils.equals(id, "A")) {
name = "baseball";
} else if (StringUtils.equals(id, "B")) {
name = "badminton";
} else {
name = "unKnow";
}
System.out.print(MessageFormat.format("{0}:{1}", id, name));
}
public void printName(String skillId) {
String name = "";
if (StringUtils.equals(skillId, "A")) {
name = "baseball";
} else if (StringUtils.equals(skillId, "B")) {
name = "badminton";
} else {
name = "unKnow";
}
System.out.print(MessageFormat.format("{0}:{1}", skillId, name));
}
class SkillMessage {
String getName(String id) {
String name;
if (StringUtils.equals(id, "A")) {
name = "baseball";
} else if (StringUtils.equals(id, "B")) {
name = "badminton";
} else {
name = "unKnow";
}
return name;
}
}
public void printNameWithContext(String id) {
String skillName = new SkillMessage().getName(id);
System.out.print(MessageFormat.format("{0}:{1}", id, skillName));
}
Last updated
Was this helpful?