「オブジェクト指向でなぜつくるのか」を読んでみた
はじめに
オブジェクト指向プログラミングへの理解を深めるため、「オブジェクト指向でなぜつくるのか」を読んでみました。
この記事には本のまとめと感想を記載します。あくまで個人の解釈ですのでお手柔らかに。
読んだ本↓
オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識
結論:オブジェクト指向でなぜつくるのか
オブジェクト指向で作る理由は「ソフトウェアを楽に作るため」である。具体的には、オブジェクト指向が登場する前の開発と比較して以下のようなメリットがある。
- ソフトウェアの保守性と再利用性が向上する
- ソフトウェアの設計がしやすい
シンプルだが強力なこの2つメリットが、オフジェクト指向プログラミングを急速広めた要因である。
オブジェクト指向の全体像と歴史
オブジェクト指向はソフトウェア開発の総合技術。JavaやPythonのようなプログラミング言語からはじまり、設計や開発手法に至るまで、ソフトウェア開発のほとんどの領域をカバーしているらしい。
オブジェクト指向が生まれた背景
個人的にはこの辺の説明が一番面白かった。
プログラミングは、機械語
→アセンブリ言語
→高級言語
→構造化言語
→オブジェクト指向のプログラミング言語
と進化してきた。それぞれの言語はそれ以前の言語のデメリットを克服してきた。
機械語
A10010
0B160210
1940年ごろの16進数でのプログラミングの例です。これで何を理解しろというのか、当時のエンジニアには尊敬でしかない。生きていたら神社になれること間違いなし。
アセンブリ言語
MOV AX, X
MOV DX, Y
ADD AX, DX
これは多少わかる。ADDは足し算,MOVは情報の移動。でもまだかなり使いづらい。
高級言語
Z=X+Y
これは数式に近く、プログラマー以外でも理解できるかと思います。1950年ごろに既に考案されていて、1960年にCOBOL
が登場したようです。
構造化プログラミングと構造化言語
構造化プログラミングはプログラムの理論のこと。
構造化プログラミングでは、プログラミングの三代要素である順次処理
、繰り返し
、条件分岐
の構造だけで表現するということが提唱されたり、グローバル変数やサブルーチン(グローバル関数)を利用してプログラムを書くようになったようです。
また、構造化プログラミング理論に基づくプログラミング言語を構造化言語と言い、Pascal
やC言語
がこれに当たる。
しかし、構造化プログラミングには「グローバル変数の管理が難しい」ことや「サブルーチンの再利用性が低い」という問題点を抱えていた。
これらを解決するために生まれたのがオブジェクト指向プログラミングである。
オブジェクト指向におけるプログラミング技術
オブジェクト指向プログラミングの三代要素はクラス
、ポリモーフィズム
、継承
である。
この3つの仕組みで構造化言語の課題である「グローバル変数問題」と「貧弱な再利用性」の解決を目指した。
今更すぎますが、これらについて少しだけ解説。
クラス
クラスは「まとめて、隠して、たくさん作る」仕組み。
Class Dog {
private string $name;
public function call(){...}
}
$dog1 = new Dog('ぽち');
$dog2 = new Dog('まろん');
- 変数とメソッドを「まとめる」
- クラス内に変数とメソッドを「隠す」
- 1つのクラスからインスタンスを「たくさん作る」
このようにクラスの中に「まとめて、隠す」ことで、変数や関数の使用範囲を限定することができ、インスたんを「たくさん作る」ことで再利用性が向上する。
ポリモーフィズム
ポリモーフィズムはひと言で表現すると「共通メインルーチンを作る」ための仕組みである。
メインルーチンを「呼び出す側」、サブルーチンを「呼び出される側」とすると、従来の構造化言語では、「呼び出される側」が共通化されていたのに対して、オブジェクト指向プログラミングでは「呼び出す側」が共通化される。
構造化言語では...
function Sub () {...}
function MainA () {
...
Sub()
...
}
function MainB () {
...
Sub()
...
}
呼び出す側(MainA, MainB)の処理が変わり、呼び出される側(Sub)の処理が共通化される。
オブジェクト指向プログラミングでは...
Class Animal {
public function call(){...}
}
Class Cat extends Animal {
public function call(){...}
}
Class Dog extends Animal {
public function call(){...}
}
// DogもCatも引数に受け取れる
function MainA (Animal $animal)
{
...
$animal->call()
...
}
継承することで、呼び出す側(MainA)の処理が共通化され、呼び出される側(Dog, Cat)の処理が変わる。
継承
継承は「クラスの共通部分を別クラスにまとめる」仕組み。
この仕組みを利用することで、変数とメソッドをまとめて共通クラスを作り、別のクラスからその定義をまとめて拝借することができる。
Class Animal {
private string $name;
public function call(){...}
}
Class Cat extends Animal {
public function nekopanti(){...}
}
Class Dog extends Animal {
public function inukick(){...}
}
Dogクラス、Catクラスは共にAnimalクラスのnameやcall()メソッドを拝借することができる。Animalをスーパークラス、DogやCatをサブクラスという。この継承の仕組みにより再利用性はさらに向上した。
クラス、ポリモーフィズム、継承の仕組みによって、従来の構造化言語の課題である「グローバル変数問題」と「貧弱な再利用性」は大きく改善された。
オブジェクト指向プログラミングは従来と比較して突然変異とも呼べるような風変わりな仕組みを多く導入しているが、どれも工夫と改良の中で必然性を持って生まれた技術である。
オブジェクト指向から生まれた応用技術
プログラミング分野での効果が認められたオブジェクト指向は、次の段階でその効果をシステム開発全体に波及させるため、上流工程に応用された。
その結果として「物事を分類して整理する基本的な枠組み」に進化し、下流工程の「プログラミング技術」と上流工程の「汎用の整理術」という2つの顔をもつようになった。
「汎用の整理術」としてオブジェクト指向はプログラミング以外にも、下記のような設計や開発手法にも活かされている。
- UML(Unified Modeling Language)
- アジャイル開発(反復型開発プロセス)
UML(Unified Modeling Language)
UMLの実態はソフトウェアの機能や内部構造を表現する「図」の描き方である。オブジェクト指向の分野における図式表現は、そもそもオブジェクト指向プログラミングの構造を表現するために考案された。
UMLの登場以前は、オブジェクト指向を使ってシステムを開発する際の作業手順や考え方を体系的にまとめた方法論が多数提唱されていた。しかし1990年代後半に当時の主要な開発方法論の考案者が集まって図式表現を統一した結果作られたのがUML。
アジャイル開発(反復型開発プロセス)
アジャイル開発に関してはオブジェクト指向と直接的な関係はない。
しかし、アジャイル開発を支えるプラクティスであるTDDやリファクタリングが、オブジェクト指向プログラミングの恩恵を深く受けていることや、アジャイル開発を提唱し推進している多くの人たちがオブジェクト指向に深い関わりを持っている。
したがって、直接的な関係はないとはいえ、両者は強い結びつきがあり、アジャイル開発はオブジェクト指向から生まれたと言ってよいだろう。
UMLによりソフトウェア開発における「業務分析」「用件定義」「設計」をより円滑に進めることができるようになり、アジャイル開発により変更につよいソフトウェア開発が可能となった。
これらは、オブジェクト指向の効果が上流工程にまで波及したことの一例である。
おわりに
この本を読んでみて、「オブジェクト指向でなぜつくるのか」と聞かれたら「保守性と再利用性をあげるため」と答えることにしようと思う。
なぜなら、歴史的な背景から機械語
→アセンブリ言語
→高級言語
の進化においては「ソフトウェアをいかに人にわかりやすい形で開発できるか」という追求してきた一方で、オブジェクト指向プログラミング言語はいかに保守性と再利用性を向上させるか
という思想のもと生まれた技術であると感じたから。
また、本を読むまで自分は、オブジェクト指向と聞くとクラス、継承、ポリモーフィズムのなどのプログラミング技術を想像していたので、上流工程においてもオブジェクト指向が活かされているというのはすごく興味深かった。
ソフトウェア開発全体を大きく発展させたオブジェクト指向、いつも当たり前のように使っていたけど、これは先人たちに感謝しなければならない。ありがとうオブジェクト指向、これからもよろしくお願いします。
Discussion