脳に収まるコードの書き方

―複雑さを避け持続可能にするための経験則とテクニック

[cover photo]
TOPICS
発行年月日
PRINT LENGTH
312
ISBN
978-4-8144-0079-9
原書
Code That Fits in Your Head
FORMAT
Print PDF EPUB
Ebook
3,740円
Ebookを購入する
Print
3,740円

ソフトウェアは複雑さを増すばかりですが、人間の脳は限られた複雑さしか扱えません。ソフトウェアが思い通りに動くようするには、脳に収まり、人間が理解できるコードを書く必要があります。
本書は、拡張を続けても行き詰ることなくコードを書き、複雑さを回避するための実践的な方法を解説します。最初のコードを書き始めるところから機能を追加していくところまでを解説し、効率的で持続可能なペースを保ちながら、横断的な問題への対処やトラブルシューティング、最適化を行なう方法を説明します。自分のチェックリストからチームワーク、カプセル化から分解、API設計から単体テストまで、ソフトウエア開発の重要な課題に対する考え方やテクニックを紹介します。サンプルプロジェクトで使うコードは、Gitリポジトリの形で入手でき、試しながら学べます。
有効に機能するプロセスを選び、効果のない方法論から脱却する方法。チェックリストを使うことで、すでに持っているスキルを活用する方法。アプリケーションのバーティカルスライス(ひとつの機能をUIからバックエンドまで一通り実装したもの)を作成しデプロイすることで、分析による停滞から脱却する方法を学びます。さらに、コードの腐敗や不必要な複雑さにつながる要因を避ける方法、コードの振る舞いを変更するためのテクニック、コードの問題を迅速かつ効果的に解決する方法について解説します。

サンプルコードのダウンロードについて

「関連ファイル」のリンクよりサンプルコードをダウンロードするには、ユーザー名とパスワードを用いた認証が必要です。
「ユーザー名」には「ctfiyh」と入力してください。
「パスワード」には、1章の図1-2(書籍およびPDFのp.10)の説明文にあるクイーン・アレクサンドリン橋が完成した年を半角数字4字で入力してください。

関連ファイル

目次

推薦の言葉
シリーズエディターによるまえがき
はじめに

第I部 加速

1章 アートかサイエンスか
    1.1 家を建てる
        1.1.1 プロジェクトの問題
        1.1.2 フェーズの問題
        1.1.3 依存関係
    1.2 庭を育てる
        1.2.1 何が庭を育てるのか?
    1.3 エンジニアリングに向けて
        1.3.1 工芸品としてのソフトウェア
        1.3.2 経験則
        1.3.3 ソフトウェアエンジニアリングの初期の概念
        1.3.4 ソフトウェアエンジニアリングの前進
    1.4 まとめ

2章 チェックリスト
    2.1 記憶の補助
    2.2 新規コードベースのためのチェックリスト
        2.2.1 Gitを使え
        2.2.2 ビルドを自動化せよ
        2.2.3 エラーメッセージをすべて有効にせよ
    2.3 既存のコードベースにチェックを追加する
        2.3.1 漸進的改善
        2.3.2 組織をハックする
    2.4 まとめ

3章 複雑さに対処する
    3.1 目的
        3.1.1 持続可能性
        3.1.2 価値
    3.2 なぜプログラミングは難しいのか
        3.2.1 脳のメタファー
        3.2.2 コードは書く回数より読む回数のほうが多い
        3.2.3 可読性
        3.2.4 知的労働
    3.3 ソフトウェアエンジニアリングに向けて
        3.3.1 コンピューターサイエンスとの関係性
        3.3.2 ヒューマンフレンドリーなコード
    3.4 まとめ

4章 バーティカルスライス
    4.1 動くソフトウェアから始める
        4.1.1 データ入力からデータ永続化まで
        4.1.2 最小のバーティカルスライス
    4.2 ウォーキングスケルトン
        4.2.1 特性評価テスト
        4.2.2 Arrange-Act-Assert
        4.2.3 静的解析の節度
    4.3 外側から内側へ(アウトサイドイン)
        4.3.1 JSON を受け取る
        4.3.2 予約をポストする
        4.3.3 ユニットテスト
        4.3.4 DTOとドメインモデル
        4.3.5 フェイクオブジェクト
        4.3.6 リポジトリインターフェイス
        4.3.7 リポジトリ内での作成
        4.3.8 依存を構成する
    4.4 バーティカルスライスを完成させる
        4.4.1 スキーマ
        4.4.2 SQLリポジトリ
        4.4.3 データベースの構成
        4.4.4 スモークテストの実施
        4.4.5 フェイクデータベースによる境界テスト
    4.5 まとめ

5章 カプセル化
    5.1 データの保存
        5.1.1 変換の優先順位
        5.1.2 パラメーター化テスト
        5.1.3 DTOをドメインモデルにコピーする
    5.2 バリデーション
        5.2.1 不正な日付
        5.2.2 レッド/グリーン/リファクタリング
        5.2.3 自然数
        5.2.4 ポステルの法則
    5.3 不変条件の保護
        5.3.1 常に有効
    5.4 まとめ

6章 三角測量
    6.1 短期記憶と長期記憶
        6.1.1 レガシーコードと記憶
    6.2 定員
        6.2.1 オーバーブッキング
        6.2.2 悪魔の代弁者
        6.2.3 既存の予約
        6.2.4 悪魔の代弁者vsレッド/グリーン/リファクタリング
        6.2.5 どれだけテストを書けば十分か?
    6.3 まとめ

