岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

デメテルの法則を守るためのずるい方法

思いついた。

デメテルの法則(Law of Demeter、デメテルの掟とも)とは、あるオブジェクトのメソッドの中で:

  • オブジェクト自身
  • メソッドの引数
  • メソッドの中で生成したオブジェクト
  • インスタンス変数

以外のオブジェクトのメソッドを呼び出すと大変なことになるぞ、どうなっても知らねえからな、という脅し文句です(間違いがあればご指摘ください)。

デメテルの法則を破っている分かりやすい例はこんな感じ。

class Foo
  def bar(a)
    a.b.c.d.e
  end
end

b、c、d は、法則の許可しているオブジェクトのどれにも当てはまりません。

デメテルの法則のエッセンスを私なりに抽出すると、必要のないオブジェクトは受け取るな、となります。

上記の例でいえば、d だけが必要なので:

class Foo
  def bar(d)
    d.e
  end
end

とするのが常道なんでしょう。

でも、a を渡したほうが使い勝手がいいケースがありますよね。そんな場合は、こうしたらいいんじゃないの?

class Foo
  def bar(a)
    b = B.new(a.b)
    c = C.new(b.c)
    d = D.new(c.d)
    d.e
  end
end

b、c、d は「メソッドの中で生成したオブジェクト」だから、問題なし。ずるいけど、意外と使える予感がします。あらためて、実際の使用例を書くかもしれません。

そこまでして守る必要ないだろ、とか言わないの〜。