互換性のないさまざまなインターフェースを持つクラス(Adaptee役)に修正を加えることなく、
利用者が望むインターフェース(Target役)で利用できるようにAdapter役が変換します。
Adaptee役を包み込むような形になることからラッパー(Wrapper)と呼ぶこともあります。
Adapteeを継承するやり方と、インスタンスとして保持し、委譲するやり方があります。
継承によるAdapterパターン・・・・・Adapter中のメソッドからAdapteeのメソッドを呼ぶ |
委譲によるAdapterパターン・・・・・Adapter中にAdapteeインスタンスを作成し、インスタンスのメソッドを呼ぶ |
Target役のメソッドを使って仕事をする。
・Target(対象)
いま必要となっているメソッドを定めている。
・Adaptee(継承される、もしくは委譲される対象)
すでに用意されているメソッド。
・Adapter(Targetを実装し、メソッドの中身にはAdapteeの機能を継承か委譲により使う。)
Adapteeのメソッドを使ってTargetを満たすのがAdapter
-----------[継承によるAdapterの例]----------------
Adateeにあたるクラス。
このクラスのメソッドをラップする。
ファイル名:Banner.java
public class Banner {
private String string;
/*
コンストラクタ
*/
public Banner(String string) {
this.string = string;
}
/*
showWithParenメソッド
「()」ではさんで表示
*/
public void showWithParen() {
System.out.println("(" + string + ")");
}
/*
showWithAsterメソッド
「*」ではさんで表示
*/
public void showWithAster() {
System.out.println("*" + string + "*");
}
}
------------------------------------------------------
Targetにあたるクラス。
メインからどう使いたいかのインタフェース。
ファイル名:Print.java
public interface Print {
public abstract void printWeak();
public abstract void printStrong();
}
------------------------------------------------------
Adapterにあたるクラス。
Targetを実装し、メソッド実装には
スーパークラスのメソッドを使う。
ファイル名:PrintBanner.java
public class PrintBanner extends Banner implements Print {
public PrintBanner(String string) {
super(string);
}
public void printWeak() {
showWithParen();
}
public void printStrong() {
showWithAster();
}
}
※Bannerクラスを継承せずに、コンポジットにして
機能を持たせると「委譲」による実装になる。
-----------------------------------------------------
メインクラス。
Targetのインタフェース型に、
Adapterのインスタンスを保持して使用。
ファイル名:Main.java
public class Main {
public static void main(String[] args) {
Print p = new PrintBanner("Hello");
p.printWeak();
p.printStrong();
}
}
----------------
Adapteeにあたるクラスの機能の呼び出し方は
Adapterに継承して使うか、インスタンスとしてローカル変数に保持しメソッドを呼び出す委譲で行うか違いはあるけれど。
Targetにあたるクラスのインタフェースで、Adapteeにあたるクラスの機能を呼び出せればOKということですね。
だんだんクラス図を読めるようになってきました(*^-^*)
0 件のコメント:
コメントを投稿