少し古い本ですが「オブジェクト指向でなぜつくるのか 第2版」を読みました。
今年は、プログラミングをただ書くだけでなく、もう少し概念的なものも学んでおきたいと思ったので、この本を手に取りました。
自身の性格上こういった概念的な本は、読んでると眠くなってくるのですが、この本は読んでてとても面白く、意外にもスラスラと読むことができました。
意外に感じたのは、オブジェクト指向は Simula67(1967年)という言語で既に存在していたということ。一般的に広まってきたのは、Smalltalk(1970年)からとのことで、個人的に「ぇ、そんな昔からあったの・・・」と驚きました。
Smalltalkといえば、テスト駆動開発本でお馴染みのKent Beckやリファクタリング本で有名なMartin Fowlerも使っていましたね。こういった著名人の繋がりも見えてきたので、個人的には面白かったです。
新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)
- 作者:Martin Fowler
- 出版社/メーカー: オーム社
- 発売日: 2014/07/26
- メディア: 単行本(ソフトカバー)
オブジェクト指向の解説は、こういった言語の歴史的背景から「何故オブジェクト指向が産まれたのか?」を説明していて、これまた面白く、とても納得のいく説明が書かれていました。
第2版では、第1版では語られていないアジャイルや関数型プログラミングについても語られています。とはいえ、第2版が出たのは2011年なので、最近Web業界にやってきた私としては「2011年で関数型プログラミングやアジャイルが既にあったのか!?」とこれまた驚きでした。
オブジェクト指向といえば
以下の3つですよね。
本書を読む前の私は、上記3つは理解していたつもりでしたが、改めて本書を読み進めてみるとポリモーフィズムについては、ちゃんと理解できていなかったことがわかりました。
例えば、PHPでポリモーフィズムを書くと以下のように書けます。
// 継承クラス(親) class ParentClass { public function echo_msg(String $msg){ echo 'デフォルト値:' . $msg . PHP_EOL; } }
// 継承先クラス(子) class ChildClass extends ParentClass { public function echo_msg(String $msg) { echo $msg . PHP_EOL; } }
// メインクラス class MainClass { // オーバーライド。 public function echo_child(ChildClass $obj) { echo $obj->echo_msg('子クラスを型にobjを呼ぶ'); } // オーバーライド。 public function echo_parent(ParentClass $obj) { echo $obj->echo_msg('親クラスを型にobjを呼ぶ'); } } // 子クラスをインスタンス化して、メインクラスに渡す。 $obj = new ChildClass(); $instance = new MainClass(); $instance->echo_child($obj); // 「子クラスを型にobjを呼ぶ」と表示する $instance->echo_parent($obj); // 「親クラスを型にobjを呼ぶ」と表示する
私も知らなかったのですが、メインクラスで継承先のParentClass
(親クラス)を型にして呼び出せるんですね。ちゃんとオーバーライドしています。
ポリモーフィズムは概念で理解していても、こういったテクニックまでは理解できていなかったなぁ・・・と改めて思いました。 こういったテクニックは、おそらくデザインパターンに通じるものがあるような気がしたので、次回かどうかはわかりませんが、こちらの本も読んでみようと思います。
- 作者:結城 浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/06/19
- メディア: 大型本
第2版では、関数型プログラミングについても書かれていました。
関数型プログラミングについては、私は知識がまったく無かったので、概要くらいは本書で掴むことができました。ただ、本書ではHaskellを使って説明していたので、理解に相当苦しみましたが・・・
もし、自分が関数型プログラミングを使うなら、JavaScripでしょう。React.jsが関数型プログラミングを採用しており、仕事で扱うWordPressのBlockエディターもReact.jsが使われているので、こちらも積極的に学んでいきたいですね。
というわけで、本書で説明していた関数型プログラミングの「高階関数」と「カリー化」をJavaScriptで書いてみました。
「高階関数」は、引数に関数を設定したり、戻り値で関数を返したりする関数のことです。
// 引数と返り値に関数「n => n + 1」を設定 const p = (fn) => { return fn; }; const hoge = p(n => n + 1); console.log(hoge(1)); // 2
「カリー化」は、複数の引数を取る関数 を 引数を1つだけ取る関数 を使って順次表現することです。
const c = n => { return m => m * n; } // c(2)は、m * 2を返す関数。それを変数tに設定 // 「複数の引数を取る関数」= c(2)、「引数を1つだけ取る関数」=t(4) const t = c(2); console.log(t(4)); // 8 // cは、以下でも書けます。 console.log(c(2)(4)); // 8
うーん、慣れないと瞬時に理解できないですね。
関数型プログラミングも面白そうなので、順次学んでいきたいですね。
最後に、こういったテクニックを知るのも大事ですが、本書では加えて「プログラマーたるもの言語で扱うメモリーの仕組みも知っておくべき!」とも書かれていました。プログラマーたるものプログラミング言語の内部の動きも知っておけ!ってことですね。確かにプログラミング言語の内部の動きまでは、意識して学ぼうと思ったことはなかったので、ここは改めて気づかされました。
まとめ
本書は、オブジェクト指向の歴史や解説だけでなく、プログラマーが知っておくべき知識やオブジェクト指向から産まれたアジャイルや次世代の関数型プログラミングまで、幅広く解説されていました。
以下、本書を読んで改めて気付かされた点(ざっくり)です。