委譲パターンはソフトウェア設計パターンにおける基本的なテクニックの一つです。委譲パターンでは、2つのオブジェクトが同じリクエストの処理に関与し、リクエストを受け取ったオブジェクトがリクエストを別のオブジェクトに委譲して処理します。委譲パターンは基本的なテクニックであり、状態パターン、ストラテジーパターン、ビジターパターンなど多くの他のパターンは、本質的により特殊な場面で委譲パターンを採用しています。委譲パターンにより、継承の代わりに集約を使用することができ、またミックスイン(mixin)をシミュレートすることもできます。
簡単なJavaの例
この例では、プリンターを模したクラスPrinterがドットインパクトプリンターRealPrinterのインスタンスを持ち、Printerが持つメソッドprint()は処理をRealPrinterのメソッドprint()に委譲します。
class RealPrinter { // the "delegate"
void print() {
System.out.print("something");
}
}
class Printer { // the "delegator"
RealPrinter p = new RealPrinter(); // create the delegate
void print() {
p.print(); // delegation
}
}
public class Main {
// to the outside world it looks like Printer actually prints.
public static void main(String[] args) {
Printer printer = new Printer();
printer.print();
}
}
複雑なJavaの例
インターフェースを使用することで、委譲は型安全でより柔軟になります。この例では、クラスCはクラスAまたはクラスBに委譲でき、クラスCはクラスAとクラスBの間で選択できるようにするメソッドを持っています。クラスAまたはクラスBはインターフェースIで規定されたメソッドを実装する必要があるため、ここでの委譲は型安全です。この例は、委譲の欠点がより多くのコードを必要とすることを示しています。
interface I {
void f();
void g();
}
class A implements I {
public void f() { System.out.println("A: doing f()"); }
public void g() { System.out.println("A: doing g()"); }
}
class B implements I {
public void f() { System.out.println("B: doing f()"); }
public void g() { System.out.println("B: doing g()"); }
}
class C implements I {
// delegation
I i = new A();
public void f() { i.f(); }
public void g() { i.g(); }
// normal attributes
public void toA() { i = new A(); }
public void toB() { i = new B(); }
}
public class Main {
public static void main(String[] args) {
C c = new C();
c.f(); // output: A: doing f()
c.g(); // output: A: doing g()
c.toB();
c.f(); // output: B: doing f()
c.g(); // output: B: doing g()
}
}
出典:https://zh.wikipedia.org/wiki/%E5%A7%94%E6%89%98%E6%A8%A1%E5%BC%8F