転送(Forwarding)と委譲(Delegation)の違いは何か?

「転送」と「委譲」の違い

オブジェクト指向プログラミングにおいて、「転送」と「委譲」は混同されがちである。

送信側(ラッパー)と受信側(ラッピー)の2つのオブジェクトがあり、ラッパーのある関数が呼び出された時、ラッピーのある関数を呼び出す、という点では両者とも共通している。

違いは「ラッピーの関数を呼び出した時、関数の内部でラッパーとラッピーのどちらを参照するか」という点である。

例えば、クラスOuter(ラッパー)のexec関数が呼ばれた時、関数の内部処理で、クラスInner(ラッピー)のexec関数を呼ぶような場合、次のようになる。

転送

class Inner {
    func exec() {
        this.bomb()
    }
    func bomb() {
        print("inner bomb")
    }
}

class Outer {
    func Outer(Inner inner) {
        this.inner = inner
    }
    func exec() {
        this.inner.exec()
    }
    func bomb() {
        print("outer bomb")
    }
}

outer = new Outer(new Inner())
outer.exec()

// "inner bomb"

ラッピー(Inner)のexec関数を呼び出した時、関数の内部でラッピー(Inner)のbomb関数を参照している。

委譲

class Inner {
    func exec() {
        this.bomb()
    }
    func bomb() {
        print("inner bomb")
    }
}

class Outer {
    func Outer(Inner inner) {
        this.inner = inner
    }
    func exec() {
        this.inner.exec()
    }
    func bomb() {
        print("outer bomb")
    }
}

outer = new Outer(new Inner())
outer.exec()

// "outer bomb"

ラッピー(Inner)のexec関数を呼び出した時、関数の内部でラッパー(Outer)のbomb関数を参照している。