<書評> 現場で役立つシステム設計の原則

published_at: 2023-03-05

概要

本書籍では、オブジェクト指向や設計パターンなどソフトウェア設計に関する基本的な概念が紹介されている。

章ごとに読んだ感想を述べていく。

CHAPTER1: 小さくまとめてわかりやすくする

ソフトウェアは常に変更され得るから、変更しやすいコードを書くには何を意識すべきかがまとめられている。

分かりやすさに主眼が置かれており、変数名を明確にしたり、値オブジェクトを使うことやイミュータブルなデータに関して言及されている。

「クラス名やメソッド名と業務の用語を一致させること」これはかなり大事。異音同義語があると認識のズレとか生まれやすいし、話していてツラミ感じる。

CHAPTER2: 場合分けのロジックを整理する

ソフトウェア変更容易性を妨げるのが複雑なロジックなので、簡単に書こうという内容や方法がまとめられている。

メソッドに切り出すとか、ifのネスト、ガード節による早期returnなど。

switch文などで分けるより、クラス化しロジックをカプセル化して呼び出すだけにすると見通しが良くなるなど。

使う側のクラスが使われる先のクラスに関する知識が少ないほど疎結合になって良い。

Railsで開発しているとどうしても密結合になりがちなので、改めて意識したいと思った。

CHAPTER3: 業務ロジックをわかりやすく整理する

1,2章が部品レベルの話だったが、この章ではアプリケーション全体の組み立てレベルでのロジックの分かりやすさについてまとめている。

ドメインオブジェクトをクラスとして管理していく際に下記のことに気をつける。

  • メソッドをロジックの置き場所にする
    • getter / setterメソッドだけになっていないか?(=ドメインモデル貧血症)
  • ロジックを、データを持つクラスに移動する
    • ロジックが点在していないか?共通化できないか?
  • 使う側のクラスにロジックを書き始めたら設計を見直す
  • メソッドを短くして、ロジックの移動をやりやすくする
  • メソッドでは必ずインスタンス変数を使う
    • Railsの文脈だとクラス内のカラム等
    • 受け取った引数だけ使っているのであればそのクラスに定義する意味がない
  • クラスが肥大化したら小さく分ける
  • パッケージを使ってクラスを管理する

上記を組み立てる段階で、プレゼンテーション層にドメインロジックが書かれていないか?

アプリケーション層との結合はどうか?等の責務を意識していく。

基本的にドメインオブジェクトにロジックをまとめることで凝集性を高める方が好ましい。

CHAPTER4: ドメインモデルの考え方で設計する

ドメインの関心事を適切にモデルに落とし込んで独立した単位として扱えるようにする重要性についてまとめられている。

ドメイン内のユビキタス言語を定めてクラス名に落とし込むことや、「コト」を中心に考えることで関心事を特定しやすくなるなど。

特に学びだったのがドメインオブジェクトの基本設計パターンと業務の関心事パターン

ドメインオブジェクトの基本設計パターン

  • 値オブジェクト
    • 数値、日付、文字列などをラップしてロジック整理する
  • コレクションオブジェクト
    • 配列やコレクションをラップしてロジック整理
  • 区分オブジェクト
    • 区分の定義と区分ごとのロジックを整理
  • 列挙型の集合操作
    • 状態遷移ルールなどを列挙型の集合として整理

この4種類で業務ロジックを整理していくと業務ロジックがドメインモデルに集約できる。

業務の関心事パターン

  • 口座パターン
    • 現在の値を表現し妥当性を管理
      • 数値の増減や現在の値を保持
      • 銀行の口座や在庫数量の管理など時系列が重要なパターン
  • 期日パターン
    • 約束の期日と判断を表現
      • 期日が適切に守れているかを管理
        • 期限切れの場合はどうするかなどの表現
  • 方針パターン
    • 様々なルールが複合する複雑な業務ロジックを表現
  • 状態パターン
    • 状態と、状態遷移できる/できないを表現
      • 決済ステータスなどで利用される
        • ある状態ではどうなるべきなのかを表現

上記4種類が主な関心事パターンとして挙げられるが、ドメイン理解をしていくことが適切に関心事を扱えるようになるポイント。

異音同義語に注意したい。あと、話を深掘り真の課題を抽出すること。

CHAPTER5: アプリケーション機能を組み立てる

サービスクラスに業務ロジックを書かないようにする。

防御的プログラミングの形式で多くのガード節があると、ドメインモデルにロジックを移すかクラスを用意するなりした方が良い。

あくまでサービスクラスは処理を呼び出すだけ。尋ねるな命じろ。

CHAPTER6: データベースの設計とドメインオブジェクト

データベース設計がうまくいくとアプリケーションロジックも書きやすくなる。

NOT NULL制約だったり、一意性制約、外部キー制約など。詳細はSQLアンチパターンなどの書籍に譲る。

というよりDB設計の細かい話より、ドメインの中でテーブル単位をどう切り分けるのかという話の方が重要。

「コトの記録」を徹底すると本書には書かれている。

実体があるものはモデリングしやすいが、実体の無いものこそ業務ロジックの中ではモデリングすることが大事。

texta.fmというラジオでも和田さんが同じことをおっしゃっていた。

CHAPTER7: 画面とドメインオブジェクトの設計を連動させる

汎用画面は複数の関心事が混ざっておりロジックを複雑にしてしまう。

何事も関心事の分離が肝とあるが、ビジネスサイドからは1つの画面で全部行いたいという要望もあるので落とし所は難しいなと思う。

逆に言うと、1つの画面で共通の関心事をまとめられていないという側面もあるのかもしれない。

複数の関心事が混ざっていることだけでなく、同じ関心事が複数画面に点在していないかも意識できると良さそう。

CHAPTER8: アプリケーション間の連携

APIの粒度を適切に保つことが再利用性や利用容易性を高める。

本書では大は小を兼ねるAPIはビジネスの発展を阻害するとあるが、まさにその通りだと思う。

ユースケース上では不要なパラメータや戻り値など、複雑にする要因があると連携がスムーズにいかない。

将来的な拡張性も難しくしてしまうと感じる。

関心事の不一致が起きていないかどうかはこういう場面でも意識したい。

CHAPTER9: オブジェクト指向の開発プロセス

オブジェクト指向らしく分析と設計を一体にすることで、変更が楽で安全なソフトウェア開発を進められる。

業務ロジックをドメインモデルに集約して整理することが肝。

分析工程と設計工程を分割せずに一貫して行うことや、コードが自己文書化すべき等の記載がある。

兎にも角にもドメインを深く理解してモデリングすることが大事。

CHAPTER10: オブジェクト指向設計の学び方と教え方

オブジェクト指向設計の考え方を習得するには、リファクタリングが手っ取り早い。

コードの重複や巨大なメソッド/クラス、引数が多すぎるメソッドなどをリファクタリングすることでなぜ使いやすくなるのかを肌で感じることが大事。

話は少し逸れるが、最近は脱オブジェクト指向が主流になりつつあるような気がするので別途ブログにまとめたい。

まとめ

再利用性が高くDRYなコードを書くのはもちろん、ドメインを適切にモデリングすることを意識したい。