『オブジェクト指向入門 第2版』の22章を読んだ
22章 クラスの見つけ方
クラス誘出の原則
クラス誘出はクラスの提案とクラスの拒否という2つの過程である。
否定されるべきクラス
何か1つのことだけをするクラス
「このクラスは……をする」という形式で説明できるクラスは,単なるルーチンかもしれない.本来であればクラスに含まれるルーチンであるはずが,間違ってクラスの形式にしている可能性がある.クラスは特定の型に対するいくつかの特性(サービス)を提供するものであるため,1つのことだけをするクラスは誤りである.
また,1つのルーチンしか含まないクラスも,ルーチンがクラスの皮をかぶっているだけかもしれない.
命令的な名前のクラス
クラスの名前は名詞(例:Parser,Window)か形容詞(例:Compareble)にするべきである.命令的な名前が適切だと感じる場合は,そのクラスが1つのことだけをしている可能性がある.
誤った分類をされたクラス
あまりに早い段階から継承の階層構造を考えてしまうと,適切な抽象化が行えなくなる.例えば,1つのルーチンしか含まない子孫が複数ある場合,正しい抽象化ができておらず,闇雲に共通部分を切り出しているだけかもしれない.
これめちゃくちゃ覚えがある.コードを書いているときに,「これって共通化できるのでは?」とか思い始めて,なんとなく切り出して満足する,といったことは実際にやったことがある.何かがに共通するものがあると(共通部分を発見した場合は特に),それを分類したくなることがよくある.対象について十分な知識を得てから分類するようにしないといけない.
命令がないクラス
ルーチンを含まない,C言語でいうところの構造体のようなクラス.このようなクラスは,単にルーチンの実装を忘れているか,リストや配列などで実現できるものを誤ってクラスにしている可能性がある.
混合された抽象
同じクラスに含まれる特性が,複数の抽象に関連する.
理想的なクラス
- 関連する抽象が1つだけある
- クラス名が,抽象の特徴を適切に表す名詞か形容詞である
- クラスがインスタンスの集合(1つでもよい)を表す
- 属性を調べるためのクエリがある
- 状態を変えるコマンドがある
- クラス不変表明,事前条件,事後条件
クラスのカテゴリ
- 分析クラス
外部のシステムのモデルから引き出されたデータ抽象.文書管理システムのParagraphなど. - 実装クラス
アルゴリズムの必要性から導入されたデータ抽象.Listなど. - 設計クラス
アーキテクチャ上の選択肢を表す.Commandなど.
ユースケースについて
ユースケースはクラスを見つけるのに最適な道具ではない.理由を以下に示す.
- ユースケースでは順序が重要であるため
オブジェクト指向は順序に依存するのを避ける.開発の初期の段階で順序を重視するのはオブジェクト指向開発において適切でない. - ユースケースが既存のプロセスに基づくため
存在しないシステムのユースケースを考えると,既存のプロセスをなぞることになる.システムの構築では,より良いユースケースを考え出す必要がある. - ユースケースは動作に基づく機能的アプローチに適しているため
所感
クラスの探し方を説明すると,それこそ厚みのある書籍一冊分にはなりそう(『エリックエヴァンスのドメイン駆動設計』とか).ここの説明は,『リーダブルコード』みたいな,とりあえずこれは押さえておいてね,というぐらいだと思う.