オブジェクト指向入門 第4章「再利用性へのアプローチ」を読みました
現在、オブジェクト指向入門という本を読み進めています。
最近引っ越しの作業などであまり時間が取れなかったのですが、スキマ時間に読みながらようやく4章を読み終わりました。 気になった点や感想などを、いつもどおりメモしていきたいと思います。
前回はこちら。
概要
第4章は、モジュールの利点の一つである、再利用性にフォーカスを当てた内容でした。
プログラムを再利用する利点
プログラムを再利用することは、下記のような様々な利点がある。
- 適時性:既存の部品を再利用することにより、しない場合に比べて早く完成できる
- 保守作業の軽減:各モジュールを再利用する事により担当領域毎の責任の所在が明確になる
- 信頼性:評判の良い部品を利用することで、1から作るより高い品質を確保できる
- 効率性:それぞれの部品をその部品を関心事の専門家が作ることにより、最善のアルゴリズムやデータ構造に出来る。(数学者が計算ライブラリを開発するなど)
- 一貫性:同じ事をしようとする時に、その部品に依存する全ての部分が一貫性のある書き方となる。
- 投資:優秀な開発者のノウハウを時間とともに消費するのでなく、部品として保存し資産として利益をもたらし続ける事が出来るようになる。
再利用性の利点には
- 生産者(部品を作る人)
- 消費者(部品を使う人)
の2つの視点での利点が存在する。
基本的に、いきなり再利用可能な部品を作ることは不可能である。
まずは良い部品を使い、使い方の学習をしたり、部品を模倣したりすることで、自身のスキルを上げることで初めて良い部品が作れるようになる。
何を再利用するか
一口に再利用と行っても、様々な粒度が存在する。例えば、 - 人材の再利用:企業がノウハウを持つ人材を様々なプロジェクトに割り当てて、ノウハウが失われるのを防止する。 - 設計と仕様の再利用:モデル設計の再利用。コードテンプレート的な形 - デザインパターン:設計上の問題に対する解決手法のパターン - ソースコードによる再利用:ソースコードをそのまま配布する
人材の再利用や設計の再利用は企業単位の話になってしまう。
また、ソースコードによる再利用は、仕様の把握が難しかったり、利用したい特定の処理がスクリプトの中に埋もれてしまったりする問題がある。そして、ソースコードの中でルールを飛び越えて他の部品に依存してしまい、不必要な部品にまで利用者側が依存してしまう問題もある。
以上のことから、再利用可能なソフトウェアの要素は、前回の章で定義されたモジュールの条件を満たすモジュールである必要がある。また、部品の使用者に関係する情報のみが開示されて、その他の詳細は隠蔽されている = 抽象的である必要もある。
モジュール再利用の障害
- NIH(Not invented here)症候群:自分のテリトリー外で開発された事を理由に、再利用を拒む NIH症候群 - Wikipedia
- HIN(Habit Inhibiting Novelty)新しいもの嫌い症候群:特定のツールに慣れてしまい、新しいツールを導入することを拒む。
- モジュールの配布方法
モジュールの再利用には、技術的な問題のみならず、組織/経済/文化的な側面での問題も存在する。
技術的な問題
- プログラムを書く時、同じ処理を繰り返しがちだが、まったく同じ処理ではなく、似たようなパターンだが微妙に異なる処理を繰り返すことが大半である。その共通性を見つけて抽出するのが難しい。
- 本当に特定の問題に対処するためだけのモジュールだと、他の部分で再利用ができず、再利用 or やり直しの2択を迫られる事になる。
- 開放/閉鎖の原則に則って、一部分を再利用しつつ(閉鎖されている)、その問題の解決に適用が可能(開放されている)のが、良いモジュールの条件である。
- 配列、ファイル、連結リストなど、様々なデータ構造に対して行いたい操作(全探索など)をする際に、カーソルの概念など共通項をを見出し、不必要な処理の重複を防ぐ必要がある。
伝統的なモジュール構造
- ルーチン:javaでいうstatic関数など。入力に対する出力が存在するのみなら共通化出来るが、複雑なデータ構造が存在する場合や、様々なケースに対応しようとして複数のルーチンを用意しようとすると独立性が失われてしまう問題がある。
- パッケージ:個別コンパイルや情報隠蔽などサポートしている。しかし、型のバリエーションに対応しておらず、処理の対象としたい型が増えるたびパッケージも対応しなければならず、独立性が無いと言える。
上記のモジュール構造の問題を解決するのが、多重定義と総称性(generics)である。
多重定義と総称性
- 多重定義:javaでいうoverload。引数が同じ型だが、それぞれ意味合いが異なる場合に対応できない。
- 総称性:javaでいうgenerics。多重定義で問題となった型のバリエーションを受け入れるための答え。
に対する は実総称パラメータ(actual generic parameter)と呼ぶ - List
がList と定義され、実際のモジュールを獲得することを総称的派生(generic derivation)と呼ぶ
総称性は、供給者モジュールの作者のための機能で、Listなど特定の概念を表す一つの実装を複数のオブジェクトに適用することが出来るようになる。
総称性は表現の独立性、共通する処理のふるいだしには有効ではない。それに関する答えはまた次の章で解説する。
感想
固有の概念や用語が多く、なかなか読むのが辛かった章でした。
ちまちま読んで4章を振り返りながら今記事を書いていたのですが、前半部分は殆ど忘れてしまっていました…
新人研修などでinterfaceやポリモーフィズム、genericsなど使い方に関しては学習してなんとなくどのような概念かはイメージがつくのですが、このように改まって抽象的に解説されると、その言語仕様の裏側にある原則などがまだまだ理解出来てなかったのだと感じました。反面、現在自分がある程度疎結合なプログラムを無意識的に、当たり前のように開発出来ているのは、先人のこのような研究や概念の発見があってこそだったんだなと、現状のパラダイムから開発をスタートできたありがたみを感じました。
数十年前の本のはずですが人材の再利用や組織の話などは、今でも通ずる話ですね。ある程度経験を積んだエンジニアだとNIH(新しいもの嫌い)症候群になりがちかちなイメージがあるので気をつけていきたいです。
また、いきなり「再利用可能な部品を作ることは不可能である」というのは、かなり重要な原則かなと思います。いきなり再利用可能性からスタートしてモジュールを作ろうとして良い部品になる事って殆ど無いですよね。様々な優れたライブラリを使って、どのような開放/閉鎖具合が望ましいかを意識的に学習していないと、そのような再利用可能な部品を作る能力は身につか無さそうですね。
次は、第五章です。少々読むのがしんどくなってきた(まだ自分には早かったのではと感じ始めている)のと、最近業務でクラス図を書く機会が増えたので最近買った下記の書籍に浮気してみようかなと思います。