OOSC 4章 再利用性へのアプローチ

先日、4章「再利用性へのアプローチ」まで読んだので、読み返しつつメモします。

4.1

4.1は、再利用性がなぜ大事かという話。

再利用性は、消費者(再利用可能なモジュールを使う人)の側からの視点と、生産者(再利用可能なモジュールを作る人)の側からの視点から考える。再利用性の話をする時には、どちらの視点からの話をしているかを意識せよ、とのこと。

再利用の生産者になろうとする前に再利用の消費者となれ。

4.2

4.2は、「何を」再利用するかについて。再利用するのはソフトウェア部品でないといけないらしい。

日常的に「再利用(できる|すべきである)のは、実装でなく設計だ」という話をよく聞く。ここではその言説に否定的だ。ここでいう設計とは何かを考えさせられた。自分はデザインパターンの類だろうと考えていたけれども、設計とデザインパターンは項を分けられている(4.2.2と4.2.3)。再利用の対象として設計を挙げるとき、この本の文脈ではそれはデザインパターンを意味しないのだと思う。

著者は設計の再利用に否定的だが、次のようにも書いている。

「設計と実装の差がほとんどなくなるようなアプローチ(例えば、本書で進めていくオブジェクト指向の見方)ならば、設計の再利用というアイデアももっとおもしろいものになる。

つまり、再利用の対象として望ましい「設計」は、そのままソフトウェアに組み込めるくらい実装に近く、さまざまな状況のために特殊化できる程度に汎用的な「何か」だということが分かる。

4.3、4.4

4.3と4.4では、再利用の正当性と、再利用するからには利用しやすい場所に置くべしという話と、配布形式の話になる。

4.5

4.5からは、再利用可能なモジュールがどういう形であるべきかという話。ここで出てくる「再利用とやり直しのジレンマ」(p.106)はあるあるあるwwという感じでつらい……。

モジュールを凍結してしまうと、再利用かやり直し(reduce or redo)のジレンマに立たされてしまう。全くそのままでモジュールを再利用するか、完全に作業をやり直すかを選ばなければならない。

この話を読んで思い出した。再利用を目指してモジュール化されたメソッドやストアドプロシージャが、意図どおり複数の顧客モジュールから利用されてはいるものの、引数によって処理を内部で分岐することで共通化を実現しているケースをたまに見る。これは良い再利用の仕方ではないと思う。こういったケースについて、この本ではどんな説明をしていたか、注意して読み進めよう。

4.6

(なんという美猫)

4.6は、モジュール構造の5つの条件。

型のバリエーション
そのまま実行できるルーチンではなく、アルゴリズムの振る舞いのパターンであること
ルーチンのグループ分け
パッケージの話だけれど、この章では詳しく扱わない
実装のバリエーション
あるルーチンのパターンで、特定のデータ構造やアルゴリズムを使う様々な実装が可能になること
表現の独立性
顧客モジュールが、実装の詳細や実行時の変化を知らずに、そのモジュールを使えること
共通する振る舞いのふるい出し
様々なデータ構造やアルゴリズムの実装で使われるように、共通する振る舞いを定義すること

p.109

また、表現の独立性を満たすことは、モジュール性の説明のところで出てきたこれに関係する原則である単一責任選択の実現を助ける。単一責任選択の原則は次のようなたくさんの候補の中から識別する多分岐制御構造とかかわらずに済ませるための原則である。

この先の本文には、特定の実装向けの処理を多分岐で実装するサンプルコードが出てくる。先ほど疑問に思った「引数によって処理を内部で分岐することで共通化を実現しているケース」も、表現の独立性を保つことで解決されるべき問題なのかもしれない。

4.7

4.7では、オブジェクト指向以前の手法でなぜ十分でないか、という話。

まず、単純で固定的な状況では、ルーチンで事足りた。次に、アクセス権を管理できるパッケージが現れたけれども、型のバリエーションには対処できなかった。などなど。

気になったのはここ。(p.118)

多くの場合、情報隠蔽を実施するために、カプセル化支援言語ではインタフェースと実装の2つの部分に分けてパッケージを宣言し、型宣言の詳細やルーチンの本体などの内容の要素は実装の部分に退避させることが勧められている。(中略)情報隠蔽をもっと良く理解すれば、こうしたことは全く必要ない。

これって、com.example.fooとcom.example.foo.implのようなパッケージ分割の話してる? 全く必要ないとは一体。

あと、タイムリーにこんな記事があったのでメモ。

4.8

4.8は、多重定義と総称性の説明。

構文的多重定義はオーバーロード、意味的多重定義はオーバーライド、総称性はジェネリックスの話だと思う。

多重定義は顧客(呼び出し側)のため、総称性は供給者(呼び出される側)のため、という視点は面白いなと思った。そういうふうに見たことがなかった。

4.9

まとめ。ここまでの話で、「モジュール構造の5つの条件」に出てきた、型のバリエーション(総称性)とルーチンのグループ分け(パッケージ)はカバーされた。他についてはまた後々、とのこと。