「現場で役立つシステム設計の原則」を読んだので、その要点

[現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法：書籍案内｜技術評論社](https://gihyo.jp/book/2017/978-4-7741-9087-7)
[Amazon.co.jp - 現場で役立つシステム設計の原則 ~変更を楽で安全にするオブジェクト指向の実践技法 | 増田 亨 |本 | 通販](https://www.amazon.co.jp/dp/477419087X)

![](https://images-fe.ssl-images-amazon.com/images/I/51fm-EVWsnL._SY291_BO1,204,203,200_QL40_ML2_.jpg)

[「良いコード／悪いコードで学ぶ設計入門」](https://qiita.com/e99h2121/items/0f71104dbc32a5d0047c) を読んで、こちらも読みたくなった本。要点のみメモ。


## 要点
### 第1章　小さくまとめてわかりやすくする
- なぜソフトウェアの変更は大変なのか
    - ソフトウェアの変更に立ち向かう
    - 変更が大変なプログラムの特徴
        - メソッドが長い
        - クラスが大きい
        - 引数が多い
    - 変更するたびに変更が大変になる
- プログラムの変更が楽になる書き方
    - わかりやすい名前を使う

```例
int a;
int qty;
int quantity;
```

- 長いメソッドは「段落」に分けて読みやすくする
```例
int price = quantity * unitPrice;

if (price < 3000)
    price += 500; //送料
```

- 目的ごとに変数を用意する
- メソッドとして独立させる
- 異なるクラスの重複したコードをなくす
- 狭い関心事に特化したクラスにする
- メソッドは短く，クラスは小さく
- 小さなクラスでわかりやすく安全に
    - 基本データ型の落とし穴
    - 業務上の桁数を想定しない型
```例
int quantity;
BigDecimal amount;
```

- 値の範囲を制限してプログラムをわかりやすく安全にする
    - 例えば電話番号は10ケタ、数値。単なるStringではない
- 「値」を扱うための専用のクラスを作る
- 値オブジェクトは「不変」にする
- 「型」を使ってコードをわかりやすく安全にする
- 複雑さを閉じ込める
    - 配列やコレクションはコードを複雑にする
    - コレクション型を扱うコードの整理
        - コレクション型を扱うロジックを専用クラスに閉じ込める
        - **コレクションオブジェクトは業務の関心事**

```java:良い例
class Customers {
    List<Customers> customers;

    ...

    Customers add(Customer customer) {
        List<Customer> result = new ArrayList<>(customers);
        return new Customers(result.add(customer));
    }
}

```

## 第2章　場合分けのロジックを整理する
- プログラムを複雑にする「場合分け」のコード
    - 区分や種別がコードを複雑にする
    - 判断や処理のロジックをメソッドに独立させる
    - else句をなくすと条件分岐が単純になる

```java:良い例

Yen fee() {
    if(isChild()) return childFee();
    if(isSenior()) return seniorFee();
}
```

- 複文は単文に分ける
- 区分ごとのロジックを別クラスに分ける
- 区分ごとのクラスを同じ「型」として扱う
- 区分ごとのクラスのインスタンスを生成する
- Javaの列挙型を使えばもっとかんたん
    - [入門Javaのenum - Qiita](https://qiita.com/suke_masa/items/bd242617a2b9bb773cbd)
- 区分ごとの業務ロジックを区分オブジェクトで分析し整理する
- 状態の遷移ルールをわかりやすく記述する


## 第3章　業務ロジックをわかりやすく整理する
- **データとロジック (計算式) を別のクラスに分けることがわかりにくさを生む**
    - 業務アプリケーションのコードの見通しが悪くなる原因
        - データクラスを使うと同じロジックがあちこちに重複する
        - データクラスを使うと業務ロジックの見通しが悪くなる
    - 共通機能ライブラリが失敗する理由
    - データクラスが広く使われているのは、手続き型プログラミングの実装単位として採用した結果
- 業務ロジックをわかりやすく整理する基本のアプローチ
    - **データとロジックを一体にして業務ロジックを整理する**
        - 業務ロジックを重複させないためには...
            - メソッドをロジックの置き場所にする
            - 業務ロジックをデータを持つクラスに移動する
            - 使う側のクラスに業務ロジックを書き始めたら設計を見直す
        - メソッドを短く書くとロジックの移動がやりやすくなる
            - メソッドは必ずインスタンス変数を使う
            - クラスが肥大化したら小さく分ける
            - パッケージを使ってクラスを整理する
    - **三層の関心事と業務ロジックの分離を徹底する**
        - 業務ロジックを小さなオブジェクトに分けて記述する
        - 業務ロジックの全体を俯瞰して整理する
        - 三層＋ドメインモデルで関心事をわかりやすく分離する

## 第4章　ドメインモデルの考え方で設計する
- ドメインモデルの考え方を理解する。ドメインモデルで設計すると何がよいのか
- ドメインモデルの設計は難しいのか
    - 利用者の関心事とプログラミング単位を一致させる
    - 分析クラスと設計クラスを一致させる
    - 業務に使っている用語をクラス名にする
- データモデルではなくオブジェクトモデル
    - ドメインモデルとデータモデルは何が違うのか
    - なぜドメインモデルだと複雑な業務ロジックを整理しやすいのか
        - データモデル中心では手続き型の設計になる
        - オブジェクト指向のドメインモデルへ
- ドメインモデルをどうやって作っていくか
    - 部分を作りながら全体を組み立てていく
    - 全体と部分を行ったり来たりしながら作っていく
    - 重要な部分から作っていく
    - 独立した部品を組み合わせて機能を実現する
- ドメインオブジェクトを機能の一部として設計しない
- ドメインオブジェクトの見つけ方
    - 重要な関心事や関係性に注目する
    - 業務の関心事を分類してみる
    - コトに注目すると全体の関係を整理しやすい
    - コトは業務ルールの宝庫
- 何でも約束してよいわけではない
- 期待されるコト，期待されていないコト
- 業務ルールの記述　～手続き型とオブジェクト指向の違い
- 業務の関心事の基本パターンを覚えておく
    - ドメインモデルで開発してもトランザクションスクリプトになりがち
    - 業務ルールを記述するドメインオブジェクトの基本パターン
        - **ヒト・モノ・コト**
    - ドメインオブジェクトの設計を段階的に改善する
    - 組み合わせて確認しながら改良する
    - 業務の言葉をコードと一致させると変更が楽になる
    - 業務を学びながらドメインモデルを成長させていく
- 業務の理解がドメインモデルを洗練させる
    - 業務知識を取捨選択し，重要な関心事に注力して学ぶ
    - 業務知識の暗黙知を引き出す
    - 言葉をキャッチする
    - 重要な言葉を見極めながらそれをドメインモデルに反映していく
    - 形式的な資料はかえって危険
    - 言葉のあいまいさを具体的にする工夫
    - 基本語彙を増やす努力
    - 繰り返しながらしだいに知識を広げていく
    - 改善を続けながらドメインモデルを成長させる

## 第5章　アプリケーション機能を組み立てる
- ドメインオブジェクトを使って機能を実現する
    - アプリケーション層のクラスの役割
    - 三層＋ドメインモデルの構造をわかりやすく実装する
    - サービスクラスの設計はごちゃごちゃしやすい
- サービスクラスを作りながらドメインモデルを改善する
    - 初期のドメインモデルは力不足
    - ドメインモデルを育てる
- 画面の多様な要求を小さく分けて整理する
    - プレゼンテーション層に影響される複雑さ
    - 小さく分ける
        - 登録系・参照系
    - 小さく分けたサービスを組み立てる
    - 利用する側と提供する側の合意を明確にする
    - シナリオクラスの効果
- データベースの都合から分離する
    - データベースの入出力に引っ張られる問題
    - データベース操作ではなく業務の関心事で考える
    - 実際のデータベース操作とリポジトリを組み合わせる
    - サービスクラスの記述をデータベース操作の詳細から解放する
    - [Amazon.co.jp - エンタープライズ アプリケーションアーキテクチャパターン (Object Oriented SELECTION) | マーチン・ファウラー, 長瀬 嘉秀, 株式会社 テクノロジックアート |本 | 通販](https://www.amazon.co.jp/dp/4798105538)

## 第6章　データベースの設計とドメインオブジェクト
- テーブル設計が悪いとプログラムの変更が大変になる
    - データの整理に失敗しているデータベース - **成約のないデータベースがプログラムを複雑にする**
        - 用途がわかりにくいカラム
        - いろいろな用途に使う巨大なテーブル
        - テーブルの関係がわかりにくい
    - データベース設計をすっきりさせる
        - 基本的な工夫を丁寧に実践する
            - **NOT NULL制約**が導くテーブル設計
            - **一意性制約**でデータの重複を防ぐ
            - **外部キー制約**でテーブル間の関係を明確にする
    - コトに注目するデータベース設計
        - 業務アプリケーションの中核の関心事は「コト」の管理
        - ヒトやモノとの関係を正確に記録するための3つの工夫
            - 記録のタイミングが異なるデータはテーブルを分ける
            - 記録の変更を禁止する
            - カラムの追加はテーブルを追加する
    - 参照をわかりやすくする工夫
        - コトの記録に注力したテーブル設計の問題
        - 状態の参照
            - UPDATE文は使わない
            - 残高更新は同時でなくてもよい
            - 残高更新は1ヵ所でなくてもよい
            - 派生的な情報を転記して作成する
            - コトの記録から状態を動的に導出する
    - オブジェクトの設計とテーブルの設計
        - オブジェクトとテーブルは似てくる
        - 違うものとして明示的にマッピングする
        - オブジェクトはオブジェクトらしく，テーブルはテーブルらしく
        - 業務ロジックはオブジェクトで，事実の記録はテーブルで

## 第7章　画面とドメインオブジェクトの設計を連動させる
- 画面アプリケーションの開発の難しさ
    - 画面にはさまざまな利用者の関心事が詰め込まれる
    - 画面に引きずられた設計はソフトウェアの変更を大変にする
    - 関心事を分けて整理する
- 画面の関心事を小さく分けて独立させる
    - 複雑な画面は異なる関心事が混ざっている
    - 小さな単位に分けて考える
    - 画面も分けてしまう
    - タスクベースのインターフェースが増えている2つの理由
    - タスクベースに分ける設計が今後の主流
- 画面とドメインオブジェクトを連動させる
    - 画面もドメインオブジェクトも利用者の関心事のかたまり
    - ドメインオブジェクトと画面の食い違いは設計改善の手がかり
    - ドメインオブジェクトに書くべきロジック
    - HTMLのclass属性をドメインオブジェクトから出力する
- 画面（視覚表現）とソフトウェア（論理構造）を関係づける
    - 項目の並び順とドメインオブジェクトのフィールドの並び順
    - 画面項目のグルーピング
    - 画面のデザインとソフトウェアの設計を連動させながら洗練させていく
    - 画面以外の利用者向けの情報もソフトウェアと整合させる
- [ノンデザイナーズ・デザインブック [第4版] | Robin Williams, 米谷 テツヤ, 小原 司, 吉川 典秀, 米谷 テツヤ, 小原 司 |本 | 通販 - Amazon.co.jp](https://www.amazon.co.jp/dp/4839955557)

## 第8章　アプリケーション間の連携
- アプリケーションとアプリケーションをつなぐ
    - ほかのアプリケーションとの連携がアプリケーションの価値を高める
    - アプリケーションを連携する4つのやり方
        - ファイル転送
        - データベース共有
        - Web API
        - メッセージング
- Web APIのしくみを理解する
    - HTTP通信を使ったアプリケーション間の連携の4つの約束事
        - 要求の対象を指定する（URI）
        - 要求の種類を指定する（HTTPメソッド）
        - エラー時の約束事
            - 処理の結果を伝える（ステータスコード）。
            - 応答内容の表現形式（JSONやXML）
- 良いWeb APIとは何か
    - 使いにくいWeb API
        - "One Size Fit All"
        - アプリケーションを組み立てるための部品を提供する
- 発展性に富んだAPI開発のやり方
    - 単純なことをかんたんにできるAPIの提供から始める
    - 動かしながら設計を発展させていく
        - RestController
        - Jackson
        - Swagger UI
    - APIを利用する側とAPIを提供する側の共同作業の環境を整える
    - 中核となるAPIのセットを設計する
    - Web APIのバージョン管理
    - APIを複合したサービスの提供
- ドメインオブジェクトとWeb API
    - データ形式とドメインオブジェクトを変換する際に起こる不一致
    - 導出結果か生データか
    - 複雑な連携に取り組む
        - 共通部分と個別対応部分を明確にする
        - APIを進化させる
    - 小さなアプリケーションに分けて組み合わせる
    - 複雑なデータの交換
    - 非同期メッセージングを使ったアプリケーション間連携
        - [O'Reilly Japan - Web API: The Good Parts](https://www.oreilly.co.jp/books/9784873116860/)
        - [Amazon.co.jp - マイクロサービスアーキテクチャ | Sam Newman, 佐藤 直生, 木下 哲也 |本 | 通販](https://www.amazon.co.jp/%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3-Sam-Newman/dp/4873117607)
        - [Enterprise Integration Patterns - Messaging Patterns Overview](https://www.enterpriseintegrationpatterns.com/patterns/messaging/)


## 第9章　オブジェクト指向の開発プロセス
- 開発の進め方はオブジェクト指向で変わったのか
- 開発の基本はV字モデル
- 短期間で開発し修正と拡張を繰り返すことが重要になった
- オブジェクト指向の開発はうまくいっているのか
- どちらのやり方でも変更がやっかいなソフトウェアが生まれやすい
- ドメインモデルを中心にしたソフトウェア開発の進め方
- 業務ロジックに焦点を当てて開発を進める
- ソースコードを第一級のドキュメントとして活用する
- 多くのドキュメントは不要になる
- 重要になる活動
- 更新すべきドキュメント
- 全体を俯瞰するドキュメントを作成して共有する
- 技術方式のドキュメントもソースコードで表現する
- 非機能要件はテストコードで表現する
- 分析と設計が一体になった開発のやり方をマネジメントする
- 見積もりと契約
- 進捗の判断
- 品質保証
- 要員と体制

## 第10章　オブジェクト指向設計の学び方と教え方
- オブジェクト指向を学ぶハードル
- オブジェクト指向の説明は意味が不明
- なぜオブジェクト指向で設計すると良いのかがわからない
- オブジェクト指向をどうやって学ぶか
- 既存のコードを改善しながらオブジェクト指向設計を学ぶ
- 実際のコードで設計の違いを知る
- 重複したコード
- 長いメソッド
- 巨大なクラス
- リファクタリングは部分的に少しずつ
- 組み立てやすい部品に改善する
- 設計は少しずつ改良を続ける
- オブジェクト指向らしい設計を体で覚える
- 古い習慣から抜け出すためのちょっと過激なコーディング規則
- オブジェクト指向の考え方を理解する
- 『実装パターン』
- 『オブジェクト指向入門』
- 『ドメイン駆動設計』
- [オブジェクト指向に近づく9つのルール (ThoughtWorks アンソロジーより) - Qiita](https://qiita.com/kiiimiis/items/dab7ebbcab640b4f2aa0)
- [Developers Summit 2009 - 【12-A-6】オブジェクト指向エクササイズのススメ](https://codezine.jp/devsumi/2009/report/07)

## 参考

[現場で役立つシステム設計の原則 - 読書感想文](https://zenn.dev/worbridg/articles/cfbee8cafc6537)

以上です～