モジュール指向とオブジェクト指向と

tag: 

ちょっとモジュール指向について書いてみます。

オブジェクト指向の書籍などで、よく「オブジェクト指向を使えば再利用性が高まる」といったことが書かれていますが、意外となぜ? というのが分かりにくい気がします。そのあたりを軽く説明してみます。軽くないですけど…。

実はオブジェクト指向というのは手法です。目的ではありません。そこに注意です。

本来なら、手法を模倣するだけで目的を果たせるというのが理想です。お菓子作りで使うクッキーの型抜きがいい例だと思います。まるい均一な大きさのクッキーを作りたければ、まるい型を使えばいいわけです。(生地とか焼きむらの話はこの際無視して!) この場合、「まるい均一な大きさのクッキーを作る」が目的で「まるい型を使って抜く」は手法です。この手法は誰でも同じ目的が果たせます。

それに対して、手法を模倣するだけでは目的を果たせないものも多いです。例えば自動車を使えば (手法) 遠くまで行く (目的) ことができますが、そのために覚えなければいけないこと (手法の学習) はたくさんあります。目的が VIP を安全にかつ快適に目的地まで運ぶことに変わったら、更なる手法の学習を要求されます。

前者と後者の違いは「手法の学習」にコストがかかるかかからないかの違いに見えるのですが、よくよく見ると「手法の模倣」で済むか「手法の学習」をしなければならないかという違いになります。

「設計」で必要な手法のほとんどは後者だと考えています。もし、前者だとしたら世の中の SE は不要になっちゃいますが、実際はそうではありません。(逆に言うと、SE という職種に価値をつけたければ後者である部分の作業をしなければならない。これはどんな職種でも同様です。)

以上を踏まえると「オブジェクト指向を使えば再利用性が高まる」は正しくもあり、間違ってもいるということになります。オブジェクト指向を使うのが「手法の模倣」だとするなら、間違いです。オブジェクト指向言語を使ってみる程度の模倣だと話になりません。対して、「手法の学習」と考えると、「きちんと使えば」という枕詞がつくので正しいわけです。

オブジェクト指向を使っても再利用性が高まらなかった、コストだけが上がった! オブジェクト指向はだめだ! みたいな話は、オブジェクト指向を前者の「手法の模倣」だと考えたから起きることです。

さて、前置きが長くなりましたけど、本題に入ります。

「モジュール指向」についてなんですが、これは製品が複雑化していく上で必ずより高度なものが必要になってきます。これは単純に人間の脳みその限界からくる制限と考えています。個人差はありますが、いっぺんに考えられる限界というのがあります。

モジュール指向で要求されるのは部品の交換です。部品の交換でわかりやすい例で言うと、自動車のタイヤです。買ったときと違うメーカー・銘柄が異なるタイヤでもつきます。これは実はとてもすごいことです。これを成しえるために、タイヤ交換ができるように自動車は設計してあります。タイヤは消耗品だから交換できて当たり前なのですが、消耗品は交換が必ず必要なのでモジュール設計の勉強にはもってこいです。

何が言いたいかというと、「交換可能な設計にして」初めて「交換が可能」と言うことです。そして、「交換可能な設計にする」ための試行錯誤の結果として「オブジェクト指向」が生まれた (もしくは育った) 一面があるということです。

交換可能にしやすいので、「オブジェクト指向」は再利用性が高いです。再利用性が高いものが欲しければ、オブジェクト指向をうまく使うことでコストを抑えられます。(もちろん、オブジェクト指向を使わずに再利用性を高めることもできますが、コストが上がります)

ということを考えながらオブジェクト指向とはなんぞや? と考えるといろいろと見えてくると思います。

私はこのあたりに気がつくまでに 10 年以上かかりました。さすがに自分でも気がつくのが遅すぎたと思います。

余談です。

モジュール指向をするにあたって、最大の敵はオブジェクト指向の学習ではなく、馬鹿になりきれないことにあると考えています。

モジュール指向でない考えで作る場合、メソッドを実装するとき、それを呼び出す側に無意識に制約を与えていることが多いです。例えば、呼び出し側のメソッドが null をメソッドに渡すことはありえないから、null が渡されたら正常に動作しないメソッドを書いてしまうとかがこれにあたります。このメソッドは呼び出される側のメソッドからしか呼び出されないという前提の設計になっています。

こうなっていると、書いたメソッドをモジュール化して物理的に切り離すことはできますが、実際には制約が強く、大変使いづらいものになります。使いづらいので、呼び出す側のコードが肥大化したり、モジュール化したコードを修正してしまってバリエーションが増えて管理コストが上がったり…。

なので、モジュールの境界面を超えたそれ以上のことは絶対に考えてはいけないのです。そのモジュールのことは知っているが、ほかのモジュールのことは全く知らない馬鹿にならなければいけないのです。モジュール指向で交換可能だということは、使う側が誰かがわからないわけで、馬鹿になるのは当たり前なんですが、慣れというものは恐ろしいもので、ついつい関連して考えてしまいます。

そんなわけで、長くなりましたけど、「モジュール指向」は難しいんです。でも、「モジュール指向」を使わないで物が作れるほど、最近のソフトウェアは小さくありません。がんばって覚えるしかないんです。

コメントを追加

Filtered HTML

  • ウェブページアドレスとメールアドレスは、自動的にハイパーリンクに変換されます。
  • 使用できるHTMLタグ: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote> <img>
  • 次のタグを使用してソースコード構文をハイライトすることができます。: <code>, <blockcode>, <c>, <cpp>, <drupal5>, <drupal6>, <java>, <javascript>, <php>, <python>, <ruby> The supported tag styles are: <foo>, [foo].
  • 行と段落は自動的に折り返されます。

Plain text

  • HTMLタグは利用できません。
  • ウェブページアドレスとメールアドレスは、自動的にハイパーリンクに変換されます。
  • 行と段落は自動的に折り返されます。
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
イメージ CAPTCHA
Enter the characters shown in the image.