クリーンコードクックブック

―コードの設計と品質を改善するためのレシピ集

[cover photo]
TOPICS
発行年月日
PRINT LENGTH
456
ISBN
978-4-8144-0097-3
原書
Clean Code Cookbook
FORMAT
Print PDF EPUB
Ebook
4,180円
Ebookを購入する
Print
4,180円

クリーンコードとは、読みやすく、理解しやすく、メンテナンスしやすいコードのことです。日々変更が加えられるシステムにおいて、クリーンコードはコードの品質を保ち、ソフトウェアの進化を促します。
本書では、ソフトウェアは現実をモデル化したものとして捉え、ソフトウェア設計においてドメインオブジェクトは現実世界の概念と1対1に対応しているべきだとしています。この考えに基づき、コードに頻繁に発生する問題への解決策をレシピという形で解説します。ドメインモデル貧血症、プリミティブ型への執着、命名やコメントの適切な使い方、YAGNI原則、フェイルファストの考え方、if文やnullの使用方法、早すぎる最適化の回避、結合度の低減、階層構造の整理、技術的負債の対処法、メタプログラミングや型の活用など、幅広いテーマを網羅します。
コード改善の実装例を使ってリファクタリングを学ぶ本書は、コーディングスキルを向上させたいプログラマやアーキテクトにとって、必携の一冊です。

目次

まえがき
はじめに

1章 クリーンコード
    1.1 コードの不吉な臭いとは何か?
    1.2 リファクタリングとは何か?
    1.3 レシピとは何か?
    1.4 クリーンコードの重要性
    1.5 可読性、パフォーマンス、あるいはその両方
    1.6 ソフトウェアの種類
    1.7 機械生成コード
    1.8 用語の使い方
    1.9 デザインパターン
    1.10 プログラミング言語のパラダイム
    1.11 オブジェクト対クラス
    1.12 変更容易性

2章 公理の準備
    はじめに
    2.1 モデルとは何か?
    2.2 抽象的とは何か?
    2.3 プログラム可能とは何か?
    2.4 なぜ部分的なモデル化なのか?
    2.5 なぜ説明可能性が重要なのか?
    2.6 なぜ現実に関するものなのか?
    2.7 ルールを導き出す
    2.8 唯一無二のソフトウェア設計原則

3章 貧血モデル
    はじめに
    レシピ3.1 貧血オブジェクトのリッチオブジェクトへの変換
    レシピ3.2 オブジェクトの本質の見極め
    レシピ3.3 オブジェクトからのセッターの除去
    レシピ3.4 貧弱なコード生成ツールの利用の廃止
    レシピ3.5 属性から自動生成されるゲッターやセッターの除去
    レシピ3.6 DTOの除去
    レシピ3.7 空のコンストラクタの除去と適切な初期化の実施
    レシピ3.8 ゲッターの除去
    レシピ3.9 オブジェクトの無秩序な結合の防止
    レシピ3.10 動的属性の除去

4章 プリミティブへの執着
    はじめに
    レシピ4.1 小さなオブジェクトの生成
    レシピ4.2 プリミティブデータの具象化
    レシピ4.3 連想配列のオブジェクトとしての具象化
    レシピ4.4 文字列の乱用の防止
    レシピ4.5 タイムスタンプの適切なモデル化
    レシピ4.6 サブセットの独立したオブジェクトとしての具象化
    レシピ4.7 文字列検証のオブジェクトとしての実装
    レシピ4.8 不要な属性の除去
    レシピ4.9 日付範囲オブジェクトの具象化

5章 変更可能性
    はじめに
    レシピ5.1 varのconstへの変更
    レシピ5.2 変更が必要な変数の適切な宣言
    レシピ5.3 本質に対する変更の禁止
    レシピ5.4 変更可能なconst配列の回避
    レシピ5.5 遅延初期化の除去
    レシピ5.6 変更可能な定数の凍結
    レシピ5.7 副作用の除去
    レシピ5.8 変数の巻き上げの防止

6章 宣言的なコード
    はじめに
    レシピ6.1 変数の再利用の抑制
    レシピ6.2 不要な空行の整理
    レシピ6.3 メソッド名からのバージョン情報の削除
    レシピ6.4 二重否定の肯定的な表現への書き換え
    レシピ6.5 責務の適切な再配置
    レシピ6.6 添字を使ったループ処理の高レベルな反復への置き換え
    レシピ6.7 設計上の判断の明確な表現
    レシピ6.8 マジックナンバーの定数での置き換え
    レシピ6.9 「何を」と「どのように」の分離
    レシピ6.10 正規表現の可読性の向上
    レシピ6.11 ヨーダ条件式の書き換え
    レシピ6.12 不適切な表現を含むメソッドの除去
    レシピ6.13 コールバック地獄の回避
    レシピ6.14 良いエラーメッセージの作成
    レシピ6.15 自動的な値の変換の回避

