Le modèle d'adaptateur est principalement utilisé pour convertir l'interface d'une classe dans le format de classe cible souhaité par le client, afin que les classes initialement incompatibles puissent fonctionner ensemble et se convertir la classe cible Découplée de la classe adaptateur ; en même temps, elle est également conforme au « principe d'ouverture et de fermeture ». De nouvelles classes d'adaptateur peuvent être ajoutées sans modifier le code d'origine ; l'implémentation spécifique est encapsulée dans la classe d'adaptateur. classes Il est transparent et améliore la réutilisabilité de l'adaptateur, mais l'inconvénient est que le processus de mise en œuvre de remplacement de l'adaptateur est relativement compliqué.
Ainsi, le modèle d'adaptateur est plus adapté aux scénarios suivants :
(1) Le système doit utiliser des classes existantes et les interfaces de ces classes ne sont pas conformes aux interfaces du système.
(2) Lors de l'utilisation de composants tiers, la définition de l'interface du composant est différente de votre propre définition. Vous ne souhaitez pas modifier votre propre interface, mais vous devez utiliser les fonctions de l'interface du composant tiers.
Les deux exemples très frappants suivants illustrent bien ce qu'est le modèle d'adaptateur :
Le modèle d'adaptateur est principalement divisé en trois catégories : classe Adaptateur modèle, modèle d'adaptateur d'objet, modèle d'adaptateur d'interface.
1. Modèle d'adaptateur de classe :
Interface cible (Target) : l'interface attendue par les clients. La cible peut être une classe concrète ou abstraite, ou une interface.
Classe à adapter (Adaptee) : La classe à adapter ou la classe adaptatrice.
Adaptateur : convertit l'interface d'origine en interface cible en empaquetant un objet qui doit être adapté.
// 已存在的、具有特殊功能、但不符合我们既有的标准接口的类 class Adaptee { public void specificRequest() { System.out.println("被适配类具有 特殊功能..."); } } // 目标接口,或称为标准接口 interface Target { public void request(); } // 具体目标类,只提供普通功能 class ConcreteTarget implements Target { public void request() { System.out.println("普通类 具有 普通功能..."); } } // 适配器类,继承了被适配类,同时实现标准接口 class Adapter extends Adaptee implements Target{ public void request() { super.specificRequest(); } } // 测试类public class Client { public static void main(String[] args) { // 使用普通功能类 Target concreteTarget = new ConcreteTarget(); concreteTarget.request(); // 使用特殊功能类,即适配类 Target adapter = new Adapter(); adapter.request(); } }
Résultats d'exécution :
普通类 具有 普通功能... 被适配类具有 特殊功能...
2. Mode adaptateur d'objet :
// 适配器类,直接关联被适配类,同时实现标准接口 class Adapter implements Target{ // 直接关联被适配类 private Adaptee adaptee; // 可以通过构造函数传入具体需要适配的被适配类对象 public Adapter (Adaptee adaptee) { this.adaptee = adaptee; } public void request() { // 这里是使用委托的方式完成特殊功能 this.adaptee.specificRequest(); } } // 测试类 public class Client { public static void main(String[] args) { // 使用普通功能类 Target concreteTarget = new ConcreteTarget(); concreteTarget.request(); // 使用特殊功能类,即适配类, // 需要先创建一个被适配类的对象作为参数 Target adapter = new Adapter(new Adaptee()); adapter.request(); } }
Les résultats du test sont cohérents avec ce qui précède. D'après le diagramme de classes, nous savons également que ce qui doit être modifié est simplement la structure interne de la classe Adapter, c'est-à-dire que l'Adaptateur lui-même doit d'abord avoir un objet de la classe adaptée, puis déléguer des fonctions spéciales spécifiques à cet objet pour mise en œuvre. En utilisant le mode adaptateur d'objet, la classe Adapter (classe d'adaptation) peut s'adapter à plusieurs classes adaptées différentes en fonction de l'objet Adaptee entrant. Bien sûr, à ce stade, nous pouvons extraire une interface pour plusieurs classes adaptées ou classes abstraites. Il semble que le modèle d'adaptateur d'objet soit plus flexible.
3. Modèle d'adaptateur d'interface :
Parfois, il y a plusieurs méthodes abstraites dans une interface que nous écrivons. Lorsque nous écrivons la classe d'implémentation de l'interface, nous devons implémenter toutes les méthodes de l'interface, ce qui est évidemment parfois du gaspillage. . Parce que toutes les méthodes ne sont pas ce dont nous avons besoin, parfois seules certaines sont nécessaires. Afin de résoudre ce problème, nous introduisons le modèle d'adaptateur de l'interface, à l'aide d'une classe abstraite, qui implémente l'interface et implémente toutes les méthodes. et nous ne traitons pas de l'interface d'origine, mais entrons uniquement en contact avec la classe abstraite, nous écrivons donc une classe, héritons de la classe abstraite et réécrivons les méthodes dont nous avons besoin. Jetez un œil au diagramme de classes :
C'est facile à comprendre. Dans le développement réel, nous rencontrons souvent trop de méthodes définies dans cette interface, de sorte que parfois nous n'en avons pas toutes besoin dans certaines classes d'implémentation. Regardez le code :
public interface Sourceable { public void method1(); public void method2(); }
Classe abstraite Wrapper2 :
public abstract class Wrapper2 implements Sourceable{ public void method1(){} public void method2(){} } public class SourceSub1 extends Wrapper2 { public void method1(){ System.out.println("the sourceable interface's first Sub1!"); } } public class SourceSub2 extends Wrapper2 { public void method1(){ System.out.println("the sourceable interface's second Sub2!"); } }
public class WrapperTest { public static void main(String[] args) { Sourceable source1 = new SourceSub1(); Sourceable source2 = new SourceSub2(); source1.method1(); source1.method2(); source2.method1(); source2.method2(); } }
Résultat d'exécution :
the sourceable interface's first Sub1! the sourceable interface's second Sub2!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!