この記事では主に Java 設計パターンのアダプター パターン ノートを詳しく紹介します。興味のある方は参考にしてください。
アダプター パターン:
アダプター パターンはクラスを別のクラスに変換します。クライアントが期待するインターフェイスを使用できるようになり、インターフェイスの不一致により当初は連携できなかった 2 つのクラスが連携できるようになります。
生活のシナリオ:
1. 220v をラップトップの使用に適した電圧に変換できるラップトップ電源アダプター。
2. デスクトップ PS/2 インターフェースのキーボードをラップトップの USB インターフェースに接続するには、USB および PS/2 インターフェース アダプターが必要です。このとき、USB および PS/2 インターフェース アダプターはアダプターとして機能します。のキャラクター。
一般的なクラス図:
上記の一般的なクラス図では、Cient クラスは最終的に Target インターフェイス (または抽象クラス) に面しており、このターゲット クラスを満たすサブクラスのみを使用できます。 ; そして、Adapte クラスは、特定の (特別な) 操作、関数などが含まれるため、適応されたオブジェクト (ソース ロールとも呼ばれます) であるため、これを独自のシステムで使用し、それを許可する標準クラスに変換したいと考えています。特別な関数を備えた ConcreteTarget クラスまたは Adaptee クラスの使用を透過的に選択するクライアント クラス。
アダプター パターンでの役割:
ターゲット インターフェイス (Target): 顧客が期待するインターフェイス。ターゲットは、具体クラス、抽象クラス、またはインターフェイスにすることができます。
適応する必要があるクラス (Adaptee): 適応する必要があるインターフェイスまたは適応クラス。
アダプター: アダプター クラスはこのパターンの中核です。アダプターは、適応する必要があるオブジェクトをラップすることによって、ソース インターフェイスをターゲット インターフェイスに変換します。明らかに、このロールはインターフェイスであってはならず、具象クラスでなければなりません。
アダプター パターンの構造:
アダプター パターンには、クラス アダプター パターンとオブジェクト アダプター パターンの 2 つの異なる形式があります。
クラスのアダプター パターンは、適応クラスの API をターゲット クラスの API に変換します。
オブジェクトアダプターパターンはクラスアダプターパターンと同じです。オブジェクトアダプターパターンは適応クラスのAPIをターゲットクラスのAPIに変換します。オブジェクトアダプターパターンは使用しない点です。 Adaptee クラスに接続するには継承関係を使用しますが、Adaptee クラスに接続するには委任関係を使用します。
クラスアダプターパターン
1. 適応されたクラスを作成します:
/** * 被适配的类 * 已存在的、具有特殊功能、但不符合我们既有的标准接口的类 * (相当于例子中的,PS/2键盘) * @author ChuanChen * */ public class Adaptee { public void specificRequest(){ System.out.println("可以完成客户请求的需要的功能!"); } }
2. いくつかの特別なリクエストを処理できるターゲットインターフェイスを作成します
/** * 目标接口,或称为标准接口 * @author ChuanChen * */ public interface Target { void handleReq(); }
3. アダプターを作成します (クラスアダプターメソッド)。
/** * 适配器 (类适配器方式) * (相当于usb和ps/2的转接器) * @author ChuanChen * */ public class Adapter extends Adaptee implements Target { @Override public void handleReq() { super.specificRequest(); } }
4. クライアントを作成します
/** * 客户端类 * (相当于例子中的笔记本,只有USB接口) * @author ChuanChen * */ public class Client { public void test(Target t){ t.handleReq(); } public static void main(String[] args) { Client c = new Client(); Adaptee a = new Adaptee(); Target t = new Adapter(); c.test(t); } }
上記で実装されたアダプターは、Adaptee (適応されたクラス) を継承するだけでなく、Target インターフェース (この方法で実装される) も実装するため、クラスアダプターと呼ばれます。 Java は多重継承をサポートしていないため)、Client クラスでは、特定の関数を実装するニーズを満たす任意のサブクラスを選択して作成できます。
オブジェクトのアダプター パターン
1. 適応されたクラスを作成します:
/** * 被适配的类 * 已存在的、具有特殊功能、但不符合我们既有的标准接口的类 * (相当于例子中的,PS/2键盘) * @author ChuanChen * */ public class Adaptee { public void specificRequest(){ System.out.println("可以完成客户请求的需要的功能!"); } }
2. いくつかの特別なリクエストを処理できるターゲット インターフェイスを作成します
/** * 目标接口,或称为标准接口 * @author ChuanChen * */ public interface Target { void handleReq(); }
3.適応されたオブジェクトと統合するための組み合わせメソッド)
/** * 适配器 (对象适配器方式,使用了组合的方式跟被适配对象整合) * (相当于usb和ps/2的转接器) * @author ChuanChen * */ public class Adapter implements Target{ private Adaptee adaptee; @Override public void handleReq() { adaptee.specificRequest(); } public Adapter(Adaptee adaptee) { super(); this.adaptee = adaptee; } }
4. クライアントを作成します
/** * 客户端类 * (相当于例子中的笔记本,只有USB接口) * @author ChuanChen * */ public class Client { public void test(Target t){ t.handleReq(); } public static void main(String[] args) { Client c = new Client(); Adaptee a = new Adaptee(); Target t = new Adapter(a); c.test(t); } }
Adapter クラスの内部構造を変更するだけです。つまり、Adapter 自体が最初に適応オブジェクト アダプテーション クラスのオブジェクト。その後、特定の特殊関数をこのオブジェクトに委任して実装します。オブジェクト アダプター モードを使用すると、アダプター クラス (適応クラス) は、受信した Adapte オブジェクトに基づいて複数の適応クラスに適応できます。もちろん、この時点で、複数の適応クラスまたは抽象クラスのインターフェイスを抽出できます。オブジェクトアダプターのパターンがより柔軟になっているようです。
クラス アダプターとオブジェクト アダプター間のトレードオフ:
クラス アダプターは静的な定義方法であるオブジェクトの継承を使用しますが、オブジェクト アダプターは動的な結合方法であるオブジェクトの組み合わせを使用します。
クラスアダプターの場合、アダプターは Adaptee を直接継承するため、アダプターは Adaptee のサブクラスを扱うことができません。これは、アダプターが Adaptee を継承する場合、 Adaptee のサブクラスを扱うことができないためです。
オブジェクト アダプターの場合、アダプターは複数の異なるソースを同じターゲットに適応させることができます。つまり、同じアダプターでソース クラスとそのサブクラスの両方をターゲット インターフェイスに適応させることができます。オブジェクトアダプタはオブジェクトの組み合わせの関係を利用するため、オブジェクトの型が正しければサブクラスかどうかは関係ありません。
クラスアダプターの場合、アダプターは Adaptee の動作の一部を再定義できます。これは、親クラスの一部の実装メソッドをサブクラスがオーバーライドするのと同等です。
オブジェクトアダプターの場合、Adaptee の動作を再定義するのは困難です。この場合、再定義を行うために Adaptee のサブクラスを定義し、アダプターにサブクラスを結合させる必要があります。 Adaptee の動作を再定義するのは困難ですが、いくつかの新しい動作を追加するのは非常に便利であり、新しく追加された動作はすべてのソースに同時に適用できます。
クラスアダプターの場合、オブジェクトは 1 つだけ導入され、間接的に Adapte を取得するために追加の参照は必要ありません。
オブジェクトアダプターの場合、Adapte を間接的に取得するには追加の参照が必要です。
可能な限りオブジェクト アダプターの実装を使用し、合成/集約を多く使用し、継承を少なくすることをお勧めします。もちろん、具体的な問題を詳細に分析し、ニーズに応じて最適な実装方法を選択する必要があります。
アダプター パターンの利点:
再利用性の向上:
システムは既存のクラスを使用する必要があり、このクラスのインターフェイスはシステムのニーズを満たしていません。そうすれば、アダプター モードを通じてこれらの関数をより適切に再利用できるようになります。
優れた拡張性:
アダプター機能を実装する際に、独自に開発した関数を呼び出すことで、システムの機能を自然に拡張できます。
アダプター モードの欠点
アダプターを過度に使用すると、システムが非常に乱雑になり、全体を把握するのが難しくなります。たとえば、インターフェイス A が呼び出されていることは明らかですが、実際にはインターフェイス B を実装するために内部的に調整されています。これがシステム内で頻繁に発生すると、それは災害に等しいことになります。したがって、必要がなければアダプタを使用せずに直接システムを再構築することも可能です。
アダプター パターンの動作シーン:
1. 既存のクラスのインターフェイスがニーズを満たしていない。
2. 他の無関係なクラスまたは予期せぬクラスと使用できるように、再利用可能なクラスを作成します。インターフェイスが必ずしも互換性があるとは限りません) 連携して動作します。
3. インターフェイスに合わせてそれぞれをサブクラス化せずに、いくつかの既存のサブクラスを使用します。
アダプター モードは、古いシステムの改造やアップグレードによく使用されます。開発後にシステムのメンテナンスがまったく必要ない場合、多くのパターンは不要です。しかし、残念ながら実際には、システムの維持コストは開発コストの数倍になることがよくあります。
以上がJava デザイン パターンのアダプター パターンの図の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。