エンジニアリングとお金の話

都内で働くエンジニアの日記です。

システム設計の原則3

【SPONSORED LINK】

システム設計の原則の感想3

 型を使ってコードをわかりやすく安全にする

intやstringなどの基本データ型だけで書いたプログラムは思わぬバグを生む可能性がある。

悪い例

int amount(int price,int unit,int charge) {

  //すべて基本データ型だと例えばunitとchargeが入れ替わっても分からない
  return price * unit + charge

}

良い例

int amount(Price price,Unit unit,Charge charge) {

  //独自側を使用することで不正な値が入ることをガード出来る
  return price * unit + charge

}

コレクション型を扱うロジックを専用クラスに閉じ込める

コレクションを操作するコードがあちこちに散らばうと可読性が悪いコードになる。解決策としてコレクション型の変数を1つだけ持った専用クラスを独自に宣言する。

class Customers {
  List<Customer> customers;

  void add(Customer customer) {・・・}
  int count() {・・・}

このようにコレクション型のデータとロジックを特別扱いして、コレクションを1つだけ持つ専用クラスを作るやり方をコレクションオブジェクトあるいはファーストクラスコレクションと呼ぶ。コレクションを操作するロジックをコレクションオブジェクトに閉じ込めると、コレクションオブジェクトを使う側のコードが単純になる。

コレクションオブジェクトを安定させる

コレクション操作をコレクションオブジェクト外では出来ないようにすることによりコレクションオブジェクトを安定させることが出来る。コレクションの操作を安定させる方法は3つある。

  • コレクション操作のロジックをコレクションオブジェクトに移動する
  • コレクション操作の結果も同じ型のコレクションオブジェクトととして返す
  • コレクションを不変にして外部に返す。

良い例(コレクション操作の結果を同じ型のコレクションオブジェクトを作って返す)

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

  }
}

良い例(コレクションへの参照は変更不可にして渡す)

class Customers {
  List<Customer> customers;
  ・・・
  List<Customer> asList(){
    return Collections.unmodifiableList(customers)
  }
}

操作対象のデータを持つクラスにロジックを集めることがオブジェクト指向設計の基本。データを持つクラスにロジックを集めると、使う側のクラスと使われる側のクラスのどちらのコードもわかりやすくなる。