トップ «前の日記(2008-09-09) 最新 次の日記(2008-09-11)» 編集

日々の破片

著作一覧

2008-09-10

_ 機能と責務

構造化するってのは、機能で分けることだという言い回しを見かけることがある。

多分、こういうのだろう。

# 機能=function
def open(path)
  File.new(path, "r")
end
def read(f)
  f.read
end
def close(f)
  f.close
end
f = open('foobar')
puts(f.read)
f.close
で、それに対して、そもそもOOPではどうしたといいだす場合には、
#機能 = use case
class FooBar
  def initialize(path)
    @f = File.open(path, "r")
  end
  def show(f)
    f.puts(@f.read)
  end
  def close
    @f.close
  end
end
foobar = FooBar.new('foobar')
foobar.show($stdout)
foobar.close

とかいうように、エンティティとして扱えるように、最初のコードではバラバラだった「機能」をカプセル化する。

しかし、カプセル化されているとは言っても、下の3行が3行であることに何の変りもない。メリットはなんだ?

むしろ、この場合であれば

# 機能=feature
class FooBar
  def self.show(path, f)
    File.open(path, "r") do |file|
      f.puts(file.read)
    end
  end
end
Foobar.show('foobar', $stdout)

のほうが、よりカプセル化されているのではなかろうか?しかし、結果的に静的なメソッドになってしまった。

はて?

_ モジュール化

上のは、いんちきがあって、最初のと最後のは視点が異なる。

最初のは、プログラミングとしての構造化で、機能というのは細粒度となっている。与えられたパスからファイルを開くとか、与えられたファイルを閉じるとか。

最後のは、モジュールの導入だ。FooBarというクラスはまったくクラスの必要はなく(インスタンス化を考えてはいない)のだが、与えられたパスのコンテンツを表示するという、最初の例ではメインが実行していた処理そのものを行っている。この場合、FooBar.showの内部実装がOOPLによるものかたとえばCOBOLによるものかは、この粒度からはどうでも良いものだ。

「モジュールを黙殺しちゃってるんです」というのは、最初と2番目(例が無茶だが)とは別に3番目があることを言っているのだと思う。3番目はマルチインスタンスは無視しているが、2番目(あ、ちゃんとaskじゃなくてtellするように引数を使ってたので違う例になってしまった)と同様にtell, don't ask則にしたがっているというのは重要だ。というか、もし2番目でshowメソッドではなくreadメソッドを実装していたとしたら、それは最初のやつよりも手間がかかるぶんだけ、もっと悪い(この処理では同時に複数のFooBarのインスタンスが不要だと仮定している)。

というように、2.5mあたりに視点をおくと、固い3番目のFooBarの亜種をたくさん用意することこそが重要になるので、COBOLのほうがへたなJava(showメソッドではなくreadメソッドを実装するようなタイプ。ゲッタとかセッタとか)より、よほどモジュール化できるため、システムを組みやすいということなのではないか、というように推測してみる。

亜種が複数あるのに対して、ポリモーフィズムは不要なのかといえば、それは設定可能なフレームワークのレベルでサポートされることになる(粒度が粗いというのはそういうことだ)し、そのような外挿しの仕組みのほうが運用に自由度を与えられるからむしろ望ましい(場合がある)。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|

ジェズイットを見習え