Adapter
あるクラスのインターフェースを、そのクラスを利用する側が求める他のインターフェースへ変換するパターン
- インターフェースに互換性のないクラス同士を組み合わせることができる
- ClientからはTargetインターフェースしか見えなくなり、その先にある処理の実装を気にする必要がなくなる
メリット・デメリット
メリット
- 既存のクラス(Adapted)を修正しないので再テストが不要になる
- 変換のためのコードをプログラムのビジネスロジックと分離できるので単一責任の原則に違反しない
- インターフェースを介してアダプタと連携するのでオープンクローズドの原則に違反しない
デメリット
- インターフェースやクラスが増えるので、小さなシステムなどではAdapteeを直接修正した方がいい場合もある
デザインパターンの種類
構造に関するデザインパターン
例(Mermaid)
例1
Client- あるクラスの機能を「利用する」側のクラス
Target- クライアントが必要とする機能のAPIを定義するインターフェース
Adaptee- 「利用される」側のクラス
- クライアントクラスと互換性がない
AdapterTargetを実装するクラスAdapteeを継承する子クラスTargetのAPIを実装して、Adapteeの機能をClientが利用できるようにする
この場合AdapterクラスはAdapteeクラスを継承してAdapteeクラスを隠蔽する
classDiagram class Client { } class Target { <<interface>> targetMethod1() targetMethod2() } class Adapter { targetMethod1() targetMethod2() } class Adaptee { methodA() methodB() methodC() } Target <-- Client Target <|-- Adapter Adaptee <|-- Adapter
例2
- Adapterが自分のフィールドにAdapteeクラスのインスタンスを持っておきAdapteeの処理を呼び出す方法
- この場合処理はAdapteeのインスタンスに「移譲」するという
classDiagram class Client { } class Target { <<interface>> targetMethod1() targetMethod2() } class Adapter { adaptee: Adaptee targetMethod1() targetMethod2() } class Adaptee { methodA() methodB() methodC() } Target <-- Client Target <|-- Adapter Adaptee <--o Adapter