7章 分解
    7.1 コードの腐敗
        7.1.1 しきい値
        7.1.2 サイクロマティック複雑度
        7.1.3 80/24ルール
    7.2 脳に収まるコード
        7.2.1 ヘックスフラワー
        7.2.2 凝集
        7.2.3 特性の横恋慕
        7.2.4 ロスト・イン・トランスレーション
        7.2.5 検証せずにパースする
        7.2.6 フラクタルアーキテクチャー
        7.2.7 変数を数える
    7.3 まとめ

8章 API設計
    8.1 API設計の原則
        8.1.1 アフォーダンス
        8.1.2 ポカヨケ
        8.1.3 読む人のために書く
        8.1.4 コメントよりもわかりやすい名前のコードを
        8.1.5 名前をXで置き換える
        8.1.6 コマンドクエリ分離
        8.1.7 コミュニケーション階層
    8.2 API設計の例
        8.2.1 メートル・ドテル
        8.2.2 カプセル化されたオブジェクトとやりとりする
        8.2.3 実装の詳細
    8.3 まとめ

9章 チームワーク
    9.1 Git
        9.1.1 コミットメッセージ
        9.1.2 継続的インテグレーション
        9.1.3 小さなコミット
    9.2 コードの共同所有
        9.2.1 ペアプログラミング
        9.2.2 モブプログラミング
        9.2.3 コードレビューの遅延
        9.2.4 チェンジセットを拒否する
        9.2.5 コードレビュー
        9.2.6 プルリクエスト
    9.3 まとめ

第II部 持続可能性

10章 コードの増大
    10.1 フィーチャーフラグ
        10.1.1 カレンダーフラグ
    10.2 ストラングラーパターン
        10.2.1 メソッドレベルストラングラー
        10.2.2 クラスレベルストラングラー
    10.3 バージョニング
        10.3.1 事前警告
    10.4 まとめ

11章 ユニットテストを編集する
    11.1 ユニットテストのリファクタリング
        11.1.1 セーフティネットの変更
        11.1.2 新しいテストコードの追加
        11.1.3 テストとプロダクションコードを別々にリファクタリングする
    11.2 テストの失敗を確認する
    11.3 まとめ

12章 トラブルシューティング
    12.1 理解
        12.1.1 科学的手法
        12.1.2 シンプルさ
        12.1.3 ラバーダッキング
    12.2 欠陥
        12.2.1 欠陥をテストとして再現する
        12.2.2 スローテスト
        12.2.3 非決定論的欠陥
    12.3 二分法
        12.3.1 Git による二分法
    12.4 まとめ

13章 関心事の分離
    13.1 合成
        13.1.1 ネストした合成
        13.1.2 逐次合成
        13.1.3 参照透明性
    13.2 横断的関心事
        13.2.1 ロギング
        13.2.2 デコレーター
        13.2.3 何をログに出力するか
    13.3 まとめ

14章 リズム
    14.1 個人のリズム
        14.1.1 タイムボックス
        14.1.2 休憩を取る
        14.1.3 意識して時間を使う
        14.1.4 タッチタイプ
    14.2 チームのリズム
        14.2.1 定期的に依存を更新する
        14.2.2 他のことも予定を入れる
        14.2.3 コンウェイの法則
    14.3 まとめ

15章 いつもの顔ぶれ
    15.1 パフォーマンス
        15.1.1 過去の遺物
        15.1.2 視認性
    15.2 セキュリティ
        15.2.1 STRIDE
        15.2.2 なりすまし
        15.2.3 改ざん
        15.2.4 否認
        15.2.5 情報漏えい
        15.2.6 サービス妨害
        15.2.7 権限昇格
    15.3 その他のテクニック
        15.3.1 プロパティベーステスト
        15.3.2 行動コード解析
    15.4 まとめ

16章 ツアー
    16.1 ナビゲーション
        16.1.1 全体像を見る
        16.1.2 ファイル構成
        16.1.3 詳細を見つける
    16.2 アーキテクチャー
        16.2.1 モノリス
        16.2.2 循環参照
    16.3 使ってみる
        16.3.1 テストから学ぶ
        16.3.2 テストの声を聞く
    16.4 まとめ

付録A プラクティス一覧
    A.1 50/72ルール
    A.2 80/24ルール
    A.3 Arrange-Act-Assert
    A.4 二分法
    A.5 新しいコードベースのためのチェックリスト
    A.6 コマンドクエリ分離
    A.7 変数を数える
    A.8 サイクロマティック複雑度
    A.9 横断的関心事のためのデコレーター
    A.10 悪魔の代弁者
    A.11 フィーチャーフラグ
    A.12 関数型コア・命令型シェル
    A.13 コミュニケーション階層
    A.14 ルールの例外を正当化する
    A.15 検証せずにパースする
    A.16 ポステルの法則
    A.17 レッド/グリーン/リファクタリング
    A.18 依存関係を定期的に更新する
    A.19 欠陥をテストとして再現する
    A.20 コードをレビューする
    A.21 セマンティックバージョニング
    A.22 テストとプロダクションコードを別々にリファクタリングする
    A.23 スライス
    A.24 ストラングラー
    A.25 脅威モデル
    A.26 変換の優先順位
    A.27 X駆動開発
    A.28 名前をXで置き換える

付録B 参考文献

訳者あとがき
索引

コラム目次
    デプロイパイプラインを確立するときによくある課題
    null許容参照型
    ArgumentNullExceptionがNullReferenceExceptionよりも優れている理由は?
    テスト駆動開発のサイエンス
    契約による設計
    ポステルの法則
    昇順に数値表現を書く
    Maybe
    適切な文章
    機動性
    バス係数