Modèles de conception Le modèle d'adaptateur

Dans le dernier article, nous avons examiné comment le modèle de conception de façade peut être utilisé pour simplifier l’emploi de tout système de grande taille et complexe en utilisant seulement une classe de façade simple.. 

Dans cet article, nous poursuivrons notre discussion sur les modèles de conception en jetant un œil à la modèle de conception de l'adaptateur. Ce modèle particulier peut être utilisé lorsque votre code dépend d'une API externe ou de toute autre classe susceptible de changer fréquemment. Ce modèle entre dans la catégorie des "modèles structurels" car il nous enseigne comment structurer notre code et nos classes afin de les gérer et / ou les étendre facilement..

Encore une fois, j'aimerais réitérer que les modèles de conception n'ont rien de nouveau par rapport aux classes traditionnelles. Au lieu de cela, ils nous montrent un meilleur moyen de structurer nos classes, de gérer leur comportement et de gérer leur création..

Le problème

sendPayment ('2629');

Dans le code ci-dessus, vous pouvez voir que nous utilisons une classe PayPal pour simplement payer le montant. Ici, nous créons directement l'objet de la classe PayPal et payons via PayPal. Vous avez ce code dispersé dans plusieurs endroits. Nous pouvons donc voir que le code utilise le $ paypal-> sendPayment ('montant ici'); méthode de paiement. 

Il y a quelque temps, PayPal a changé le nom de la méthode de l'API de envoyer le paiement à montant du paiement. Cela devrait clairement indiquer un problème pour ceux d’entre nous qui ont utilisé le envoyer le paiement méthode. Plus précisément, nous devons changer tout envoyer le paiement appels de méthode à montant du paiement. Imaginez la quantité de code à modifier et le temps nécessaire pour tester à nouveau chacune des fonctionnalités..

La solution

Une solution à ce problème consiste à utiliser le modèle de conception de l'adaptateur.. 

Selon Wikipedia:

En ingénierie logicielle, le modèle d'adaptateur est un modèle de conception logicielle qui permet d'utiliser l'interface d'une classe existante à partir d'une autre interface. Il est souvent utilisé pour faire en sorte que les classes existantes fonctionnent avec d'autres sans modifier leur code source..

Dans ce cas, nous devrions créer une interface de wrapper qui rend cela possible. Nous n'apporterons aucune modification à la bibliothèque de classes externe car nous n'avons aucun contrôle sur celle-ci et cela peut changer à tout moment.. 

Entrons maintenant dans le code, qui montre le modèle d'adaptateur en action:

// Mise en œuvre concrète de la classe PayPal Classe PayPal fonction publique __construct () // votre code ici // fonction publique sendPayment ($ montant) // Paiement via Paypal // echo "Paiement via PayPal:". $ montant;  // Interface simple pour chaque adaptateur, nous créons une interface paymentAdapter public function pay ($ montant);  La classe paypalAdapter implémente paymentAdapter private $ paypal; fonction publique __construct (PayPal $ paypal) $ this-> paypal = $ paypal;  fonction publique paye ($ montant) $ this-> paypal-> sendPayment ($ montant); 

Étudiez le code ci-dessus et vous devriez être en mesure de dire que nous n’avons introduit aucun changement dans le menu principal. Pay Pal classe. Au lieu de cela, nous avons créé une interface pour notre adaptateur de paiement et une classe d'adaptateur pour PayPal..

Et ainsi après nous avons fait l'objet de la classe adaptateur au lieu de la principale Pay Pal classe. En créant un objet de classe adaptateur, nous allons passer l’objet de la classe principale Pay Pal classe comme argument, de sorte que la classe adaptateur puisse avoir une référence à la classe principale et appeler les méthodes requises du principal Pay Pal classe.

Voyons comment nous pouvons utiliser cette méthode directement:

// Code client $ paypal = new paypalAdapter (new PayPal ()); $ paypal-> pay ('2629');

Maintenant, imaginez que PayPal change son nom de méthode de envoyer le paiement à payer. Ensuite, nous devons juste apporter des modifications dans paypalAdapter. Il suffit de jeter un coup d'œil au code de l'adaptateur révisé, qui ne comporte qu'un changement..

La classe paypalAdapter implémente paymentAdapter private $ paypal; fonction publique __construct (PayPal $ paypal) $ this-> paypal = $ paypal;  fonction publique paye ($ montant) $ this-> paypal-> payAmount ($ montant); 

Donc, juste un changement et nous sommes là.

Ajout d'un nouvel adaptateur

À ce stade, nous avons vu comment nous pouvons utiliser le schéma de conception d’adaptateur pour surmonter les scénarios susmentionnés. Maintenant, il est très facile d'ajouter une nouvelle classe dépendant de l'adaptateur existant. Disons que l'API MoneyBooker est là pour le paiement.

Ensuite, au lieu d'utiliser directement la classe MoneyBooker, nous devrions appliquer le même modèle d'adaptateur que nous venons d'utiliser pour PayPal..

// Mise en œuvre concrète de la classe MoneyBooker, classe MoneyBooker fonction publique __construct () // votre code ici // fonction publique doPayment ($ montant) // Paiement via MoneyBooker // echo "Paiement via MoneyBooker:". $ montant;  // Classe Moneybooker Adapter moneybookerAdapter implémente paymentAdapter private $ moneybooker; fonction publique __construct (Moneybooker $ moneybooker) $ this-> moneybooker = $ moneybooker;  fonction publique paye ($ montant) $ this-> moneybooker-> doPayment (montant $);  // Code client $ moneybooker = new moneybookerAdapter (new MoneyBooker ()); $ moneybooker-> pay ('2629');

Comme vous pouvez le constater, les mêmes principes s'appliquent. Vous définissez une méthode disponible pour les classes tierces, puis, si une dépendance change son API, vous modifiez simplement la classe dépendante sans exposer son interface externe..

Conclusion

Une excellente application est constamment connectée à d'autres bibliothèques et API. Je propose donc d'implémenter la méthode de l'adaptateur afin d'éviter tout problème lorsqu'une API ou une bibliothèque tierce modifie son code..

J'ai essayé de mon mieux pour fournir un exemple élémentaire et utile pour illustrer le modèle de conception de l'adaptateur, mais si vous avez des commentaires ou des questions supplémentaires, n'hésitez pas à les ajouter dans le fil ci-dessous..