1. 動機
- ソフトウェア システムでは、アプリケーション環境の変化により、「一部の既存のオブジェクト」を新しい環境に適用する必要が生じることがよくありますが、新しい環境のインターフェイスはこれらの既存のオブジェクトでは満足されません。
- この「移住の変化」にどう対処するのか?既存のオブジェクトの優れた実装を使用するだけでなく、新しいアプリケーション環境に必要なインターフェイスを満たすにはどうすればよいでしょうか?
2. 私たちの周りにあるアダプター
3. スキーマ定義
クラスのインターフェースをクライアントが望む別のインターフェースに変換します。アダプター パターンを使用すると、インターフェイスに互換性がないために連携できないクラスが連携できるようになります。
-----《デザインパターン》GOF
4. 構造
上図の Target は必要なインターフェイスであり、Adaptee は過去のインターフェイスです。
5. コード例
// 新接口
class ITarget{
public:
virtual void Process() = 0;
};
// 老接口
class IAdaptee{
public:
virtual void foo(int data) = 0;
virtual int bar() = 0;
};
class OldClass : public IAdaptee{
virtual void foo(int data){
// ...
}
virtual int bar(){
// ...
}
};
// 由于某种内在某种功能可复用和关联性,可以将IAdaptee转成ITarget,如果毫无关联,是没有适配的意义的。
class Adapter : public ITarget{
protected:
IAdaptee *pAdaptee;
public:
Adapter(IAdaptee *pAdaptee){
this->pAdaptee = pAdaptee;
}
virtual void Process(){
// ...这个转换过程可能没有那么简单,会很复杂
int res = pAdaptee->bar();
pAdaptee->foo(res);
// ...
}
};
// 用一个旧的类,塞到Adapter里面,当做一个面向一个新接口来使用
void main(){
IAdaptee *pAdaptee = new OldClass();
ITarget *pTarget = new Adapter(pAdaptee);
pTarget->Process();
}
6. まとめ
- アダプターモードは主に「既存のクラスを再利用したいが、インターフェースが再利用環境と一致しない状況」で使用され、レガシーコードの再利用やクラスライブラリの移行といった面で非常に役立ちます。
- GOF 23 は、アダプター パターンの 2 つの実装構造、オブジェクト アダプターとクラス アダプターを定義します。ただし、クラス アダプタでは、一般的に推奨されない「多重継承」実装方法が使用されています。オブジェクト アダプターは、疎結合の精神により近い「オブジェクト合成」の方法を採用しています。
- アダプター モードは、Gof 23 で定義されている 2 つの構造に固執することなく、非常に柔軟に実装できます。たとえば、適応の目的を達成するために、アダプター モードで「既存のオブジェクト」を新しいインターフェイス メソッドのパラメーターとして使用することは完全に可能です。