<style> .textleft { text-align:left; } .reveal, .reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 { font-family:Arial, Microsoft JhengHei;} .small-font { font-size: 20px !important; } .reveal .progress { height: 14px !important; } .progress span { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAMCAIAAAAs6UAAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUNCQzIyREQ0QjdEMTFFMzlEMDM4Qzc3MEY0NzdGMDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUNCQzIyREU0QjdEMTFFMzlEMDM4Qzc3MEY0NzdGMDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQ0JDMjJEQjRCN0QxMUUzOUQwMzhDNzcwRjQ3N0YwOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQ0JDMjJEQzRCN0QxMUUzOUQwMzhDNzcwRjQ3N0YwOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PovDFgYAAAAmSURBVHjaYvjPwMAAxjMZmBhA9H8INv4P4TPM/A+m04zBNECAAQBCWQv9SUQpVgAAAABJRU5ErkJggg==) repeat-x !important; } .progress span:after, .progress span.nyancat { content: ""; background: url(data:image/gif;base64,R0lGODlhIgAVAKIHAL3/9/+Zmf8zmf/MmZmZmf+Z/wAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpDMkJBNjY5RTU1NEJFMzExOUM4QUM2MDAwNDQzRERBQyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCREIzOEIzMzRCN0IxMUUzODhEQjgwOTYzMTgyNTE0QiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCREIzOEIzMjRCN0IxMUUzODhEQjgwOTYzMTgyNTE0QiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkM1QkE2NjlFNTU0QkUzMTE5QzhBQzYwMDA0NDNEREFDIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMyQkE2NjlFNTU0QkUzMTE5QzhBQzYwMDA0NDNEREFDIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8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) ; width: 36px !important; height: 21px !important; border: none !important; float: right; margin-top: -7px; margin-right: -10px; transform: scale(1.5,1.5); } .reveal section img { height: 550px !important; } </style> <!-- .slide: data-transition="slide" --> # Clean Code 讀書筆記 - Chapter 2 有意義的命名 @Kais(VagrantPi) ###### tags: `slide`, `簡報`, `Clean Code` --- <!-- .slide: data-transition="slide" --> ## Agenda - 讓名稱代表意圖 -- 使之名副其實 - 避免誤導 - 產生有意義的區別 - 能被唸出來的名稱 - 使用可被搜尋的名字 - 避免編碼 - 避免思維轉換 - 類別的命名 - 方法的命名 ---- <!-- .slide: data-transition="convex" --> - 不要裝可愛 - 每個概念使用一個字詞 - 別說雙關語 - 使用解決方案領域命名 - 使用問題領域的命名 - 添加有意義的上下文資訊(Context) - 別添加無理由的上下文資訊 - 總結 - Q&A - 該章節可否優化團隊現狀 --- <!-- .slide: data-transition="convex" --> ## 讓名稱代表意圖 -- 使之名副其實 ---- <!-- .slide: data-transition="convex" --> ```java int d; // elapsed time in days ``` ```java int elapsedTimeInDays; int daysSinceCreation; int daysSinceModification; int fileAgeInDays; ``` ---- <!-- .slide: data-transition="convex" --> ```java public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>(); // theList 代表什麼? for (int[] x : theList) // x[0] 代表什麼? // 4 代表什麼? if (x[0] == 4) list1.add(x); return list1; } ``` ---- <!-- .slide: data-transition="convex" --> 看得出來這邊會遍歷 gameBoard,如果 cell 的狀態碼為 FLAGGED,則會加到已標記(flaggedCells)list 中 ```diff - public List<int[]> getThem() { + public List<int[]> getFlaggedCells() { - List<int[]> list1 = new ArrayList<int[]>(); + List<int[]> flaggedCells = new ArrayList<int[]>(); - for (int[] x : theList) + for (int[] cell : gameBoard) - if (x[0] == 4) + if (cell[STATUS_VALUE] == FLAGGED) - list1.add(x); + flaggedCells.add(cell); - return list1; + return flaggedCells; } ``` ---- 這邊使用泛型進一步抽象化 <!-- .slide: data-transition="convex" --> ```diff - public List<int[]> getFlaggedCells() { + public List<Cell> getFlaggedCells() { - List<int[]> flaggedCells = new ArrayList<int[]>(); + List<Cell> flaggedCells = new ArrayList<Cell>(); for (Cell cell : gameBoard) - if (cell[STATUS_VALUE] == FLAGGED) + if (cell.isFlagged()) flaggedCells.add(cell); return flaggedCells; } ``` --- <!-- .slide: data-transition="convex" --> ## 避免誤導 ---- <!-- .slide: data-transition="convex" --> - 應避免專有系統中的專有名詞『縮寫』(hp、aix、sco) 另外這些命名也與一些系統平台或指令撞名 ---- <!-- .slide: data-transition="convex" --> - 清單類的變數,竟量不要出現 List,可能造成混淆 - 命名過長情況下,避免出現些微差別的其他命名 - XYZControllerForEfficient`Handling`OfStrings - XYZControllerForEfficient`Storage`OfStrings - 避免拼寫不一致,或是容易誤導的字 - O、0、l、1,單獨或偶而出現可能還好,不過很容易混淆 --- <!-- .slide: data-transition="convex" --> ## 產生有意義的區別 ---- <!-- .slide: data-transition="convex" --> - 在命名時使用數字序列或是無意義命名時,無法提供太多作者意圖 ```diff - public static void copyChars(char a1[], char a2[]) { + public static void copyChars(source a1[], destination a2[]) { for (int i = 0; i < a1.length; i++) { a2[i] = a1[i]; } } ``` ---- <!-- .slide: data-transition="convex" --> - 下面命名幾乎是無意義的,如同英文中的冠詞 `a`、`an`、`the` - `Data` 與 `Info` 之類的用詞也是無意義的,舉例 `ProductData`、`ProductInfo` 同樣代表 Product 類別的資料,但兩者差異只在於命名不同,幾乎等價於 `Product` - variable 字眼出現在變數命名 - table 字眼出現在表格名稱 - Customer 與 CustomerObject 差別在哪,哪個最能代表客戶付款紀錄 --- <!-- .slide: data-transition="convex" --> ## 能被唸出來的名稱 ---- <!-- .slide: data-transition="convex" --> 常見縮寫併再一起幾乎唸不出來 genymdhms (generation date, year, month, day, hour, minute, and second) 都念不出來了,更難想像意圖,因此沒有文件下,後續接手的同人無法維護 ---- <!-- .slide: data-transition="convex" --> 應該可以簡單判斷哪個比較好讀 ```java class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = "102"; /* ... */ }; ``` ```java class Customer { private Date generationTimestamp; private Date modificationTimestamp;; private final String recordId = "102"; /* ... */ }; ``` --- <!-- .slide: data-transition="convex" --> ## 使用可被搜尋的名字 ---- <!-- .slide: data-transition="convex" --> - 長命名勝於短命名 - 常數命名會避數字容易被搜尋 ```java const int WORK_DAYS_PER_WEEK = 5; ``` 比較要在整個專案中搜尋到 5,`WORK_DAYS_PER_WEEK` 會更好找到 --- <!-- .slide: data-transition="convex" --> ## 避免編碼 ---- <!-- .slide: data-transition="convex" --> - [匈牙利命名法 ](https://zh.wikipedia.org/zh-tw/%E5%8C%88%E7%89%99%E5%88%A9%E5%91%BD%E5%90%8D%E6%B3%95) - 會在字首加上型別,但其實在強型別語言中,就是無意義的規定 - 成員字首(Member Prefixes) - 不需要再變數前面新增 m_aaa, m_bbb 的前綴 ---- <!-- .slide: data-transition="convex" --> - Interface、Implementations 介面的命名,比起使用 `IShapeFactory` 更傾向使用 `ShapeFactory`,而如果一定要對 Interface、Implementations 進行命名,這樣這邊會建議只對 Implementations 命名。`ShapeFactoryImp` 都比在 interface 在前面加個 I 好 --- <!-- .slide: data-transition="convex" --> ## 避免思維轉換 ---- <!-- .slide: data-transition="convex" --> `i`、`j`、`k` 這類變數,使用在 for 迴圈內可說是約定熟成 但單個字當變數在其他地方,可以說是非常糟糕,還需要在腦內轉換一下,才能對應到真實的變數概念 『清楚才是王道』 --- <!-- .slide: data-transition="convex" --> ## 類別的命名 ---- <!-- .slide: data-transition="convex" --> class 的命名應該為名詞與名詞片語 - ⭕️ Customer(顧客) - ⭕️ WikiPage(維基頁面) - ⭕️ Account(帳戶) - ⭕️ AddressParser(地址解析器) - ❌ Manager(管理者) - ❌ Processor(處理者) - ❌ Data(資料) - ❌ Info(資訊) --- <!-- .slide: data-transition="convex" --> ## 方法的命名 ---- <!-- .slide: data-transition="convex" --> 方法應該是用動詞或是動詞片語 - postPayment(登記款項) - deletePage(刪除頁面) - save(儲存) ---- <!-- .slide: data-transition="convex" --> 此外,在 Javabean 的標準中 - accessors(取出器)使用 get 當字首 - mutators(修改器)使用 set 當字首 - predicates(判定)使用 is 當字首 --- <!-- .slide: data-transition="convex" --> ## 不要裝可愛 ---- <!-- .slide: data-transition="convex" --> HolyHandGrenade(神聖手榴彈),光看名字不知道這個 Method 要做什麼,娛樂價值大於實用 --- <!-- .slide: data-transition="convex" --> ## 每個概念使用一個字詞 ---- <!-- .slide: data-transition="convex" --> - fetch、retrieve、get,都可以用在取得的方法命名,但是如果沒有統一,在使用時會需要而外花時間理解 - controller(控制器)、manager(管理員)、driver(驅動程式)也不要一起使用, --- <!-- .slide: data-transition="convex" --> ## 別說雙關語 ---- <!-- .slide: data-transition="convex" --> 原先有一個 add 方法用來做『相加或想連』的概念,散落多個 class 中,今天有一個新類別也用了這個 add,但是功能卻將參數『加』進物件內。因此這出現了一個命名兩個意思的問題,這邊可能使用 insert 或是 append 會更好些 --- <!-- .slide: data-transition="convex" --> ## 使用解決方案領域命名 ---- <!-- .slide: data-transition="convex" --> 使用工程師的電腦科學專業術語、演算法名稱、pattern name、數學字彙協助命名 因為讀你程式碼的,也會是工程師 --- <!-- .slide: data-transition="convex" --> ## 使用問題領域的命名 ---- <!-- .slide: data-transition="convex" --> 可以詢問問題領域專家使用的術語來幫助命名 --- <!-- .slide: data-transition="convex" --> ## 添加有意義的上下文資訊(Context) ---- <!-- .slide: data-transition="convex" --> 變數時常需要搭配上下文,來盼端該變數實際的意義 如果只看到變數 state ,你會聯想到什麼 ---- <!-- .slide: data-transition="convex" --> 那看到 street, houseNumber, city, state, zipcode 你應該猜得出來這個 state 是什麼了 當然,如果將這些全部幫進 Address 的 class 會更清楚 ---- <!-- .slide: data-transition="convex" --> 以下有另外一個例子 ```java // 統計猜測 private void printGuessStatistics(char candidate, int count) { // 數字 String number; // 動詞 String verb; // 複數型態修改器 String pluralModifier; if (count == 0) { number = "no"; verb = "are"; pluralModifier = "s"; } else if (count == 1) { number = "1"; verb = "is"; pluralModifier = ""; } else { number = Integer.toString(count); verb = "are"; pluralModifier = "s"; } String guessMessage = String.format( "There %s %s %s%s", verb, number, candidate, pluralModifier ); print(guessMessage); } ``` ---- <!-- .slide: data-transition="convex" --> 這邊提到了幾個問題點 - 函數過長 - 所有區域變數在整段函數中都被使用 ```java public class GuessStatisticsMessage { private String number; private String verb; private String pluralModifier; public String make(char candidate, int count) { createPluralDependentMessageParts(count); return String.format( "There %s %s %s%s", verb, number, candidate, pluralModifier ); } private void createPluralDependentMessageParts(int count) { if (count == 0) { thereAreNoLetters(); } else if (count == 1) { thereIsOneLetter(); } else { thereAreManyLetters(count); } } private void thereAreManyLetters(int count) { number = Integer.toString(count); verb = "are"; pluralModifier = "s"; } private void thereIsOneLetter() { number = "1"; verb = "is"; pluralModifier = ""; } private void thereAreNoLetters() { number = "no"; verb = "are"; pluralModifier = "s"; } } ``` --- <!-- .slide: data-transition="convex" --> ## 別添加無理由的上下文資訊 ---- <!-- .slide: data-transition="convex" --> 假設有個系統『豪華版加油站(Gas Station Deluxe)』 因此在每個 Class 前都加上 GSD 字首,這很明顯在跟 IDE 做對,因為當輸入 `G` 後,會跳出系統哪所影類別的建議 ---- <!-- .slide: data-transition="convex" --> 此外,如果較小的命名可以清楚表達,則好過較長命名,以免添加過多與內文不符的名稱 ```java public class Address { private String accountAddress; // 帳戶地址 private String customerAddress; // 客戶地址 } ``` `accountAddress`、`customerAddress`是個明確的命名 --- <!-- .slide: data-transition="convex" --> ## 總結 ---- <!-- .slide: data-transition="convex" --> 需要良好的描述技巧,與共同的文化背景, --- <!-- .slide: data-transition="convex" --> ## Q&A --- <!-- .slide: data-transition="convex" --> ## 該章節可否優化團隊現狀 ---
{"metaMigratedAt":"2023-06-18T02:53:12.086Z","metaMigratedFrom":"Content","title":"Clean Code 讀書筆記 - Chapter 2 有意義的命名","breaks":true,"contributors":"[{\"id\":\"69ade472-3ed3-499d-8a69-767243a31621\",\"add\":9106,\"del\":320}]","description":"@Kais(VagrantPi)"}
    102 views