Delegation

Javaプログラムで委譲を説明

エンジニアをしていると委譲という言葉がよくでてくるかと思いますが、調べた際には理解したつもりが後々になんだっけ?となる事がしばしばあるので備忘のために纏めていければと思い記事にすることにしました。内容などに間違いなどあれば、ご指摘いただければ光栄です。

・委譲(Delegation )とは
そもそも委譲(Delegation )とは何なのか。委譲とは言葉の通り権利・権限などを他の人・機関に譲ずって任せることを意味しています。プログラムに置き換えて説明すると委譲(delegate)とは、あるオブジェクトがプログラム中でイベントが発生したとき、それに代わって、または連携して処理するオブジェクトのことを意味しています。

なぜ委譲なのか、委譲以外の方法で実装できないのか。
実際委譲を使わなくてもJavaなどのオブジェクト指向プログラミング(OOP)では標準機能として用意されている継承(既存クラスを継承することにより特性、振る舞いを引き継ぐ)を使うことで想定するプログラムを作成することは可能です。しかしながら継承のみでは問題点もあります。
クラスを継承すると、親クラスの変更に子クラスが大きな影響を受けるので変更がしづらくなることがあります。
そのほかにも菱形継承問題です。Javaでは多重継承を言語として許していません。
委譲を使った場合では、2つのクラスは完全に分離しているので、変更の影響が低くなります。また複数のインスタンスを保持することで多重継承の問題にも対応可能です。

委譲の実装サンプル
それではどのように委譲をプログラムに組み込んでいけばいいのか。
委譲は別のクラスをインスタンス変数として保持し、各インスタンスメソッドで、それぞれのメソッドに対する既存クラスのメソッドを呼び出してその結果を返すようにします。
継承で書く場合と、委譲で書く場合のサンプルが以下となります。
比較してみてみましょう。

継承を使った実装 
class A { 
  void print() { 
    System.out.println("test"); 
  } 
} 
class B extends A { 
  void print() { 
    super.print(); 
  } 
} 
public class Tester { 
  public static void main(String[] args) { 
    B b = new B(); 
    b.print(); 
  } 
} 


委譲を使った実装

class A {
  void print() {
    System.out.println("test");
  }
}

class B {
  A a = new A();
  void print() {
     a.print();
  }
}

public class Tester {
  public static void main(String[] args) {
    B b = new B();
    b.print();
  }
}


どんな時に使い分けるのか
継承を使ったほうが良いのか、委譲を使ったほうが良いのか、具体的に何を基準にして使い分ければ良いかを以下に記載しています。参考例であるため、絶対ではないと考えて頂ければと思います。
・子に親と同じ役割が期待される場合、親と同様に振る舞えるようになる継承を使うのが良い
クラスBとクラスAとの間に「is-a」関係が存在している場合にだけ適用するべきといわれています。
・子に親と同じ役割が期待されない場合、子にとって親は単なるツールである可能性が高いため委譲を使うのが良い
親クラスが子クラスを含んでいる(例えば子クラスが持つ機能を親クラスが持っている状態。 has-a関係)場合は委譲を適用するべきといわれています。

まとめ
メリット、デメリット
・継承のメリット
継承では基底クラスのメソッドを変更しなければ、何もせずにそのまま使うことができる。
・継承のデメリット
親クラスの実装が変更された場合にはその変更の影響を受ける。
・委譲のメリット
親クラスに変更があった場合には別クラスにきりかえるなど継承よりも柔軟性がある。
・委譲のデメリット
わざわざメソッドの呼び出しを実装しなくてはならないため、継承に比べてコードの記述量が多くなります。
委譲の方がクラス同士に幅を持たせることが容易であるため、デザインパターンではクラス継承よりも委譲がよく利用されています。
Adapterパターン、Bridgeパターン、Strategyパターンなど利用されており、その他にも利用されています。
今後機会があれば上記のような委譲を利用したデザインパターンをまとめていきたいと思います。

コメント

コメントを追加

user-symbol

Stay in touch

ビジネスおよび開発者向けの実用的な最新情報をご希望ですか?

ソースコードプロジェクトに対するPieceXコミュニティのニーズについてご提供します。

PieceXの最新の無料コミュニティコードプロジェクトをいち早くお知らせします。