オブジェクト設計において、コードの読みやすさ、書きやすさ、メンテナンス性を向上させるにはどうすればよいでしょうか? 本書は、より良いオブジェクト指向のコードを書くためのルールを紹介します。オブジェクトの種類に応じたオブジェクトの構築、メソッドの定義、状態の変更や公開など、設計ルールを説明します。Java、Python、C#など、あらゆるオブジェクト指向言語に適用できるテクニックを、擬似コードを使ってわかりやすく解説します。コードの品質を上げるためのルールを紹介する本書は、プログラマ必携の一冊です。
オブジェクト設計スタイルガイド
Matthias Noback 著、田中 裕一 訳
- TOPICS
- Programming
- 発行年月日
- 2023年07月
- PRINT LENGTH
- 328
- ISBN
- 978-4-8144-0033-1
- 原書
- Object Design Style Guide
- FORMAT
- Print PDF EPUB
目次
まえがき 序文 本書について 1章 オブジェクトを使ったプログラミング入門 1.1 クラスとオブジェクト 1.2 状態 1.3 振る舞い 1.4 依存関係 1.5 継承 1.6 ポリモフィズム 1.7 コンポジション 1.8 クラスの整理 1.9 Return文と例外 1.10 ユニットテスト 1.11 動的配列 1.12 まとめ 2章 サービスの作成 2.1 2種類のオブジェクト 2.2 依存関係や設定値をコンストラクタ引数として渡す 2.2.1 一緒に使うべき設定値をまとめる 2.3 サービスロケータを注入するのではなく、必要なもの自体を注入する 2.4 すべてのコンストラクタ引数を必須とする 2.5 コンストラクタ引数による注入のみを使う 2.6 省略可能な依存関係というものは存在しない 2.7 すべての依存関係を明示する 2.7.1 スタティックな依存関係をオブジェクトの依存関係に変換する 2.7.2 複雑な関数をオブジェクトの依存関係にする 2.7.3 システムコールを明示する 2.8 タスクに関連するデータはコンストラクタ引数ではなくメソッド引数として渡す 2.9 サービスをインスタンス化した後にそのサービスの振る舞いを変更しない 2.10 コンストラクタの中ではプロパティへの代入以外は何もしない 2.11 引数が無効な場合には例外を投げる 2.12 サービスは少数のエントリポイントを持つイミュータブルなオブジェクトグラフとして定義する 2.13 まとめ 2.14 練習問題の解答 3章 ほかのオブジェクトの作成 3.1 一貫した振る舞いに最低限必要なデータを要求する 3.2 意味をなすデータを要求する 3.3 無効な引数の例外にカスタム例外クラスを使用しない 3.4 例外のメッセージを分析することで特定の無効な引数例外をテストする 3.5 ドメイン不変条件が複数の場所で検証されるのを防ぐために新しいオブジェクトを抽出する 3.6 複合値を表現する新しいオブジェクトを抽出する 3.7 アサーションを使ってコンストラクタ引数を検証する 3.8 依存関係は注入せず必要ならばメソッド引数として渡す 3.9 名前付きコンストラクタを使う 3.9.1 プリミティブ型の値からの作成 3.9.2 いたずらにtoString( )やtoInt( )などを追加しない 3.9.3 ドメイン固有の概念の導入 3.9.4 必要に応じてプライベートコンストラクタで制約を強制する 3.10 プロパティフィラーを使用しない 3.11 オブジェクトに不要なものは持たない 3.12 コンストラクタをテストしない 3.13 ルールの例外:データ転送オブジェクト 3.13.1 パブリックプロパティを使う 3.13.2 例外を投げるのではなくバリデーションエラーを収集する 3.13.3 必要であればプロパティフィラーを使用する 3.14 まとめ 3.15 練習問題の解答 4章 オブジェクトの操作 4.1 エンティティ:変更を追跡し、イベントを記録する識別可能なオブジェクト 4.2 バリューオブジェクト:置き換え可能、匿名、イミュータブルな値 4.3 データ転送オブジェクト:設計ルールの少ないシンプルなオブジェクト 4.4 イミュータブルオブジェクトを優先する 4.4.1 値を変更するのではなく置き換える 4.5 イミュータブルオブジェクトのモディファイアメソッドでは変更されたコピーを返す 4.6 ミュータブルオブジェクトではモディファイアメソッドはコマンドメソッドとする 4.7 イミュータブルオブジェクトではモディファイアメソッドは宣言的な名前にする 4.8 オブジェクト全体の比較 4.9 イミュータブルオブジェクトを比較するときは同一性ではなく同等性を確認する 4.10 モディファイアメソッドの呼び出しでは常に有効なオブジェクトを生成する 4.11 モディファイアメソッドで要求された状態の変化が有効であることを検証する 4.12 内部で記録されたイベントを使用してミュータブルオブジェクトの変更を検証する 4.13 ミュータブルオブジェクトに流れるようなインタフェースを実装しない 4.14 まとめ 4.15 練習問題の解答 5章 オブジェクトの使用 5.1 メソッドを実装するためのテンプレート 5.1.1 事前条件のチェック 5.1.2 失敗のシナリオ 5.1.3 ハッピーパス 5.1.4 事後条件のチェック 5.1.5 戻り値 5.2 例外に関するルール 5.2.1 カスタム例外クラスは必要な場合のみ使う 5.2.2 無効な引数やロジックの例外クラスの命名 5.2.3 実行時例外クラスの命名 5.2.4 失敗の理由を示すために名前付きコンストラクタを使う 5.2.5 詳細なメッセージの追加 5.3 まとめ 5.4 練習問題の解答 6章 情報の取得 6.1 情報取得のためにはクエリメソッドを使う 6.2 クエリメソッドでは単一の型の戻り値を持つ 6.3 内部状態を公開するようなクエリメソッドは避ける 6.4 尋ねたいクエリに特化したメソッドとその戻り値の型を定義する 6.5 システム境界を越えるクエリに対する抽象を定義する 6.6 クエリメソッドのテストダブルにはスタブを使う 6.7 クエリメソッドからはコマンドメソッドは呼び出さず、ほかのクエリメソッドのみを呼び出す 6.8 まとめ 6.9 練習問題の解答 7章 タスクの実行 7.1 コマンドメソッドには命令形の名前を使う 7.2 コマンドメソッドでやることを限定し、イベントを使用して二次的なタスクを実行する 7.3 外部からだけでなく内部からもサービスをイミュータブルにする 7.4 問題が発生したら例外を投げる 7.5 情報を収集するためにクエリを使用し、その次のステップに進むためにコマンドを使用する 7.6 システム境界を越えるコマンドに対する抽象を定義する 7.7 モックで検証するのはコマンドメソッドの呼び出しのみとする 7.8 まとめ 7.9 練習問題の解答 8章 責務の分割 8.1 ライトモデルとリードモデルを分離する 8.2 ユースケースに特化したリードモデルを作成する 8.3 データソースから直接リードモデルを作成する 8.4 ドメインイベントからリードモデルを構築する 8.5 まとめ 8.6 練習問題の解答 9章 サービスの振る舞いの変更 9.1 振る舞いを設定可能にするためのコンストラクタ引数を導入する 9.2 振る舞いを交換可能にするためにコンストラクタ引数を導入する 9.3 より複雑な振る舞いを実現するために抽象を合成する 9.4 既存の振る舞いを装飾する 9.5 追加の振る舞いには通知オブジェクトまたはイベントリスナを使う 9.6 オブジェクトの振る舞いを変更するために継承を使用しない 9.6.1 どのような場合に継承を使用するのがよいのでしょうか? 9.7 デフォルトでクラスをfinalとする 9.8 デフォルトでメソッドやプロパティをprivateとする 9.9 まとめ 9.10 練習問題の解答 10章 オブジェクトフィールドガイド 10.1 コントローラ 10.2 アプリケーションサービス 10.3 ライトモデルリポジトリ 10.4 エンティティ 10.5 バリューオブジェクト 10.6 イベントリスナ 10.7 リードモデルとリードモデルリポジトリ 10.8 抽象、具象、レイヤ、および依存関係 10.9 まとめ 11章 エピローグ 11.1 アーキテクチャパターン 11.2 テスト 11.2.1 クラステストとオブジェクトテスト 11.2.2 トップダウンの機能開発 11.3 ドメイン駆動設計 11.4 まとめ 付録A サンプルコードのコーディング規約 付録B スタイルガイド早見表 訳者あとがき 索引