4の顔を持つオブジェクト指向

# TL;DR
- 「オブジェクト指向」という言葉は複数の意味を持ち, それぞれ別のレイヤーで使われている.
- 「オブジェクト指向」についての言説を読む場合はそれがどの「オブジェクト指向」について
語っているかを判断してから内容を評価するべきである.

# 君はオブジェクト指向を知っているか?

オブジェクト指向を知ってるかだって？もちろん知っているに決まっているだろ！

(具体的にどういうものなのですか？)

そりゃあれだよ、犬とか猫とかそういう現実世界に存在する概念をそのままモデル化してプログラムで表現して実行させるってやつだよ

（うーん、言いたいことはわかる気はするんですが、実際どうやってプログラムに落とし込んでいくのかはちょっとわからないですよね）

そこでクラスってやつがでてくるんだよ.
必要なメソッドを持った犬とか猫とかそういったクラス単位でプログラムを組んで, あとはそいつらが協同して動いて
一つのソフトウェアとなるように組み立てていくんだよ.
そうそう、クラスを作るときはちゃんと単体テストしやすいようにしておかないとだめだよ.
なんたってオブジェクト指向だからね.

(ところで、カプセル化とか多態性とかそういう話もきいたことがある気がするんですが…)

ああそうだね、カプセル化や多態性も重要だね. 
なんたってオブジェクト指向だからね.

(なるほど…ところで現実世界の犬をモデル化したものとカプセル化、どっちがオブジェクト指向なんですか？)
どっちがオブジェクト指向かだって？
__もちろん全部オブジェクト指向なんだよ！！__


# 4つの顔
オブジェクト指向には様々な側面があると考えられるが, ここではそれらのうちの4つについて
説明したいと思う

## 第一の顔 オブジェクトは, 現実世界を抽象モデルとして表現したものである
オブジェクト指向設計では, 対象となる問題領域を実装すべきロジックあるいはそれを表現するデータ構造としてではなく
現実世界に存在し、仕事を行っている人物を意味するコンポーネントとして表現し, それぞれの仕事は
すべてを制御する単一のプロセスによって達成されるのではなく, 
それぞればらばらに動くコンポーネントの協同作業によって達成されると考える.
つまり
「経費精算ロジックは, 経費データを受け取り,その内容を経費テーブルに登録したのちに予算レコードを更新する」
と記述する代わりに
「経理担当者は, 社員から経費申請を受けた際にその内容を経費申請台帳に記録し, あらかじめ用意された予算から必要分を支払う」
などといったより実作業に近い形で記述する.
このことによって, ソフトウェアについての記述はエンジニアだけでなく対象領域のエキスパートであるクライアントにも
十分に理解可能なものになり, より祖語の少ない仕様を作ることができるようになる.

## 第二の顔 オブジェクトとは, 明確に定義されたインタフェイスを持つモジュールである
オブジェクト指向設計では, ソフトウェアはそれぞれ独立したモジュール群と, それらの間の相互作用を定義した
インタフェイスにとして記述される.
モジュールだけではなくインタフェイスも定義するのはなぜだろうか？
インタフェイスを用意しないでモジュール同士を直接接続してゆきソフトウェアを作成することは, 実際には可能である
その場合, モジュール間の相互作用部分の作成はまず出来上がったモジュール実物を持ち寄り, それぞれの挙動を調べ, 
その挙動に合うように互いに摺り寄せていき, 両方が完成後動作テストを行うという過程を経ることになる.
この方法には4つの問題点がある

- 両サイドのモジュールが完成しないと接続のための機構を作成できない
- モジュール間の相互作用は相手側モジュールの事情に直接影響受けつことになるため, 一度作成したら
  片方だけを変更といったようなことは行いにくい
- 依存先モジュールを別のものに交換したい場合は, 新モジュールが旧モジュールの仕様を完全にトレースするか, あるいは依存元モジュールを新モジュールに合わせて書き換える必要がある.
- テストに失敗した場合（あるいは実働時に不具合が発生した場合）, どちらのモジュールに問題があるのかを特定するのが難しい

