オブジェクト指向のこころ(1)
オブジェクト指向以前のプログラミング
機能分解から始める既存の構造化プログラミングの問題に触れる部分からスタート。 アンチパターンとして
- 問題領域に存在する実体と出て来る動詞を書き出してしまう方法
- オブジェクトをメソッド一緒になったデータと考える事
機能分解をすると個々の機能自体やそれらを呼び出すための手順を把握したオーガナイザー的なものが必要になる。オーガナイザーが複数の機能を扱うということはそれだけ多くの責任を持っているということ。機能の変更の際は機能自体だけでなくその操作を行うオーガナイザーに関しても修正を必要とする。 機能分解分解をすると
- 凝縮度(Cohesion)が下がる
- ある機能を叶えるために必要なコード群がいろいろな場所にあること
- 明快度(Degree of Clarity?原文だとなんてなってるんだろ)が下がるとも言える
- 色々な場所を見る必要があり見通しが悪い
- 副作用(unwanted side effect)を引き起こしやすい
- 変更の際に全てを網羅できずバグを生む
オブジェクト指向やっていき
単一の責任だけを持つように責任の移譲をしたい
- 責任の移譲をするということはつまりは相手を信頼し機能を任せているということ
- 任せるというのは相手のやり方や手順(実装やアルゴリズム)に関して一切感知をしないという意味(とりあえず機能を叶えてくれればそれでよい)
- これによってオブジェクト間で「汚れのついた皿を集め洗剤とスポンジを用意してこすったり泡を流したあと乾かしてくれ」とかやんないといけなかったのを「"皿洗い"をしてくれ」という抽象的なやり取りに簡単化できる
- "どうするか"ではなく"なにをするか"
- 例えば「手順のみを知っているやつ」や「どうするかだけを知っているやつ」にするってこと?
考えるレイヤーによってオブジェクトの捉え方は変わる
- 概念 - 登場するオブジェクトを洗い出し何に責任をもつものなのか考える
- 仕様 - オブジェクト間のインターフェースを決定する
- 実装 - どうやって自分の責任を達成するか。責任の分離が出来ているので他のオブジェクトのことは考えなくてもいい(そうなっているはず)
カプセル化
変わり得る(と考えられる)部分(データだろうが振る舞いだろうが)を他のオブジェクトから隠蔽すること。他のオブジェクトからは特定の部分(公開インターフェース)にだけ依存させるようにする。 もしカプセル化が出来ていない場合は依存している部分が変更されてしまったときに修正箇所を増やすことになる。
ポリモーフィズム
異なる振る舞いを持つオブジェクト群に共通のインターフェースをもたせ同じように扱えるようにする。継承によってインターフェースの共通化を行い、そのインターフェースに紐づく挙動を個々のオブジェクトに任せる
おまけ
オブジェクトは自分が何の責任をもつクラスから作られたものなのかを知っている必要があるってのが明示的に書いてあったのが気になった。 オブジェクトが自分が誰なのか知ってるのは当たり前なのだけれどこういうのをはっきり書くのは理論屋さんとかが考えるときの公理みたいな扱いになってるからなのかな