Modèle de conception | Modèle d'adaptateur

1 | Présentation du mode adaptateur

Pensons à un phénomène de la vie courante. La tension électrique de la vie de notre pays est de 220 V, mais la tension de fonctionnement réelle des téléphones portables, ordinateurs portables, téléviseurs et autres équipements n'est pas si élevée. Pour que ces équipements utilisent de l'électricité à vie de 220 V, il est nécessaire L'adaptateur secteur (AC Adpater) est également un chargeur ou un transformateur. Avec cet adaptateur secteur, les appareils électroménagers et autres équipements qui ne peuvent pas fonctionner directement peuvent être compatibles et utilisés, et l'adaptateur secteur fait office d'adaptateur.

De même dans le développement logiciel, ce genre d'incompatibilité similaire se produit parfois. Nous pouvons également introduire un rôle appelé adaptateur comme un adaptateur secteur pour coordonner ces structures incompatibles. Ce schéma de conception est le mode adaptateur. 

Semblable à l'adaptateur secteur, une classe d'emballage appelée Adapter est introduite dans le mode adaptateur, et l'objet qu'il encapsule s'appelle Adaptee, qui est la classe à adapter. La réalisation de l'adaptateur consiste à convertir la requête de la classe client en un appel à l'interface correspondante de l'adaptateur. C'est-à-dire: lorsque la classe client appelle la méthode de l'adaptateur, la méthode de la classe adaptateur sera appelée à l'intérieur de la classe adaptateur, et ce processus est transparent pour la classe client, et la classe client n'accède pas directement à l'adaptateur classer. Par conséquent, l'adaptateur permet aux classes qui ne peuvent pas interagir en raison d'interfaces incompatibles de fonctionner ensemble.

1.1 Définition du mode adaptateur

  • Modèle d'adaptateur : convertissez l'interface d'une classe en une autre interface souhaitée par le client. Le mode adaptateur permet aux classes avec des interfaces incompatibles de travailler ensemble.
  • Modèle d'adaptateur : convertissez l'interface d'une classe en une autre interface attendue par les clients. L'adaptateur permet aux casses de fonctionner ensemble, ce qui ne le serait pas autrement à cause des interfaces compatibles.

Le modèle d'adaptateur peut faire correspondre l'interface d'une classe avec l'interface d'une autre classe sans modifier l'interface d'adaptateur d'origine et la classe d'interface cible abstraite.

L'alias du modèle d'adaptateur est le modèle d'enveloppe , qui peut être utilisé comme modèle de structure de classe ou comme modèle de structure d'objet . L'interface mentionnée dans la définition du modèle d'adaptateur fait référence à une interface large, qui peut représenter une méthode ou un ensemble de méthodes.

2 | La structure et la mise en œuvre du modèle d'adaptateur

Le modèle d'adaptateur comprend l'adaptateur de classe et l'adaptateur d'objet. Dans le modèle d'adaptateur d'objet, il existe une relation d'association entre l'adaptateur et l'adaptateur; dans le modèle d'adaptateur de classe, l'adaptateur et l'adaptateur ont une relation d'héritage (ou de réalisation). Ce qui suit est une analyse structurelle des deux adaptateurs.

2.1 La structure du mode adaptateur

