「現場で役立つシステム設計の原則」まとめ ~ 1章 ~

システム設計の原則知ってますか?

この記事は「現場で役立つシステム設計の原則」を読んで勉強になったことや仕事で役に立ちそうなことをまとめた記事です。 あくまでまとめで、説明できなさそうなところは省いているのできちんと理解したい人は本を買って読んでください!

この本を書いた方

著者は増田亨さんという方で、ドメイン駆動設計も用いたアプリケーション設計・開発をやられている方です。 スライドシェアにもドメイン駆動設計関連のスライドがたくさんありました。

www.slideshare.net

第1章「小さくまとめてわかりやすくする」

ソフトウェアの変更が大変な理由
  • ソフトウェアの修正や変更で副作用が出たり、予期せぬ問題が出るのは設計(=ソースコード)に問題があるから
  • 変更が大変なプログラムは3つの特徴がある
    • メソッドが長い(理解が大変)
    • クラスが大きい(変更時の影響範囲の特定が難しくなる)
    • 引数が多い(変更時の影響範囲の特定が難しくなる)
  • ちょっとの修正が重なることで全体が複雑になる。
プログラムの変更を楽にする書き方
  • わかりやすい名前を使う
    • 略語や一致しない名前の使用を避ける
// Bad
int a; 
int qty;
return qty * up;
// Good
int quantity;
return quantity * unitPrice;
  • コードのまとまり(処理のまとまり)ごとに空白行を入れる
  • 目的ごとに変数(= 説明用の変数)を用意する(破壊的代入*1を避ける)
// Bad
int price = quantity * unitPrice; // 数量x単価

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

price = price * taxRate(); // 税込み金額
// Good
int basePrice = quantity * unitPrice; // 数量x単価

int shippingCost = 0; // 送料
if (basePrice < 3000)
  shippingCost = 500;

int ItemPrice = ... // 税込み金額
  • メソッドとして独立させる(メリットは以下)
    • 変更の影響をメソッド内に閉じ込めやすくなる
    • 詳細をメソッドに記載するので呼び出し元のコードが綺麗になる
    • メソッドの名前からコードの意図を理解しやすくなる
int basePrice = quantity * unitPrice; // 数量x単価

int shippingCost = shippingConst(basePrice) // 送料計算を別のメソッドに切り出す

int shippingCost(int basePrice) {
...
}
  • 異なるクラスの重複したコードをなくす
  • 業務の関心ごとに対応したクラス(ドメインオブジェクト)を作る
    • 例えば、送料に関することは送料クラスにまとめることで変更の対象や影響範囲をそのオブジェクト内に限定できる
小さなクラスでわかりやすく安全にする
  • 業務で扱う値は基本データ型で扱う値と一致しないことがある
    • 例えば、業務では単価は1億円まででも、intを使うとマイナス21億円からプラス21億円まで扱うことができてしまう
  • 業務的に正しい値を扱えるように独自のクラス(値オブジェクト)を作成する*2ことで異常な値を防ぐことができる
    • 例えば、数量に特化したQuantityクラスや電話番号に特化したTelephoneクラスを作成することで異常な値を防ぐと同時にコードの意図も明確にすることができる
  • 値オブジェクトを不変にする(別の値が必要になったら別オブジェクトを作成するようにする)
    • 変数の上書きは予期せぬ副作用を呼ぶ可能性があるため
  • 型を使ってコードをわかりやすく安全にする
// Bad
int amount(int unitPrice , int quantity) {
... // unitPriceとquantityの渡す順番を間違えてもコンパイルエラーにならない
}

// Good
Money amount(Money unitPrice, Quantity quantity) {
... // unitPriceとquantityの渡す順番を間違えるとコンパイルエラーになる
}
1章まとめ
  • コード整理の基本は名前と段落にあり
  • 短いメソッド、小さなクラスでコードを整理しよう
  • 値オブジェクトを使ってわかりやすく安全にしよう
  • クラス名やメソッド名を業務の用語と一致させるとプログラムがわかりやすくなり、変更もやりやすくなる

*1:破壊的代入とは1つの変数を使いまわし代入を繰り返す書き方のこと

*2:値を扱うための専用のクラスを作るやり方を値オブジェクトと言います