オブジェクト指向が理解しづらい理由
最近気づいたのは、ほとんどの人がプログラミング視点で見ているせいではないかなと考えるようになりました。
プログラムは目的ではなく手段です。
本当の目的は業務であり、システム開発の目的は現実社会の業務をコンピュータへ代替させることです。
つまりプログラムの手段的視点ではなく、もっと上位の目的視点でオブジェクト指向を観察すれば、カプセル化やポリモーフィズムがどんな目的で存在しているのかが見えてくるはずです。
例えば、運送業務をオブジェクト指向で実現するとした場合
まずは、実世界の業務を観察し、行為ではなく実体を見つけます。
例えば、こんな感じになります。
・商品
・配送センター
・トラック
・お客様
これらはすべてカプセル化されたオブジェクトに相当します。
次に、これらのオブジェクトの「関係」を観察します。
その時に使用する概念は「機能」です。
機能は実体が活動する行為で表せます。
例えば、以下のようになります。
・商品は配送センターに集約、保管され
・お客様からの注文で
・トラックでお客様宅へ配送される
ただ、実際には商品にもたくさん種類があり、種類ごとに扱いが変わります。
それらすべてを最初から盛り込むと非常に複雑になり、理解しづらくなります。
そこで、まず、概要設計段階では、その辺を無視して単に商品として定義します。
これが、業務レベルの抽象化です。
実装する場合は、商品オブジェクトは抽象クラスになるでしょう。
ただ、設計レベルでもこの段階で抽象的なオブジェクトとして扱うことで、設計から実装にフェーズが変わっても、これまでの方式のように視点を変換する必要がなくなります。つまり、現実社会をそのまま実装しやすくなるというわけです。
また、詳細レベルのフェーズに入った時には、商品としての基本部分は親クラスとして定義し、商品毎に異なる部分はポリモーフィズムで定義します。
これが、実装レベルの抽象化です。
このように、機能レベルでオブジェクト指向を観察すると、その目的が明確になります。
そして、機能設計が終わった段階で、すでにプログラムレベルでの構成はできているので、あとは、個別のオブジェクトに閉じて淡々と実装すればよく、他のオブジェクトとの複雑な関係はインターフェースで吸収することで、汎用的な部品としてシンプルな単一オブジェクトを扱うことができます。
最後に、この機能をインターフェースとして定義します。
機能も概要レベルでは抽象度は高くシンプルですが、詳細レベルでは細かなオブジェクト間の関係性を記述することになり、概要レベルでは抽象クラスとして定義します。
つまり、抽象度が高いものは業務担当者向け、抽象度が低いものはプログラマー向けとして分業化が可能になります。
そして、従来のように、概要設計と詳細設計で記載概念が変わるのに対して、オブジェクト指向では抽象度が変わっても、その記載概念(アーキテクト)は変わらないので、シームレスで一貫したシステム開発が可能になります。
そして、バグが一番発生しやすい変換作業が軽減できるので、信頼性も向上します。