「CleanCode」1章〜4章まとめ

Clean Code アジャイルソフトウェア達人の技

Clean Code アジャイルソフトウェア達人の技

途中だけどメモ。

1章 クリーンコード

  • 粗悪なコードは会社を廃業に追いやることもある
  • コードを新たに書き起こす際は、常に既存のコードを読まなければならない(読みやすさ=書きやすさ)
ボーイスカウトの法則
キャンプ場を、自分が見つけたときよりキレイにすること(コミットするときはチェックアウト時よりキレイに)

2章 意味のある名前

if文の条件
// Bad
if (複雑な条件式)

// Better
if (isFlagged())
意味のある対比
  • 悪い例
    • 変数名に連続した数字
    • classが予約後なのでklass
    • CustomerとCustomerObject
getActiveAccount();
getActiveAccounts();
getActiveAccountInfo();
// Bad
Complex fulcrumPoint = new Complex(23.0);

// Better
Complex fulcrumPoint = Complex.FromRealNumber(23.0);
1つのコンセプトには1つの単語
  • get,retrieve,fetch
  • controller,manager,driver

3章 関数

小さいこと!
関数の第一規則
小さくせよ
関数の第二規則
更に小さくせよ
ブロックとインデント

if文、for文等のブロックは1行でなければならない

関数は1つのことを行うようにせよ。その1つのことをきちんと行い、それ以外のことを行ってはならない。

1つの関数に1つの抽象レベル
// 抽象度高
getHtml();
// 抽象度中
String pagePathName = PathParser.render(pagePath);
// 抽象度低
buffer.append("\n");
switch文

switch文には問題がいっぱい

  • 関数が大きい
  • 関数が複数のことをやる
  • 単一責務の原則(SRP)に違反
  • 開放/閉鎖原則(OCP)に違反

switch文は最下層の抽象ファクトリに隠蔽

public abstract class Employee {
    public abstract boolean isPayDay();
    public abstract Money calculatePay();
    public abstract void deliverPay();
}

public interface EmployeeFactory {
    public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;
}

public class EmployeeFactory implements EmployeeFactory {
    public Employee makeEmployee(EmployeeRecord r) {
        switch(r.type) {
            case COMMISSIONED:
                return new CommissionedEmployee(r);
            ...
        }
    }
}
関数の引数
  • 関数の引数はできるだけ少なく
  • 出力引数は避ける
  • 引数をまとめてクラスにラップ

引数1(モナディック)の場合、

  • 引数について照会する
  • 引数を変換して(戻り値で)返す
  • イベント

以外の形式は避ける

// Bad
void transform(StringBuffer out);
// Better
StringBuffer transform(StringBuffer in)
フラグ引数

フラグ引数は悪!二つの関数に分割せよ

コマンド・照会の分離原則

関数は、何らかの処理を行うか、何らかの応答を返すかのどちらかを行うべき。

// ?
if (set("username", "unclebob")) ...
  • 引数よりも例外
  • try,catchブロックの中も1行で

4章 コメント

「ダメなコードをコメントで取り繕ってはいけない。書き直すのだ」

// Bad
// 従業員が、給与の完全給付を受けるかどうかチェック
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))

// Better
if (employee.isEligibleForFullBenefits())
良いコメント
  • まっとうなコメント(Author等)
  • 意図の説明
  • 結果に対する警告(@return)
  • TODOコメント(潰さなきゃいけないけど)
  • 公開APIに対するJavadoc
よくないコメント
  • 冗長なコメント
/**
 * このコンテナと関連付けられたLoggerの実装
 */
protected Log logger = null;
  • 命令コメント
/**
 *
 * @param title CDのタイトル
 * @param author CDの作曲家
 * @param tracks CDのトラック数
 * @param durationInMinutes CDの分単位の長さ
 */
public void addCD(String title, String author, int tracks, int durationInMinutes)
  • 日誌コメント(変更履歴)

バージョン管理に任せんさい

  • ノイズ
/**
 * デフォルトコンストラクタ
 */
public AnnualDateRule() {
}

/** 名前 */
private String name;
  • 道標
//// Actions ////////////////////////////////////////////
  • 閉じカッココメント

関数を短くすれば解決

...
        } // while
    } // try
...
    } // catch
} // main
  • 属性と署名

日誌コメントと同じくバージョン管理に任せる

これが大量にあると読む気が失せるよね

  • HTMLコメント
  • 非公開コードのJavadoc