デメテルの法則

「直接の友達とだけ話すこと」というプログラミングのお約束です。

社員、部署、会社というオブジェクトがあったとします。

class Employee {
  String id;
  String name;
  Depertment dept;
}

class Depertment {
  String id;
  String name;
  Company company;
}

class Company {
  String id;
  String name;
}

社員の会社名を取り出すときに、社員から”直接の友達”じゃない会社にアクセスしてはダメという話です。 こういうのはダメです。

employee.dept.name

じゃ、Employee に getter を追加したらいいのか?

class Employee {
  String id;
  String name;
  Depertment dept;

  String getCompanyName() {
    return dept.name;
  }
}

これも正解ではない。というか、何も解決してない。 問題は、社員、部署、会社という3つのオブジェクトに関与してしまっていることです。 依存が大きくて、ほかのオブジェクトの影響を受けやすいです。

これのテストコードを書くことを想像してください。テストデータとして、3つのオブジェクトのテストデータを作らないといけないです。 ユニットテストのコードの大部分は、テストデータとモックなので、依存するオブジェクトが多いと、ユニットテストのコード量も肥大していきます。

ではどうするのか? 解決策は、専用のクラスを作って、責任範囲をそのクラスに限定することです。 "社員の会社名を出力する" とき、このオブジェクトのことだけ知ってればよくて、3つのオブジェクトを知る必要はない。それらのオブジェクトの事情に影響をうけることもない。

class CompanyEmployeeName {
  String employeeId;
  String employeeName;
  String companyName;
}

また、クラスは、多重継承よりも、コンポジットの方がよいのだけど、さらに、プロパティは、できるだけフラットに設計するのが、よいとされてます。 専用クラスを作って、データを移し替えることで、フラットにすることを検討しましょう。

これだけで、テスタビリティは、ものすごく改善します。テストデータは、1つだけだから、テストコードもスッキリします。 とりあえず、なんらかの処理を書くときは、ほかの処理で使っているオブジェクトを使いまわすんじゃなくて、 いったん、必要な項目だけの専用の入れ物を作って、移し替えて、結合の依存をできるだけ薄い状態にして、処理を書くようにする。 これを徹底することで、ユニットテストの作業負荷を小さくしていきましょう。

デメテルの法則、覚えておきましょう。

最近の記事タグ

\(^▽^*) 私たちと一緒に働いてみませんか? (*^▽^)/

少しでも興味をお持ちいただけたら、お気軽に、お問い合わせください。

採用応募受付へ

(採用応募じゃなく、ただ、会ってみたいという方も、大歓迎です。)