<輪読会> オブジェクト指向実践ガイド -第8章コンポジションでオブジェクトを組み合わせる-

輪読会メンバー

  • Izumi Haruya

github.com

  • Sekine Yutaro

github.com

第8章コンポジションでオブジェクトを組み合わせる

8.5コンポジションと継承の選択

継承による影響を認める

  • 継承の利点

    • 「合理的であること」
      • 振る舞いの大きな変更を、コードの小さな変更で成し遂げられる
    • 「利用性が高いこと」
      • 新たなサブクラスを既存の階層構造へ追加するとき、既存のコードへの変更はまったく必要がない
    • 「模範的であること」
      • 階層構造(クラスの親子間)における既存のパターンはかんたんに倣うことができる
  • 継承のコスト

    • 継承が適さない問題に対して、誤って継承を選択してしまうこと
      • 新たに振る舞いを追加したいのに、かんたんに追加できる方法がまったくない(コードの複製、再構成など)
    • 問題に対して継承の適用が妥当であったとしても、自分が書いているコードがほかのプログラマーによって、まったく予期していなかった目的のために使われる可能性がある
      • 間違ってモデル化された階層構造の頂点近くの変更にかかる、莫大なコスト
      • サブクラスが複数の型を混合したものの表現であるときの、振る舞いの追加の不可能さ
      • 階層構造を拡張しようとするとき、プログラマーの技術力に依存が故に、意図しない設計になってしまう

継承はケースバイケースである(以下具体例)

たとえば社内向けのアプリケーションのコードを書くとしましょう。しかも、それは自分にとって本当に慣れ親しんだ問題領域のアプリケーションだとします。この場合、抱える設計課題にとって、継承が費用対効果の高い解決法であると自信を持てるぐらい、未来を十分に予測できるかもしれません。しかし、より幅広い人たちにコードを書くほど、将来の要求を予期する能力は必然的に下がっていきます。そして、インターフェースの一部として継承を必要とすることの適切さも下がっていくでしょう。

Sandi Metz. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 (Japanese Edition) (Kindle の位置No.5119-5124). Kindle 版.

コンポジションの影響を認める

  • コンポジションによってつくられたオブジェクト

    • クラス階層の構造には依存しない
    • 自身のメッセージは自身で委譲する
    • 上記の違いが、異なるコストと利点をもたらす
  • コンポジションの利点

    • 責任が単純明快で、明確に定義されたインターフェースを介してアクセス可能な小さなオブジェクトが作られる
      • 小さなオブジェクトは単一責任を持つ
      • コードは簡単に理解でき、変更が起きた場合に何が起こるか明確である
    • 上の階層構造にあるクラスへの変更によって生じる副作用の影響を受けにくい
    • 自身のパーツと、インターフェースを介して関わることで、抜き差し可能で、拡張性が高く、変更にも寛容なオブジェクトが作られる
  • コンポジションのコスト

    • コンポーズされたオブジェクトは多くの小さなオブジェクトに依存してしまい、組み合わせられた全体の動作は、理解しやすいとはいえない
    • 明示的にどのメッセージをだれに委譲するかを必ず知っていなければならない
    • 同一の委譲のコードが、いくつもの多岐にわたるオブジェクトによって必要とされる可能性がある
    • コードを共有するための手段は何も提供してくれない

8.6まとめ

  • 継承が良い場合
    • 過去のコードの大部分を使いつつ、新たなコードの追加が比較的少量のときに、既存のクラスに機能を追加する場合(is-a関係)
  • コンポジションが良い場合
    • 振る舞いが、それを構成するパーツの総和を上回る場合(has-a関係)

総和《名・ス他》幾つかの数・量の全部を加えた合計。総計。

参考書籍

オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 | Sandi Metz, 髙山泰基 | 工学 | Kindleストア | Amazon