2.1 Adaptateur

Adapter (Adapter) est un modèle de conception structurelle conçu pour organiser l'utilisation des fonctions d'un objet qui n'est pas disponible pour modification via une interface spécialement créée.

La définition officielle est un peu délicate, mais si vous la décrivez avec vos propres mots, un adaptateur est un modèle de conception qui permet à des objets avec des interfaces incompatibles de fonctionner ensemble .

modèle d'adaptateur

Permet d'organiser l'utilisation des fonctions d'un objet non modifiable via une interface spécialement créée. Une classe supplémentaire est créée qui a l'interface requise, et cette classe appelle à son tour les méthodes de l'objet souhaité (qui n'a pas l'interface requise).

Important! Si dans le code vous rencontrez le suffixe Adapter pour une classe, alors vous avez tout à fait le droit de considérer que cette classe agit comme un adaptateur et est associée à un groupe de classes qui fonctionnent selon le schéma décrit ci-dessus.

Il est utilisé dans les cas où le système prend en charge les données et le comportement requis, mais possède une interface inappropriée. L'utilisation la plus courante du modèle Adapter est lorsque vous souhaitez créer une classe qui hérite d'une classe abstraite nouvelle ou existante.

Forces:

  • La transition vers l'utilisation d'autres classes externes ne nécessite pas de retravailler le système lui-même, il suffit d'implémenter une classe Adapter supplémentaire.
  • Indépendance vis-à-vis de l'implémentation de classes externes (classes issues de bibliothèques dont nous ne pouvons pas modifier le code). Votre programme devient indépendant de l'interface des classes externes.

2.2 Décorateurs

Decorator est un modèle de conception structurelle permettant d'attacher dynamiquement un comportement supplémentaire à un objet. Le pattern Decorator offre une bonne alternative flexible à la pratique des sous-classes pour étendre les fonctionnalités.

Motif décorateur

Utilisé pour connecter dynamiquement des obligations supplémentaires à un objet.

Beaucoup d'entre vous se demanderont : comment pouvez-vous dynamiquement (pendant que le programme tourne) ajouter un nouveau comportement à un objet ? Un objet peut être assemblé à partir de morceaux, c'est-à-dire de petits objets. Vous vous souvenez des chaînes de filtrage dans les servlets ? Ou l'API Stream lorsque vous avez écrit une requête en utilisant filter(), map(), list() ?

IntStream.of(50, 60, 70, 80, 90).filter(x -> x < 90).map(x -> x + 10).limit(3).forEach(System.out::print);

Points forts du motif Decorator :

  • Il n'est pas nécessaire de créer des sous-classes pour étendre les fonctionnalités d'un objet.
  • La possibilité de connecter dynamiquement de nouvelles fonctionnalités n'importe où : avant ou après la fonctionnalité principale de l'objet ConcreteComponent.

2.3 Procurations

Le proxy est un modèle de conception structurel qui fournit un objet qui contrôle l'accès à un autre objet, interceptant et passant par tous ses appels.

Adjoint (Procuration)

Le modèle Proxy fournit un objet de substitution à la place de l'objet réel. Cet objet contrôle l'accès à l'objet d'origine. Utilisé très souvent.

Rappelez-vous comment nous avons utilisé le framework Mockito et intercepté un appel à un objet réel à l'aide de la méthode Mockito.spy() ou de l'annotation @Spy ? C'est alors qu'un objet Proxy spécial a été créé, par lequel tous les appels à l'objet d'origine passaient.

Et puis nous pourrions gérer ces appels en ajoutant des règles à l'objet. C'est vrai - l'objet d'origine ne change pas et son utilisation devient beaucoup plus flexible. C'est particulièrement utile lorsque nous n'appelons pas l'objet proxy à partir de notre code, mais le passons quelque part. Contrôler ainsi la communication de deux objets indépendants de nous.

