委譲

[id:soutaro:20050903:1125679890]
委譲って、こういうやつですよね。

class Printer {
    Writer writer;
    void write(String s) {
        writer.write(s);
    }
    ...
}

class Writer {
    void write(String s) {
        ...
    }
}

これは、私もやらないですね。下のように書けばいいと思いますから。

printer.writer.write("hello!");

でも、逆に、これでいいと思うので、下のようなコードは、書きたくないかも。なぜって、こういう風に書かれたコードは、すぐに見通しが悪くなって、メンテナンスしにくくなるからなんです。自分だけで開発が閉じていれば、たいした問題に感じないですけど、他人が書いたコードを読んでいると、かなり読みにくく感じます。特に、ドキュメントがない(少ない)と、ソースに対してgrepをかけまくることになりがちです。

class Printer extends Writer {
    ....
}

もし、PrinterとWriterを同じ型のオブジェクトとして使いたいなら、初めて上のパターンが選択肢として浮上しますけど、これよりも、インターフェースを使った下の形式の方がずっとよいと思います。そして、ここで初めて、委譲を使う可能性が出てくるのだと思います。

interface WriterIntf {
    void write(String s);
}

class Writer implements WriterIntf {
    void write(String s) {
        ....
    }
}

class Printer implements WriterIntf {
    void write(String s) {
        ....
    }
}
      • -

他に、委譲を使う可能性といえば、メソッド名を変えたいときや、一部の実装だけを利用したときや、ユーティリティオブジェクトを利用する場合なんかがあるのかな。でも、そういうのは、たいてい丸投げではないので、いわゆる「委譲」というのとはちょっと違うのかも。ただ、そういう目的のために、「継承」を使っているコードは見るので、対立概念として「委譲」といってもいいかも。