オブジェクト指向設計でよく使われるちょっとしたテクニックを自分の言葉で(from オブジェクト指向設計実践ガイド)

「オブジェクト指向設計実践ガイド」の最初の方をあらためて読む中で目についたテクニックを、自分なりの言葉で(あえて言葉だけで)表現してみる。大体意識せずやってるような内容だが、言葉だけで表現しようとすると理解の細かさが問われなかなか難しいものがある。

当然ながらこれらは有効な場面とそうでない場面がある。文脈に応じて適用するか否かは判断する必要はある。 あとこれだけ読んでも前提が無いのでなんのこっちゃかもしれない。

インスタンス変数の隠蔽

  • インスタンス変数はアクセサで包み直接参照しないようにする。同一クラス内での参照であっても同様。
  • 直接参照の場合「データ」という詳細に依存し、アクセサの場合は「ふるまい」という抽象に依存する。そのためアクセサを利用する方が詳細の変化の影響を受けなくてすみ、クライアント(= オブジェクトの利用者)への影響を抑制できる。

依存性の注入

  • 依存するオブジェクトそのものを外から渡すことで依存の程度を小さくできる。
  • 例えば「具象クラスが何か?」や「生成のための手順」といった依存先の詳細を知る必要が無くなる。
  • 結果として依存先の変更による影響を受けにくくなる。

インスタンス作成の分離

  • 依存性を注入できない場合、つまり別クラスへの依存を内部で保持しなくてはならないような場合は、その箇所をクラス内で分離する。
  • 分かりやすい例としては依存先インスタンスの作成処理が挙げられる。
  • 実現方法としては2つ。1つはinitializeメソッド内で作成するもので、もう1つは依存先インスタンス用のアクセサメソッドを用意しその内でインスタンスを作成する。
  • 前者はインスタンス作成と同時に依存インスタンスも作成する。依存インスタンスの作成タイミングは固定されるが、要不要に関わらず必ず依存インスタンスを作成することになる。
  • 後者は必要になったタイミングで初めて依存インスタンスを作成するが、そのタイミングは固定化されないため、メモ化 (外部インスタンスの作成時に ||= を用いて インスタンス変数に代入する)のような考慮も必要になる

脆い外部メッセージの隔離

  • 外部メッセージはそれ自体をメソッドとして隔離する。
  • 他のテクニックでも言えることだがこれは必ずしも必要な対処ではない。
  • 例えば外部メッセージの利用が処理の大部分を占めるようなシンプルなメソッドにおいては、依存性が明確であるため隔離する必要性は薄い。
  • 逆に複雑なメソッドにおいては、そのメソッド自体が行いたいロジックと外部メッセージの利用が混在し、依存性が埋め込まれて見えにくくなってしまう。この状態では修正が意図しない範囲に悪影響を及ぼす可能性があるため、外部メッセージは隔離する方が良くなる。