Types de procurations par objectif :

  • Proxy de journalisation : journalise tous les appels au « Sujet » avec leurs paramètres.
  • Proxy distant (remote proxies) : assure la communication avec le « Sujet », qui se trouve dans un espace d'adressage différent ou sur une machine distante. Il peut également être chargé d'encoder la requête et ses arguments et d'envoyer la requête encodée au véritable "Sujet".
  • Proxy virtuel (proxies virtuels) : garantit que le véritable "Sujet" n'est créé que lorsqu'il est vraiment nécessaire. Il peut également mettre en cache certaines des informations sur le véritable "sujet" pour retarder sa création.
  • Copy-on-write : Fournit une copie du "sujet" lorsque le client effectue certaines actions (cas particulier du "proxy virtuel").
  • Proxies de protection : Peut vérifier si l'appelant a les autorisations nécessaires pour faire la demande.
  • Caching Proxy : Fournit un stockage temporaire des résultats de calcul avant de les servir à plusieurs clients qui peuvent partager les résultats.
  • Screening Proxy : Protège le "Sujet" des clients dangereux (ou vice versa).
  • Proxy de synchronisation : effectue un contrôle d'accès synchronisé au "Sujet" dans un environnement multi-thread asynchrone.
  • Lien « intelligent » (proxy de référence intelligent) : effectue des actions supplémentaires lorsqu'un lien vers le « Sujet » est créé, par exemple, calcule le nombre de liens actifs vers le « Sujet ».

2.4 Pont

Le modèle Bridge est un modèle de conception structurelle utilisé pour "séparer l'abstraction et l'implémentation afin qu'elles puissent changer indépendamment".

Le modèle de pont utilise l'encapsulation, l'agrégation et peut utiliser l'héritage pour partager la responsabilité entre les classes.

Pont

Lorsque l'abstraction et l'implémentation sont séparées, elles peuvent changer indépendamment. En d'autres termes, lorsqu'elle est implémentée via le modèle de pont, la modification de la structure de l'interface n'interfère pas avec la modification de la structure de l'implémentation.

Considérez une telle abstraction comme une figure. Il existe de nombreux types de formes, chacune avec ses propres propriétés et méthodes. Cependant, il y a quelque chose qui unit toutes les figures. Par exemple, chaque forme doit pouvoir se dessiner, se mettre à l'échelle, etc.

Dans le même temps, les graphiques de dessin peuvent différer selon le type de système d'exploitation ou de bibliothèque graphique. Les formes doivent pouvoir se dessiner dans divers environnements graphiques. Mais il n'est pas pratique d'implémenter toutes les méthodes de dessin dans chaque forme, ou de modifier la forme chaque fois que la méthode de dessin change.

Dans ce cas, le modèle de pont aide, vous permettant de créer de nouvelles classes qui implémenteront le dessin dans divers environnements graphiques. En utilisant cette approche, il est très facile d'ajouter à la fois de nouvelles formes et des façons de les dessiner.

La connexion représentée par la flèche dans les schémas peut avoir 2 sens : a) « un genre », conformément au principe de substitution de Liskov, et b) une des implémentations possibles de l'abstraction. Les langages utilisent généralement l'héritage pour implémenter à la fois a) et b), ce qui a tendance à gonfler les hiérarchies de classes.

Le pont sert justement à résoudre ce problème : les objets sont créés par paires à partir d'un objet d'une classe de hiérarchie A et de hiérarchie B, l'héritage au sein de la hiérarchie A a le sens de « variété » selon Liskov, et pour le concept de « mise en œuvre d'abstraction », un lien de l'objet A vers son objet apparié B est utilisé.

2.5 Façade

Le modèle Facade est un modèle de conception structurelle qui masque la complexité d'un système en réduisant tous les appels externes possibles à un seul objet qui les délègue aux objets appropriés du système.

Gabarit de façade

Comment fournir une interface unifiée avec un ensemble d'implémentations ou d'interfaces disparates, par exemple, à un sous-système, si un couplage fort à ce sous-système n'est pas souhaitable, ou si l'implémentation du sous-système peut changer ?

Définissez un point d'interaction avec le sous-système - un objet de façade qui fournit une interface commune avec le sous-système et attribuez-lui la responsabilité d'interagir avec ses composants. Une façade est un objet externe qui fournit un point d'entrée unique pour les services du sous-système.

L'implémentation des autres composants du sous-système est privée et non visible pour les composants externes. L'objet façade fournit une implémentation du modèle GRASP résistant aux changements en termes de protection contre les changements dans l'implémentation du sous-système.

Important! Ce modèle est utilisé lorsque nous voulons masquer complètement un groupe d'objets et faire passer toutes les communications avec eux via notre objet. Si vous souhaitez simplement fournir un certain contrôle sur le processus de communication des objets et ne pas nécessairement les masquer, il est préférable d'utiliser le modèle Proxy.