Le mode adaptateur contient les 3 rôles suivants

  • (1) Cible (classe abstraite cible): La classe abstraite cible définit l'interface requise par le client, qui peut être une classe ou une interface abstraite, ou une classe concrète. Dans l'adaptateur de classe, en raison de l'héritage unique de la fonctionnalité de langage C # et de plusieurs extensions d'interface.
  • (2) Adaptateur (classe d'adaptateur): il peut appeler une autre interface en tant que convertisseur pour adapter Adaptee et Target. L'adaptateur est le cœur du modèle d'adaptateur. Dans l'adaptateur de classe, il relie les deux en implémentant l'interface Target et en héritant de la classe Adaptee. Dans l'adaptateur d'objet, il relie les deux en héritant de Target et en associant un objet Adaptee.
  • (3) Adaptee (classe d'adaptateur): l'adaptateur est le rôle à adapter. Il définit une interface existante qui doit être adaptée. La classe d'adaptateur est généralement une classe spécifique et la phrase contient le client La méthode métier que vous souhaitez l'utilisation peut même ne pas avoir le code source de la classe d'adaptateur dans certains cas.

2.2 Implémentation du mode adaptateur

Étant donné que le mode adaptateur comprend deux formes de mode adaptateur de classe et de mode adaptateur d'objet, ce qui suit décrit les mécanismes d'implémentation de ces deux modes d'adaptateur.

2.2.1 Adaptateur de classe

Dans l'adaptateur de classe, la classe d'adaptateur Adaptee n'a pas de méthode Beavast () et le client attend cette méthode, mais la méthode SpecificRequest () est implémentée dans la classe d'adaptateur. L'implémentation fournie par cette méthode est exactement ce dont le client a besoin . Afin de permettre aux clients d'utiliser la classe d'adaptateur, une classe intermédiaire est fournie, à savoir la classe Adaptet. La classe d'adaptateur implémente l'interface de classe d'objet cible et hérite de la classe d'adaptateur. Dans le Reqpest () de la classe d'adaptateur, la méthode appelle la méthode SpecificRequest () de la classe d'adaptateur héritée pour atteindre l'objectif d'adaptation. Étant donné que la classe d'adaptateur et la classe d'adaptateur sont héritées , ce mode d'adaptateur est appelé le mode d'adaptateur de classe. Le code d'adaptateur de classe typique est le suivant:

interface ITarget
{
    string Request();
}

class Adaptee
{
    public string SpecificRequest() => "Adaptee.SpecificRequest";
}

class ClassAdapter : Adaptee, ITarget
{
    public string Request() => $"ClassAdapter.Request 调用 {base.SpecificRequest()}";
}

2.2.2 Adaptateur d'objet

Dans l'adaptateur d'objet, le client doit appeler la méthode Request (), tandis que la classe Adaptee n'a pas cette méthode mais la méthode SpecificRequest () qu'elle fournit est ce dont le client a besoin. Pour permettre au client d'utiliser la classe d'adaptateur, il est nécessaire de fournir une classe de wrapper Adapter, la classe d'adaptateur. Cette classe wrapper encapsule une instance d'un adaptateur pour connecter le client à l'adaptateur et appelle la méthode SpecificRequest () de l'adaptateur dans la méthode Request () de l'adaptateur. Étant donné que la classe d'adaptateur et la classe d'adaptateur sont dans une relation d'association (également appelée relation de délégation ), ce modèle d'adaptateur est appelé un modèle d'adaptateur d'objet. Le code d'adaptateur d'objet typique est le suivant:

class ObjectAdapter : ITarget
{
    private readonly Adaptee _Adaptee; //维持一个适配者对象的引用

    public ObjectAdapter(Adaptee adaptee)
    {
        _Adaptee = adaptee;
    }

    public string Request() => $"ObjectAdapter.Request 调用 {_Adaptee.SpecificRequest()}";
}

Le modèle d'adaptateur peut faire correspondre l'interface d'une classe avec l'interface d'une autre classe. Le principe de son utilisation est que vous ne pouvez pas ou ne voulez pas modifier l'interface d'adaptateur d'origine et l'interface de classe cible abstraite. Par exemple: certaines bibliothèques de classes ou contrôles tiers sont achetés, mais il n'y a pas de code source. À ce stade, le mode adaptateur peut être utilisé pour unifier l'interface d'accès aux objets.
Le modèle d'adaptateur met davantage l'accent sur l'organisation du code que sur la réalisation de la fonction. Dans le développement réel, la fréquence d'utilisation des adaptateurs d'objet est plus élevée.

Appel client

3 | Exemples d'application du modèle d'adaptateur

Conception de code

  1. ScoreOperation: une classe d'opération de partition abstraite qui sert d'interface cible.
  2. QuickSortClass: classe de tri rapide, agissant comme un adaptateur.
  3. BinarySearchClass: classe de recherche binaire, agissant comme une classe d'adaptation.
  4. Le fichier de configuration App.config stocke le nom de classe (nom complet) de la classe d'adaptateur dans le fichier de configuration.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="adapter" value="AdapterPattern.Sample.OperationAdapter"/>
  </appSettings>
</configuration>

Pour les détails du code ci-dessus, veuillez vérifier =》https://gitee.com/dolayout/DesignPatternOfCSharp/tree/master/DesignPatternOfCSharp/AdapterPattern

Appel client

4 | Mode adaptateur par défaut

Le mode adaptateur par défaut est une variante du mode adaptateur et son application est également plus répandue. Ce mode est également appelé mode adaptateur à interface unique .

4.1 Définition du mode d'adaptateur par défaut

  • Modèle d'adaptateur par défaut : lorsque vous n'avez pas besoin d'implémenter toutes les méthodes fournies par une interface, vous pouvez d'abord concevoir une classe abstraite pour implémenter l'interface, et fournir une implémentation par défaut (méthode vide) pour chaque méthode de l'interface, puis la sous-classe de cette classe abstraite peut remplacer sélectivement certaines méthodes de la classe parente pour satisfaire aux exigences. Elle convient aux situations dans lesquelles vous ne souhaitez pas utiliser toutes les méthodes d'une interface, également appelée mode d'adaptateur à interface unique.

4.2 Le mode d'adaptateur par défaut contient les 3 rôles suivants:

  • (1) IServiceInterface (interface de l'adaptateur) : C'est une interface, et généralement un grand nombre de méthodes sont déclarées dans l'interface.
  • (2) AbstractServiceClass (classe d'adaptateur par défaut) : C'est la classe principale du modèle d'adaptateur par défaut, qui implémente les méthodes déclarées dans l'interface ServiceInterface sous la forme de méthodes vides. Elle est généralement définie comme une classe abstraite, car il n'a aucun sens de l'instancier.
  • (3) ConcreteServiceClass (classe de service spécifique) : il s'agit d'une sous-classe de la classe d'adaptateur par défaut. Avant l'introduction de l'adaptateur, il doit implémenter l'interface de l'adaptateur, il doit donc implémenter toutes les méthodes déclarées dans l'interface de l'adaptateur. Certaines méthodes qui n'ont pas besoin d'être utilisés doivent fournir des implémentations vides. Une fois l'adaptateur par défaut, vous pouvez hériter directement de la classe d'adaptateur et remplacer de manière sélective les méthodes définies dans la classe d'adaptateur si nécessaire.

Parmi eux, l'extrait de code typique de la classe d'adaptateur par défaut est le suivant:

interface IServiceInterface 
{
    void ServiceMethod1();
    void ServiceMethod2();
    void ServiceMethod3();
}

abstract class AbstractServiceClass : IServiceInterface
{
    public void ServiceMethod1() { } // 空方法
    public void ServiceMethod2() { }
    public void ServiceMethod3() { }
}

5 | Mode adaptateur bidirectionnel

Lors de l'utilisation de l'adaptateur d'objet, si l'adaptateur contient des références à la fois à la classe cible et à la classe d'adaptateur, l'adaptateur peut l'utiliser pour appeler des méthodes dans la classe cible, et la classe cible peut également appeler la classe d'adaptateur par son intermédiaire. Méthode , alors l'adaptateur est un adaptateur bidirectionnel.

L'implémentation de l'adaptateur bidirectionnel est plus compliquée et son code typique est le suivant:

class TwoWayApapter : Adaptee, ITarget
{
    // 同时维持抽象目标类和适配者的引用
    private readonly Adaptee _Adaptee;
    private readonly ITarget _Target;

    public TwoWayApapter(Adaptee adaptee) 
    {
        _Adaptee = adaptee;
    }

    public TwoWayApapter(ITarget target)
    {
        _Target = target;
    }

    public new string SpecificRequest() => _Target.Request();

    public string Request() => _Adaptee.SpecificRequest();

}

6 | Avantages et inconvénients du mode adaptateur et de l'environnement applicable

Le modèle d'adaptateur transforme l'interface existante en l'interface attendue par la classe client, et réalise la réutilisation de la classe existante.C'est un modèle de conception avec une fréquence d'utilisation très élevée et a été largement utilisé dans le développement de logiciels.

6.1 Avantages du mode adaptateur (à la fois le mode adaptateur d'objet et le mode adaptateur de classe)

  • (1) Découplez la classe cible et la classe d'adaptateur et réutilisez la classe d'adaptateur existante en introduisant une classe d'adaptateur sans modifier la structure d'origine.
  • (2) Augmentez la transparence et la réutilisabilité de la classe, encapsulez le processus de réalisation métier spécifique dans la classe d'adaptateur, qui est transparente pour la classe client, et améliore la réutilisabilité de l'adaptateur. La première est que la classe d'adaptateur peut être réutilisée dans plusieurs différents systèmes.
  • (3) La flexibilité et l'évolutivité sont très bonnes. Grâce à l'utilisation de fichiers de configuration, l'adaptateur peut être facilement remplacé et de nouvelles classes d'adaptateur peuvent être ajoutées sans modifier le code d'origine, qui est entièrement conforme aux principes d'ouverture et de fermeture.

Plus précisément, le modèle d'adaptateur de classe présente également les avantages suivants:

  • Étant donné que la classe d'adaptateur est une sous-classe de la classe d'adaptateur, certaines méthodes d'adaptateur peuvent être remplacées dans la classe d'adaptateur pour rendre l'adaptateur plus flexible.

Le mode adaptateur d'objet présente également les avantages suivants:

  • (1) Un adaptateur d'objet peut adapter plusieurs adaptateurs différents à la même cible.
  • (2) Le mode adaptateur d'objet peut s'adapter à une sous-classe d'adaptateur. Puisque l'adaptateur et l'adaptateur sont associés, selon le principe de substitution de Richter, la sous-classe de l'adaptateur peut également être adaptée via l'adaptateur.

6.2 Inconvénients
du mode adaptateur Les principaux inconvénients du mode adaptateur de classe sont les suivants:

  • (1) Pour les langages qui ne prennent pas en charge l'héritage de plusieurs classes, tels que C # et Java, au plus une classe d'adaptateur peut être adaptée à la fois, et plusieurs adaptateurs peuvent être adaptés en même temps.
  • (2) La classe adaptateur ne peut pas être la classe finale, par exemple, elle ne peut pas être la classe scellée en C #.
  • (3) Dans des langages tels que C # et Java, la classe abstraite cible dans le modèle d'adaptateur de classe ne peut être qu'une interface, pas une classe, et son utilisation présente certaines limitations.

Les principaux inconvénients du modèle d'adaptateur d'objet sont les suivants:

  • Par rapport au modèle d'adaptateur de classe, certaines méthodes de remplacement de la classe d'adaptateur dans l'adaptateur sont plus gênantes. Si vous devez remplacer une ou plusieurs méthodes de la classe d'adaptateur, vous pouvez d'abord créer une sous-classe de la classe d'adaptateur, supprimer la méthode de la classe d'adaptateur, puis traiter la sous-classe de la classe d'adaptateur comme réelle Le processus d'adaptation de l'adaptateur est plus compliqué.

6.3 Environnement applicable du mode adaptateur

  • (1) Le système doit utiliser certaines classes existantes, et les interfaces de ces classes (telles que les noms de méthodes) ne répondent pas aux besoins du système, et il n'y a même pas de code source pour ces classes.
  • (2) Créez une classe réutilisable pour travailler avec des classes qui ne sont pas très liées les unes aux autres, y compris les classes qui pourraient être introduites dans le futur.

 

Je suppose que tu aimes

Origine blog.csdn.net/ChaITSimpleLove/article/details/115056329
conseillé
Classement