7章 命名
    はじめに
    レシピ7.1 略語の回避
    レシピ7.2 ヘルパーとユーティリティクラスの改名と責務の分割
    レシピ7.3 myで始まるオブジェクト名の変更
    レシピ7.4 resultという名の変数の回避
    レシピ7.5 型に基づいた変数名の変更
    レシピ7.6 長い名前の変更
    レシピ7.7 抽象的な名前の変更
    レシピ7.8 スペルミスの修正
    レシピ7.9 属性名からのクラス名の削除
    レシピ7.10 クラス・インターフェース名からの識別用文字の削除
    レシピ7.11 「Basic」や「Do」という関数名の変更
    レシピ7.12 複数形のクラス名の単数形への変更
    レシピ7.13 名前からのCollectionの削除
    レシピ7.14 クラス名からのImplの削除
    レシピ7.15 引数名の役割に応じた改善
    レシピ7.16 冗長な引数名の改善
    レシピ7.17 名前からの不必要な文脈の除去
    レシピ7.18 名前からのdataの削除

8章 コメント
    はじめに
    レシピ8.1 コメントアウトされたコードの除去
    レシピ8.2 古くなったコメントの整理
    レシピ8.3 条件式内の不適切なコメントの除去
    レシピ8.4 ゲッターのコメントの削除
    レシピ8.5 コメントの関数名への変換
    レシピ8.6 メソッド内のコメントの削除
    レシピ8.7 コメントのテストでの置き換え

9章 コーディング規約
    はじめに
    レシピ9.1 コーディング規約への準拠
    レシピ9.2 インデントの標準化
    レシピ9.3 大文字・小文字に関する規約の統一
    レシピ9.4 英語でのコードの記述
    レシピ9.5 引数の順序の統一
    レシピ9.6 割れた窓の修理

10章 複雑さ
    はじめに
    レシピ10.1 重複コードの除去
    レシピ10.2 設定/コンフィグおよび機能フラグの削除
    レシピ10.3 オブジェクトの状態変化を属性変更で表現することの廃止
    レシピ10.4 コードからの過度な技巧の除去
    レシピ10.5 複数のPromiseの分解
    レシピ10.6 長く続くメソッド呼び出しの連鎖の分割
    レシピ10.7 メソッドのオブジェクトとしての抽出
    レシピ10.8 配列コンストラクタの使用の回避
    レシピ10.9 ポルターガイストオブジェクトの除去

11章 肥大化要因
    はじめに
    レシピ11.1 長過ぎるメソッドの分割
    レシピ11.2 多過ぎる引数の削減
    レシピ11.3 過度な変数の削減
    レシピ11.4 過剰な括弧の除去
    レシピ11.5 過度なメソッドの削除
    レシピ11.6 多すぎる属性の分割
    レシピ11.7 importのリストの削減
    レシピ11.8 名前にAndが付いた関数の分割
    レシピ11.9 肥大化したインターフェースの分割

12章 YAGNI
    はじめに
    レシピ12.1 デッドコードの除去
    レシピ12.2 図ではなくコードによる表現
    レシピ12.3 サブクラスが1つしかないクラスのリファクタリング
    レシピ12.4 実装が1つしかないインターフェースの削除
    レシピ12.5 過剰なデザインパターンの見直し
    レシピ12.6 独自のコレクションクラスの見直し

13章 フェイルファスト
    はじめに
    レシピ13.1 変数の再利用を避けるリファクタリング
    レシピ13.2 事前条件の強制
    レシピ13.3 引数の型の厳格な制限
    レシピ13.4 switch文のdefault節における通常処理の除去
    レシピ13.5 コレクションの繰り返し処理中の変更の回避
    レシピ13.6 オブジェクトのハッシュ値と等価性の適切な実装
    レシピ13.7 機能変更を伴わないリファクタリング

14章 If
    はじめに
    レシピ14.1 偶発的なif文のポリモーフィズムを用いた書き換え
    レシピ14.2 状態を表す真偽値変数の名前の改善
    レシピ14.3 真偽値変数の具体的なオブジェクトへの置き換え
    レシピ14.4 switch/case/elseifの置き換え
    レシピ14.5 固定値と比較するif文のコレクションによる置き換え
    レシピ14.6 条件式の短絡評価の活用
    レシピ14.7 else節の明示的な記述
    レシピ14.8 階段状の条件分岐の簡素化
    レシピ14.9 短絡評価を利用したハックの回避
    レシピ14.10 ネストされたif文の書き換え
    レシピ14.11 条件分岐において真偽値を直接返却することの回避
    レシピ14.12 真偽値への暗黙的な型変換の防止
    レシピ14.13 複雑で長い三項演算子の簡素化
    レシピ14.14 非ポリモーフィック関数からポリモーフィック関数への変換
    レシピ14.15 オブジェクトの等価性の比較の改善
    レシピ14.16 ハードコードされたビジネス条件の具象化
    レシピ14.17 不要な条件式の削除
    レシピ14.18 ネストされた三項演算子の書き換え

15章 Null
    はじめに
    レシピ15.1 Nullオブジェクトの作成
    レシピ15.2 オプショナルチェーンの排除
    レシピ15.3 オプショナルな属性のコレクションによる表現
    レシピ15.4 null表現のための既存オブジェクトの活用
    レシピ15.5 未知の位置情報のnull以外による表現

