Adapter パターン (互換性のないインタフェースを持つクラス同士の接続を可能にする)

[Adapter] という英単語は, [適合させるもの] という意味.

互換性のないインタフェースを持つメソッド間の相違を, 埋めるような (適合させる) パターンが, [Adapter パターン] である. つまり, [Adapter パターン] は, ある任意の機能のインタフェースを変更することなく, 他クラスが提供している新しい機能を使用できるようにするパターン.

このパターンには, 以下の2つの実装方法がある:

1. 継承 (is a 関係)
2. 委譲 (has a 関係)

役割

  1. Client (利用者):
[Target] のメソッドを利用して処理を行う.
  1. Target (対象):
要求されているメソッド (インタフェース) を定める.
  1. Adaptee (適合される側):
既存のメソッドを提供する. このメソッドの機能を [Target] のインタフェースに適合させ利用する.
  1. Adapter (適合させる):

[Adaptee] のメソッドのインタフェースを吸収し, [Target] から利用できるインタフェースに変換する. 実装方法としては, 以下の 2 通りある. 1). [Target] が interface で定義されている場合: [Adaptee] を継承する方法 (1. 継承を利用した方法) で実装する.

2). [Target] が [abstract class] で定義されている場合: [Adaptee] に委譲する方法 (2. 委譲を利用した方法) で実装する.

クラス図

Adapter パターンのクラス図

  1. 継承 (is a 関係) を利用した方法
_images/designpattern-adapter013.gif
  1. 委譲 (has a 関係) を利用した方法
_images/designpattern-adapter023.gif

ソースコード

  1. 継承 (is a 関係) を利用した方法: [Target] がインタフェースとして提供されている場合
  1. Client.java
1
2
3
4
5
6
7
public class Client{
    public static void main(String[] args){
	Target target = new Adapter();
	target.targetMethod1();
	target.targetMethod2();
    }
}
  1. Target.java
1
2
3
4
public interface Target{
    public abstract void targetMethod1();
    public abstract void targetMethod2();
}
  1. Adaptee.java
1
2
3
4
5
6
7
8
9
public class Adaptee{
    public void method1(){
	System.out.println("method1");
    }

    public void method2(){
	System.out.println("method2");
    }
}
  1. Adapter.java
1
2
3
4
5
6
7
8
9
public class Adapter extends Adaptee implements Target{
    public void targetMethod1(){
	method1();
    }

    public void targetMethod2(){
	method2();
    }
}
  1. 委譲 (has a 関係) を利用した方法: [Target] が抽象クラスとして提供されている場合
  1. Client.java ([1.継承] と同様)
1
2
3
4
5
6
7
public class Client{
    public static void main(String[] args){
	Target target = new Adapter();
	target.targetMethod1();
	target.targetMethod2();
    }
}
  1. Target.java
1
2
3
4
public abstract class Target{
    public abstract void targetMethod1();
    public abstract void targetMethod2();
}
  1. Adaptee.java ([1.継承] と同様)
1
2
3
4
5
6
7
8
9
public class Adaptee{
    public void method1(){
	System.out.println("method1");
    }

    public void method2(){
	System.out.println("method2");
    }
}
  1. Adapter.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class Adapter extends Target{
    private Adaptee adaptee;

    public Adapter(){
	this.adaptee = new Adaptee();
    }

    public void targetMethod1(){
	adaptee.method1();
    }

    public void targetMethod2(){
	adaptee.method2();
    }
}

実行結果

1). 継承を利用した方法:

[wtopia is_a]$ java Client

method1
method2

2). 委譲を利用した方法:

[wtopia has_a]$ java Client

method1
method2