2007-07-07

抽象化

 私たちの脳は、ごく自然に、意識することなく「抽象化」ということをやってくれてます。
これ、日常生活では全く無意識にやってることなんですが、ソフトウェア開発の世界では、みんながわざわざがんばって習得している、非常に重要な概念の一つです。

で、ソフトウェア開発者でない方も、私たちが実はこんなことを無意識にやっていたんだということを知ることは、いいことです。
「無意識」というのは、あまり頭がよくないようで、複雑なことになると適用してくれなくなったりします。
なので、複雑な場面になったら、無意識くんがやってくれてたことを、私たちが意識的に適用しなければならなくなるわけです。
そうすることで、無意識くんの力だったものを、いろいろな高度な問題に利用することができるようになります。

コンテンツ

  1. なんだって抽象
  2. ふたたび旅行計画
  3. カプセル化
  4. ソフトウェア開発者の方のための追記
  5. オススメ


私たちは、物事を常に抽象的にみています。
1本のネジとか、今手の中にあるシャープペンシルとか、そういう一見具体的なものに見えるものでも、私たちは実は抽象的に捉えているのです。

なんだって抽象

たとえばシャープペンシル。
シャープペンシルを見たとき、あなたはそれがどこで、どんな材料から、どうやって作られたのか、気にしますか?
今、中に芯は何本入っているか、いちいち確認しませんよね。
シャープペンシルを持ったら、とりあえずカチカチと芯を出してみて、出たらOK。
実際に芯が出なくなるまでは、それ以上シャープペンシルのことは考えずに書き物をはじめますよね。
iPodで音楽を聴くときは?
ヘッドフォンをつけて、クリックホイールを押したら、はいOK。
たまには、特定の曲が聴きたくなって、探すこともあるでしょう。
それでもやっぱり、探し当てたら再生を開始して、はいOK。
ですよね。
iPodの中でハードディスクがぎゅんぎゅん回ってることとか、そこにどんな密度でデータが書き込まれてるかとか、だいたい今iPodの中に何曲入れてたっけ?なんてことすら、あまり考えませんよね。
そんなこと考えなくたって、シャープペンシルはちゃんと線を描かせてくれますし、iPodはお気に入りの曲をえんえんと再生し続けてくれます。
今持っているシャープペンシルやiPodがどういう状態なのか、それほど詳しく知らなくてもいいのです。
一般的にシャープペンシルってどんなものなのか、iPodってどんなものなのかだけ知ってれば十分です。
つまり、私たちはほんとうに具体的な知識でなく、抽象的な知識によっていろんなものとやりとりしているのです。
今説明した、抽象的なシャープペンシルやiPodのようなもののことを、抽象(概念)と呼びます。こういうふうに、抽象的なやりかたで物事をとらえるのが、「抽象化」です。

ふたたび旅行計画

開放・閉鎖原則のお話の中で、「旅行計画」を例にとりましたね。
もう一度、以下にその例を挙げてみます。
旅行の計画を立てるとします。
あなたなら、どんな計画を立てるでしょう?
計画案1

出発(9:00)→2時間→観光地A 昼食もとる(~14:00)→1時間→観光地B(~18:00)→移動30分→ホテル到着(18:30)
計画案2
出発(9:00)→2時間→観光地A到着(11:00)→A'を観る(11:00~11:30)→A''で遊ぶ(11:30~12:00)→昼食(12:00~13:00)→A'''を散策(13:00~14:00)→1時間→観光地B到着(15:00)→…以下略
前回は、計画案2は開放・閉鎖原則に反しているので失敗しやすいと言いました。
今回は、計画案2は抽象化されていないので失敗しやすいという説明をしたいと思います。
単純なハナシ、あなたが計画を立てる人でなく、参加する人だとしたら、計画案2を渡されたとき、この日の行動を簡単に把握できますか?
マジックナンバーという言葉があります。
プロ野球のマジックナンバーではありません。
プログラムで使用すべきでないマジックナンバーでもありません。
一般的には、人間は一度に7つ±2つ程度(もう少し多いという説や、少ないという説もありますが)のことしか把握できないというハナシです。
こまごましたことをいっぺんに並べ立てても、人は把握できないのです。
計画が把握できないというのに、その計画がうまくいくわけはありませんね。

カプセル化

ところで、この抽象化を支える重要なテクニックがあります。
カプセル化です。
属性や振る舞いを、カプセルのようにオブジェクトの中に隠してしまうことです。
この例の場合、たとえば観光地Aの中で何をするのかというような細かい行動が、観光地Aというオブジェクトの中に隠された結果が、計画案1ですね。
計画案1では、カプセル化した結果把握しやすく、また開放・閉鎖原則のところでお話したように、変更に強くなっています。
さらに言うと、この観光地AとかBは、抽象概念なわけです。
カプセル化に漏れがあると、この抽象化が壊れます。
シャープペンシルの中の芯がボキボキに折れてたりすると、常に芯が途切れないかどうか心配しながら書き物をすることになりますよね。
シャープペンシルの中のことに気をとられて、書き物に集中できません。
本来なら気にする必要もない(シャープペンシルの)内部のことを気にしなければならない。
書き物という本来あなたがやりたい作業に、シャープペンシルの内部事情が影響を与えているわけです。
この状態を、カプセル化が漏れている、あるいは抽象に漏れがあると言います。

ソフトウェア開発者の方のための追記

ソフトウェア開発者の方には、この抽象化/カプセル化を設計や実装において守るにあたって、基本的な姿勢があります。
あなたが使用しているプログラミング言語とその文化が許すなら、まずは全てのメンバのスコープをプライベートから開始してください。
その後、必要に応じて、必要最小限にスコープを広げていってください。
ネットワークセキュリティのための、ポートの開放手順と同じ考え方です。
あるメンバのスコープを広げる際には、そのメンバがよりオープンにアクセスされることについて、そのクラスが使用される限りの期間ずっと責任が持てるかどうか、考えてみてください。
抽象化・カプセル化というのは、単にメンバを隠蔽したり、まとめ上げたりするというだけでも大きな意味がありますが、それだけでなく、より重要な意義もあるのです。
既に書きましたが、人間の把握力には一定の限界があります。
それもごく小さな限界です。
7±2くらいのオブジェクトしか把握できないのですよ!
システムをある角度(サブシステムやレイヤーなど)から見たとき、それ以上のオブジェクトが出現することは、できるだけ避けるべきです。
一般に、メソッドのパラメータの数が規約によって制限されるのにも、そういうわけがあるのです。
同じ理由で、パブリックメンバが異常に多いクラスは把握しづらくなります。
把握しづらければ、メンテナンスが容易でなくなりますので、修正時のバグ混入率が上昇します。
クライアントクラスは「面倒くさい」という理由で、そのクラスを使用しなくなり、かわりに同じ機能を独自実装しはじめます。
もちろん、バグ混入率がまた上昇しますね。
極端な話、そうなったらそのクラスがお払い箱になるか、そのアプリケーションがお払い箱になるかということにもなりますよね。
抽象化は徹底的に行い、崩すときには細心の注意を払ってください。

オススメ

ソフトウェア開発者の方向けには、カプセル化についてもオブジェクト脳のつくり方で解説されています。
ほんとにこればっかりですが、ほんとにわかりやすくていい本なんです。

0 件のコメント:

コメントを投稿

Related Posts Plugin for WordPress, Blogger...