16章 早すぎる最適化
    はじめに
    レシピ16.1 オブジェクトにおけるIDの回避
    レシピ16.2 早すぎる最適化の排除
    レシピ16.3 ビット演算子を用いた早すぎる最適化の排除
    レシピ16.4 過度な一般化の抑制
    レシピ16.5 根拠のない複雑なデータ構造の見直し
    レシピ16.6 未使用コードの削除
    レシピ16.7 ドメインオブジェクトにおけるキャッシュの見直し
    レシピ16.8 イベント処理における命名と実装の分離
    レシピ16.9 コンストラクタからのデータベースアクセスの分離
    レシピ16.10 デストラクタからのコードの排除

17章 結合
    はじめに
    レシピ17.1 隠された前提の明確化
    レシピ17.2 シングルトンの置き換え
    レシピ17.3 ゴッドオブジェクトの分割
    レシピ17.4 関連性のない責務の分離
    レシピ17.5 無効なデータを特殊な値で表すことの回避
    レシピ17.6 散弾銃型変更の解消
    レシピ17.7 オプション引数の排除
    レシピ17.8 フィーチャーエンヴィの防止
    レシピ17.9 中間者の排除
    レシピ17.10 デフォルト引数の末尾への移動
    レシピ17.11 波及効果の回避
    レシピ17.12 ビジネスオブジェクトからの偶発的なメソッドの削除
    レシピ17.13 ユーザーインターフェースからのアプリケーションロジックの分離
    レシピ17.14 クラス間の強い依存関係の解消
    レシピ17.15 データの塊のリファクタリング
    レシピ17.16 クラス間の過度な依存関係の解消
    レシピ17.17 同等性を持つオブジェクトの適切な表現

18章 グローバル
    はじめに
    レシピ18.1 グローバル関数の具象化
    レシピ18.2 スタティックメソッドの具象化
    レシピ18.3 goto文の構造化コードへの置き換え
    レシピ18.4 グローバルクラスの除去
    レシピ18.5 日付・時刻生成のグローバルな依存関係の解消

19章 階層構造
    はじめに
    レシピ19.1 深い継承の分割
    レシピ19.2 ヨーヨー階層の分割
    レシピ19.3 コード再利用のためのサブクラス化の回避
    レシピ19.4 「is-a」関係の振る舞いへの置き換え
    レシピ19.5 ネストしたクラスの除去
    レシピ19.6 グローバルクラスの適切な命名
    レシピ19.7 具象クラスのfinal化
    レシピ19.8 クラスの継承可否の明確化
    レシピ19.9 振る舞いのないクラスの除去
    レシピ19.10 早すぎる分類の回避
    レシピ19.11 protected属性の削除
    レシピ19.12 空のメソッドの適切な処理

20章 テスト
    はじめに
    レシピ20.1 プライベートメソッドのテスト
    レシピ20.2 アサーションへの説明の追加
    レシピ20.3 assertTrueから具体的なアサーションへの移行
    レシピ20.4 モックの実オブジェクトへの置き換え
    レシピ20.5 一般的なアサーションの改善
    レシピ20.6 不安定なテストの削除
    レシピ20.7 浮動小数点数のアサーションの変更
    レシピ20.8 テストデータの現実的なデータへの変更
    レシピ20.9 カプセル化を尊重したテスト設計
    レシピ20.10 テストにおける不要な情報の削除
    レシピ20.11 プルリクエストごとのテストカバレッジの確保
    レシピ20.12 日付に依存するテストの書き換え
    レシピ20.13 新しいプログラミング言語の学習

21章 技術的負債
    はじめに
    レシピ21.1 本番環境に依存するコードの排除
    レシピ21.2 イシュートラッカーの廃止
    レシピ21.3 警告オプションとストリクトモードの常時有効化
    レシピ21.4 TODOとFIXMEコメントの削除

22章 例外
    はじめに
    レシピ22.1 空の例外ブロックの除去
    レシピ22.2 不要な例外の除去
    レシピ22.3 期待されるケースにおける例外の使用の回避
    レシピ22.4 ネストしたtry/catchの書き換え
    レシピ22.5 リターンコードの例外への置き換え
    レシピ22.6 例外処理におけるアローコードの書き換え
    レシピ22.7 エンドユーザーからの低レベルなエラーの隠蔽
    レシピ22.8 tryブロックの範囲の縮小

23章 メタプログラミング
    はじめに
    レシピ23.1 メタプログラミングの使用の停止
    レシピ23.2 無名関数の具象化
    レシピ23.3 プリプロセッサの除去
    レシピ23.4 動的メソッドの除去

24章 型
    はじめに
    レシピ24.1 動的な型チェックの削除
    レシピ24.2 真値の扱い
    レシピ24.3 浮動小数点数型から十進数型への変更

25章 セキュリティ
    はじめに
    レシピ25.1 入力値のサニタイズ
    レシピ25.2 連番IDの置き換え
    レシピ25.3 外部パッケージへの依存の最小化
    レシピ25.4 危険な正規表現の改善
    レシピ25.5 オブジェクトのデシリアライゼーションの保護

付録A 用語集

訳者あとがき
索引