ここにインタフェイスを導入し, 各モジュールはあくまでインタフェイスに依存するように変えることで
上記の問題点は以下のように改善される.

- それぞれのモジュールは相手側モジュールの開発状況に関係なく独自に開発を進めることができる
- モジュール間の相互作用についての要件はすべてインタフェイスで定義されているため, それぞれのモジュール内部の変更や改良も（インタフェイスの範囲内で）自由に行うことができる
- インタフェイスの要件を満たしたモジュールであれば柔軟に切り替えることができる
- それぞれのモジュールを独自にテストすることが可能になる

このようにオブジェクト指向設計では, ソフトウェアを「複数のモジュールを溶接して作った一つの塊」ではなく「複数のモジュールをレゴのように組み合わせて作った構築物」として作ることができるのである.

## 第三の顔 オブジェクトとは, 階層構造をもつ型である
多くのオブジェクト指向言語において, クラスは階層構造を持つことができる.
階層内の子にあたるクラスは, 自分自身のクラスであると同時に親のクラスとしても扱われる.
このことによって, 定義時は汎用的なクラスを使い, 動作時はその子に当たる特化クラスに差し替るといった
テクニックが可能になる.
また階層内で共通する処理をまとめることで重複した記述をなくすことができるといった利点も存在する.

## 第四の顔 オブジェクトとは, 抽象データ型である
拡張データ型とは, 一連の変数とそれらを操作する一連のロジックからなる__型__である.
旧来的な型は一つの値, もしくは2つ以上の値からなる構造体を意味していた.
そのため, あるロジックがライブラリ提供されていた場合でも, 呼び出し元はプログラムは
そのロジックと, ロジックが扱う変数の両方を別々に管理する必要があった.
このことが多くの悲劇を生みだした.
ロジックとそれに関連する変数を同時に管理する抽象データ型の発明は, 呼び出し元プログラムが管理すべき
変数（状態）を減らし, またロジックの扱う変数の安全性も高めた(自分が扱う変数が他のロジックによって変更されないことが保証されるため)

# まるで別人のようだ
ここまでオブジェクト指向の特性を4点あげて説明してきた.
ところでこれら4つに何らかの関連性はあるだろうか？
対象領域の分析ための方法論とプログラミング言語の一機能の間に何か関係があるのだろうか？
おそらく, まったくないだろう.
このようなまとまりのなさは, 各方面の研究成果を「オブジェクト指向」という流行り言葉に絡めて
語ってきたという歴史的経緯が原因なのではないかと考えている.

なんにせよ, 現代の雑多な意味を持つ「オブジェクト指向」について議論する際には, 
一歩引いてそれがどの「オブジェクト指向」なのかを考えてからでないと
意見はすれ違うばかりで有益な議論はできないのではないかと思われる.


# 参考文献
[オブジェクト指向入門 第2版 原則・コンセプト](https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E5%8E%9F%E5%89%87%E3%83%BB%E3%82%B3%E3%83%B3%E3%82%BB%E3%83%97%E3%83%88-Architect%E2%80%99Archive-%E3%82%AF%E3%83%A9%E3%82%B7%E3%83%83%E3%82%AF%E3%83%A2%E3%83%80%E3%83%B3%E3%83%BB%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0/dp/4798111112)
オブジェクト指向__言語__についての本(上下巻ともに恐ろしく分厚い)


[アジャイルソフトウェア開発の奥義](https://www.amazon.co.jp/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E5%A5%A5%E7%BE%A9-%E7%AC%AC2%E7%89%88-%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E9%96%8B%E7%99%BA%E3%81%AE%E7%A5%9E%E9%AB%84%E3%81%A8%E5%8C%A0%E3%81%AE%E6%8A%80-%E3%83%AD%E3%83%90%E3%83%BC%E3%83%88%E3%83%BBC%E3%83%BB%E3%83%9E%E3%83%BC%E3%83%81%E3%83%B3/dp/4797347783)
オブジェクト指向__設計__についての本


オブジェクト指向__分析__についての良い本があったら教えてほしいです.