オブジェクト指向がわからないマンなので、「オブジェクト指向入門」という本を読んでます。
800ページ以上あるうちの100ページちょいしか読んでないんですけど、忘れないうちに気になったことや面白かったことをまとめたいと思います。
ちなみに4章までは「オブジェクト指向を理解するための下準備」みたいな話なので、実質まだ本編に入っていないところまでです。
本全体について
誰が読むべきか
オブジェクト指向がわからないマンは読むといいと思います。
自分がオブジェクト指向がわからないマンかどうかの判断は
「オブジェクト指向のゴール(目標)は何ですか?(どのような状態になったらオブジェクト指向を使って良かったと言えますか?)」
という問いにすっと答えられるかでわかると思います。
易しくない入門書
この本は800ページありますが、入門書です。
つまり、「オブジェクト指向」というものを知らなくても、普段の開発の現場でどのような問題があり、それをオブジェクト指向がどのように解決してくれるのかがとても丁寧に書いてあります。
ページ数が多いもののほうが、ちゃんと丁寧に説明してる場合が多いなーと改めて思いました。
ちなみにエリック・エヴァンスの「ドメイン駆動設計」もページ数が多いですが、そちらよりも圧倒的に読みやすいです。
一方で、この本は易しくはありません。
なぜなら抽象度がとても高い内容だからです。
この本を読み解くには、自分の持ってる知識をフルで使っていく必要があるように思います。
「あー、これはPHPでいうと〇〇のことだな」と自分に身近なもので置き換えていくと理解しやすいです。
読む前に知っておくと良いこと
以下を知っていると読むのが捗りそうです。
数学については日本人は苦手だと思います。
この本で必要になるのは数字計算ではなく概念です。
数学的な概念は入試では問われないことが多いので、わからない人も案外多そう。
・・・といっても基礎的な概念を理解してれば大丈夫です。
具体的には以下のような概念が出てくるので、これを自分の言葉で説明できるようになっておくと良いと思います。
- 関数
- 開いている/閉じている
- 依存している/独立している
- 連続している
本の内容について
まえがき
ざっとまとめると、「オブジェクト指向とは、ソフトウェア工学の目標を達成するものである。ソフトウェア工学の目標とは、品質の高いソフトウェアを作り出すことである。」のようなことが書いてありました。
オブジェクト指向の目標は何ですか?という問いに自分は答えられなかったので、ここだけでも価値がありました。
オブジェクト指向の核心については、
- 構造的な手法
- 信頼性の規律
- 認識論上の原則
- 分類の技法
とまとめられています。
最近のオブジェクト指向の議論では「構造的な手法」ばかりが目立っているように感じていて、他の要素についてはあまり認知されていなさそうだなーと思います。
僕も構造的な手法しか知らなく、「信頼性の規律」である契約の話を知りたくてこの本を買いました。
読んでるところがまだそこまで到達していないので、ワクワクしながら読み進めてます。
あと、「ブックワイドウェブ」1という言葉がキャッチーで好きです。
1章 ソフトウェアの品質
ソフトウェア工学の目標が品質なので、まず「品質とはなにか」という話から始まります。 この本では品質を、ユーザが認識できる「外的品質要因」とそれ以外の「内的品質要因」に分けていて、内的品質要因は外的品質要因を高めるために必要であることが書かれています。
ので、この章では外的品質要因の特性についてつらつらと書かれています。
拡張性について
なるほどーとなったのは、拡張性が外的品質要因に含められていることです。
ネット上の情報では拡張性は内的品質要因として語られていることが多かったので、意外でした。
ちなみに理由は以下のように書いてあります。
「ユーザ」という言葉には、航空券予約システムを使う航空会社の職員のような、最終的な製品を利用する人々だけでなく、航空券予約システムの調達や委託の責任を持つ航空会社の役員などの、ソフトウェアの買い付けやソフトウェア開発の契約を担当する人々も含まれる。したがって、ソフトウェアが仕様の変更に対応しやすいかといった性質(これは後で出てくるが、本書では拡張性と定義した)は、予約係などの「エンドユーザ」とは直接の関係はないかもしれないが、外的品質要因に含まれる。
僕たちは「ユーザ」というとエンドユーザのことを思い浮かべてしまいますが、視野が狭かったなと気付かされました。
使いやすさについて
ここではユーザインターフェースの有名な教訓である「ユーザのことを知りなさい」を提示していて、それとは真逆である
そのユーザのことを知っている気になるな。あなたは知らない。
ということを提唱しています。
最近風に言うと、たとえばファイルアップロードの機能を作るにあたり、ドラッグアンドドロップでアップロードを可能にするとします。
このとき、「ドラッグアンドドロップなんてみんな知ってて当たり前だよね」という前提のもとにシステムを作ってはいけないという話です。
この本は80年代に書かれているものなのですが、現在のユーザビリティへの示唆に富んでいるなと思いました。
アジャイルの示唆
この本では、「人間の一番の特徴は変化することだ」と述べており、仕様は必ず変わるものだ、という話が何度も出てきます。
これは、アジャイルの基本的な考え方です。
また、品質についてはすべてを満たすことはできず、トレードオフになることも書かれています。
この本は80年代に出版されています。当然、その頃はアジャイルなんて流行っていなかったはずです。
ちょっと先見の明がありすぎないか・・・?と軽く感動しました。
2章 オブジェクト指向の基準
この章は特別で、「これから本書で説明していくオブジェクト指向とはこういう性質を持ってるよ」という内容が書いてあります。
つまり、「オブジェクト指向らしさ」について書かれているところです。
だいたいの言語が満たしていない
だいたいの言語が満たしていない項目がいくつかあります。
型としてのクラス
すべての型はクラスに基づいていなければならない。
つまり、「プリミティブな型なんてないよ」という話です。
PHPは満たしていなさそうです。
Javaはどうなんでしょうね。
Integerクラスを用いてint型が実現されているのであれば満たしていそうですが、int型を用いてIntegerクラスが実現されているのであれば満たしていなさそうです。
多重継承・反復継承
クラスは任意の数のクラスから継承できなければならない。
反復継承の場合の特性がどうなるかは、厳密な規則によって管理されなければならない。
これもサポートしている言語を知らないなーと思いました。
多重継承がサポートされないので、反復継承ももちろんサポートされません。
3章 モジュール性
自己文書化
モジュールを設計する人は、モジュールについてのすべての情報をそのモジュールの一部として作るようにあらゆる努力をするべきである
これはドキュメンテーション信者の僕としてはよくわかる話で、swaggerなんかもここに近い思想だよなーと思ったりしています。
つまり、API定義を別のファイルで管理するのではなく、なるべくクラス(モジュール)に閉じ込めようという話です。
「テストコードは仕様書」なんて言葉をたまに聞きます。2
もしテストコードが仕様書としての機能を期待されているのであれば、テストコードは同じモジュール(クラス)内に書いたほうが良いのでしょうか。
テストコードがモジュール内にあれば、仕様を確認するためにわざわざテストコードのファイルを探す手間も省けますし、IDEがよしなに表示してくれそうですよね。
なんかそれもアリな気がしてきました。
開放/閉鎖の原則
モジュールは開いていると同時に閉じているべきである。 モジュールが拡張を受け入れられる状態にある場合、そのモジュールは開放されているという。 モジュールがほかのモジュールから使用できる状態にある場合、そのモジュールは閉鎖されているという。
ほぼSOLID原則の開放閉鎖の原則と同じですね。
モジュールは拡張に対して開いてなければならず、修正に対して閉じていなければならない。
のような感じだったと記憶しています。
まぁ言っていることは変わらないのですが、気になるのは「開く」「閉じる」という言葉の含んでいるものが微妙に違うということです。
オブジェクト指向入門でいうところの「開く」「閉じる」は対象も包含した言葉であり、SOLID原則の「開く」「閉じる」は対象を包含していません。
まぁ、細かい話なんですが。
ちなみに、オブジェクト指向入門での開放/閉鎖の原則は、継承によって達成する、という話の流れになっています。
単一責任選択の原則
ソフトウェアシステムが選択肢を提供しなければならないとき、そのシステムの中の1つのモジュールだけがその選択肢のすべてを把握すべきである。
似た言葉にSOLID原則の「単一責任の原則」がありますよね。
クラスを変更する理由は1つ以上存在してはならない
これは言い方が違うだけで同じことを指しているのか、それともたまたま名前が似通っただけなのか、すごい気になります。
4章 再利用性
何を再利用すべきか?
この話題で一番最初に出てくるのが「人材の再利用」で笑ってしまいました。
そしてなるほどー!たしかに!ってなる。
やっぱ自分の視野は狭いんだな・・・と思わされます。
ソフトウェア開発における繰り返し
開発者は似たような作業を繰り返しやっている、という話なのですが、それを示す話として以下のような質問があり、グサッと来ました。
あなた自身、あるいは、あなたの部下は過去6ヶ月の間に表検索のプログラムを何回書きましたか。 ここでいう表検索は、ある特定の要素xがそれと同じような要素からなる表tにあるかどうかを判断する問題として定義する。要素の型、tのデータ構造の表現、探索アルゴリズムなどについて、この問題には多くの変形が存在する。
つまり、for文などのループで配列から特定の値を抽出するプログラムのことを指してるわけですね。
死ぬほど!!!書いてる!!!!
再利用とやり直しのジレンマ
良くある状況は、そのモジュールがいまの仕事の部分的な解決策にはなるが、完全な解決策というわけにはいかない場合である。そのときの要求を満たすためには、そのモジュールのもともとの振る舞いをいくらか調整しなければならない。したがって、そのような場合にすることは再利用とやり直しなのである。少し再利用して、少しやり直す。願わくは、たくさん再利用して、少しやり直す。
よくある・・・
この本、現実をグサグサと突きつけてくる感じがします。
そして似たようなコードが大量にできてしまうんですよね・・・
多重定義
異なる名前を使うのを避けることにいったいメリットはあるのだろうか。おそらくないだろう。 残念なことに、最近のJava言語には、特にオブジェクトを作成するための代替手段として、いま述べたような構文的多重定義が含まれている。
ここでの多重定義はオーバーロードのことを指しているのですが、オーバーロード全否定。。。
まぁでも中身を読むとたしかに・・・となったりします。
でも同じ命名付けたくなるとき、あるよねぇ・・・
まとめ
まだオブジェクト指向の話に入ってないわけですが(笑)
それでもソフトウェア開発という文脈だけで、これだけの気づきがあるのはとても楽しいです。
みなさんもよければぜひ読んでみてください!
-
ワールドワイドウェブのもじり↩
-
僕はこの言葉はあまり好きではないのですが・・・↩