iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
Software Development

程式淨化計畫:痛苦是重構的起源!系列 第 28

Clean Code - Chapter 2 Meaningful Names - Part 2

  • 分享至 

  • xImage
  •  

以下是讀完 Clean code 第二章節(part 2)的筆記:

Avoid Mental Mapping

  • 一般做單字母會用在for迴圈, 比如i j k等
  • 但其他變數用單字母, 每個人的觀念不同
  • 於是明確完整的單字才是重要

Class Names

  • 要使用名詞或名詞短語
    • Customer
    • WikiPage
    • Account
    • AddessParser
  • 避免使用Manager, Processor, Data或Info
    • 避免Manager和processor等, 是因為職責太多的意思
  • 類別名稱不應該有動詞

Method Names

  • 要使用動詞或動詞短語
    • PostPayment
    • DeletePage
    • Save
  • 重構constructor, 使用static factory來描述參數, 比直接new constructor好
    • 將constructor設為private
Complex fulcrumPoint = Complex.FromRealNumber(23.0);

// is generally better than
Complex fulcrumPoint = new Complex(23.0);

Don’t Be Cute

  • 比如要終止東西, 使用的是Abort(), 而不是EatMyShorts()(去死吧的意思)
  • 也不是Whack()來取代Kill()

Pick One Word per Concept

  • fetch, retrieve, get等, 每個人對這術語命名不同
  • 在不了解意義的狀況下, 大都得查註解
  • 比如有人命名Controller, 又有Manager, 那這兩種什麼不同?
  • 如果你能以同一個概念對應只有一個單字命名, 對其他開發者是非常好的福利

Don’t Pun(雙關語)

  • 一術語多個意義就是一種雙關語
  • 比如有個容器類別, 只用add來新增內容
  • 如果多個類別都有add, 此時想想insert和append會不會比較好

Use Solution Domain Names

  • 盡量用電腦科學的相關術語做命名
  • 而不要用領域做命名
    • 因為得總是去跟客戶問定義
  • 比如, 我們習慣Visitor模式, 於是用AccountVisitor, 因為開發者都會知道這模式
  • 但如果命名JobQueue....誰會不知道這意思?
  • 所以用技術性當名詞是最好理解

Use Problem Domain Names

  • 如果是非技術性術語能做命名, 則用問題領域來命名
    • 得請教領域問題專家
  • 分離問題領域與技術方案, 是優秀開發者該做到的

Add Meaningful Context

  • 在一個情境內, 我們可以看到Street, zipcode, state等, 都認為是指地址
  • 但如果有個函數內只有state, 那會是什麼意思?
    • 也許前面多加上addrStreet, addrState可以區分
    • 但最好是建立一個Address類別
  • 以下是一段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);
}
  • number, verb, pluralModifier等都是看完程式碼才推測是”測估”的值
  • 以下是修改後的樣子
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";
  }
}
  • 這樣的重構是把函數拆成一個類別, 並為這三個field再用函數處理

Don’t Add Gratuitous(沒用的) Context

  • 假如你有個系統, 叫做GDS
  • 那你為每個類別都加上GDSXXXXXXX是沒有用的
    • 比如某客戶的Email, GDSCustomerAddress, 顯然GDSCustomer就很多餘
  • 用短名的類別夠清楚即可
  • 比如Address類別, 而他的實例變數用customerAddress是允許的
  • 地址類別也很多種, MAC, end point和郵政地址都有類似意義, 則為它們用不同類別名稱
    • URI
    • MAC
    • PostalAddress

Final Words

  • 命名是一種教學問題
  • 別怕重新命名

上一篇
Clean Code - Chapter 2 Meaningful Names - Part 1
下一篇
Clean Code - Chapter 3 Functions - Part 1
系列文
程式淨化計畫:痛苦是重構的起源!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言