Adapter(委譲)
Adapterパターンにおいて,継承ではなく,委譲(Delegation)を用いて設計する場合を見てみる.
委譲とは,権利や権限などを他の人に譲って任せることを意味している.Adapterパターンとしての委譲は,実際の処理を他のインスタンスに任せることを意味している.したがって,他のインスタンスの処理を実行しているにも関わらずあたかも,そのインスタンスを持っている自分が実行したかのように見せることができる.
これによって,他のインスタンスが実行した処理を利用して,その出力結果を変化させたり,他の処理を追加することができる.これによって,元の処理を拡張することができる.
クラス構造
異なるインターフェイスを変換するクラスが,変換元のクラスとどのような関係があるかという見方をすると,継承でなく,委譲という形をとることができる.
V1_5クラスは,1.5[V]を出力する抽象メソッドが定義されており,1.5[V]が出力されるように,サブクラスで実装することを求めている.
Tan3クラスは,単三電池を模したクラスで,単3電池から1.5[V]を出力するメソッドがある. 単三電池から,電池の種類に依存せずにoutput1_5()メソッドで1.5[V]を得られるようなDenchiAdapterクラスを想定して,インターフェイスを変換する.DenchiAdapterクラスは,Tan3クラスのフィールドdenchiをもち,denchiを介して,1.5[V]を得るようにする.
このような,実際の処理をほかのオブジェクトに任せてしまうことを,「委譲」とよぶ.
プログラム(委譲)
V1_5クラスのプログラムを以下に示す.このクラスは,output1_5()を実行すると1.5[V]が返されるメソッドのみが定義されている.このクラスを継承するサブクラスでは,このメソッドを実装する必要がある.
public abstract class V1_5 { public abstract double output1_5(); }
Tan3クラスのプログラムを示す.単三電池を模したクラスであり,tan3outputメソッドを実行することで,1.5[V]が得られる.
public class Tan3 { public double tan3output() { return 1.5; } }
DenchiAdapterクラスのプログラムを示す.このクラスでは,どのような単三電池で1.5[V]を得るAPIを,電池の型に関係なく1.5[V]を得るAPIに変換する.そのために,2つのことを行う,一つは,電源のもとになる単三電池をこのクラスに組み込むことである.もう一つは,組み込んだ電池を,提供すべきAPIに合わせることである.
まず,単三電池を組み込むために,Tan3クラスのフィールドを用意する.このアダプターをインスタンス化するときに,単三電池を入れることを想定して,引数に単三電池のインスタンスとり,DenchiAdapterクラスのフォールドに代入する.
次に,output1_5メソッドを実装する.このとき,フィールドに持っているTan3電池のメソッドを利用して,1.5[V]を返す.このような,他のクラスに処理を任せることを委譲と呼ぶ.すなわち,DenchiAdapterクラスで提供すべき処理をTan3クラスに委譲している.
public class DenchiAdapter extends V1_5 { private Tan3 denchi; DenchiAdapter(Tan3 denchi) { this.denchi = denchi; } @Override public double output1_5() { return denchi.tan3output(); } }
委譲を用いて変換したクラスをインスタンス化して,1.5[V]が得られる様子をためすためのMainクラスを示す.
public class Main { public static void main(String[] args) { Tan3 tan3denchi = new Tan3(); V1_5 v1_5denchi = new DenchiAdapter(tan3denchi); System.out.println(v1_5denchi.output1_5() + "[V]"); } }
演習(委譲)
(1)追加
tan4outputというAPIで1.5[V]が得られる単4電池クラスを変換して,output1_5というAPIで1.5[V]が得られるように,V1_5クラスを継承するAdapterパターンに則ったクラスを作成せよ.
(2)パターン全体を作成
水道と接続して,ミネラルウォーターを出せる浄水器を考える. 浄水器をアダプタークラスとしてとらえて,水道がミネラルウォーターに変わる様子を Adapterパターン(委譲,継承両方において)を用いて表わせ.