Pensez à changer de branche pour suivre ce chapitre ; vous devez vous trouver sur la branche partie-3/chapitre-3-debut
.
Utilisez un Proxy Pattern pour mettre en place une solution de cache
Grande nouvelle ! On vient d’intégrer sur le projet Filmo Patterns un algorithme de tri dont le rôle sera de trier les films via leur date de sortie. Seulement voilà, l’algorithme est un peu long et prend à chaque fois une seconde pour trier les films. Voici l’issue qui a été créée spécialement pour l’occasion.
Si vous vous rendez sur le projet Filmo Patterns et que vous utilisez la fonction de tri par date de sortie, vous allez voir que chaque opération (en dehors de celle où il n’y a aucun tri) prend environ une seconde. C’est beaucoup trop long ! Nous allons mettre en place un système de cache avec un Proxy Pattern.
Un système de cache ?
Et quand est-ce qu’on se sert du cache ?
Tout le temps !
Quand vous allez sur un site web et que ce dernier charge les polices et les images du site en question. Ces données vont être mises en cache. Si vous rechargez le site, ces données seront récupérées de votre ordinateur et non du serveur.
Quand vous stockez des informations utilisateur, par exemple ses identifiants de connexion dans des cookies ou en LocalStorage, vous mettez en cache ces informations.
C’est pareil côté serveur ! Pour optimiser les performances des données, on se sert souvent d’outils type Redis ou Memcached.
Avant de passer à la définition et aux caractéristiques de ce design pattern, quelques informations concernant le code du projet :
Il y a un nouveau template :
js/templates/SorterForm
. C’est ce dernier qui affiche le formulaire de tri et qui appelle la librairie de tri.La librairie de tri est, quant à elle, située dans le dossier
lib/sorter/index.js
. On considère que c’est une librairie externe sur laquelle on n’a pas la main.J’ai aussi modifié un peu le CSS pour afficher les deux formulaires. :)
Identifiez les caractéristiques du Proxy Pattern
Un Proxy Pattern est composé des acteurs suivants :
Le Client : c’est la fonction ou l’objet qui va appeler le proxy. Dans notre cas, ce sera l’objet
js/templates/SorterForm.js
.Le Proxy qui va être l’objet chargé de faire la communication entre le client et le Sujet. Ici, ce sera l’objet
js/proxy/ProxyRatingSorter
.Le Sujet (ici RealSubject) qui va être l’objet appelé par le proxy. Dans notre cas, ce sera l’objet
lib/sorter/index.js
.
Mais du coup, un proxy, ça sert uniquement pour le cache ?
Excellente question !
En fait, un proxy est un composant logiciel qui joue le rôle d’intermédiaire entre deux hôtes pour faciliter ou surveiller leurs échanges. Un hôte peut être un objet (comme c’est le cas dans notre projet), mais cela peut aussi être un serveur informatique.
Donc, pour répondre à votre question, non, un proxy ne sert pas uniquement pour le cache. Dès lors qu’un objet est un peu complexe à manipuler, nous pouvons mettre en place un proxy pour faciliter sa manipulation.
L’avantage d’utiliser un Proxy Pattern pour la gestion du cache, c’est que nous allons avoir des gains de performance très importants :
Lors de la première requête auprès de notre librairie, le temps de réponse sera le même (1 seconde), sauf que nous allons stocker le résultat de la fonction dans notre proxy.
Lors de la deuxième requête, le proxy va regarder si le résultat de la fonction a été stocké (ce qui sera le cas). Il va alors retourner directement le résultat plutôt que de rappeler à nouveau la fonction de la librairie. Le temps de réponse sera cette fois instantané !
Un autre cas d’utilisation du Proxy Pattern sera, par exemple, si vous mettez en place un système de géolocalisation via Google Maps. Google Maps est une API payante si vous dépassez un certain nombre de requêtes. Grâce à un Proxy Pattern, vous pouvez limiter ce nombre de requêtes. D’ailleurs, bonne nouvelle, c’est ce que nous allons faire dès maintenant. :)
Implémentez un Proxy Pattern
Pour implémenter un Proxy Pattern, je vous invite à créer un dossier proxy dans lequel vous allez “ranger” tous vos proxys. Dans le cadre du projet Filmo Patterns, j’ai appelé ce fichier ProxyRatingSorter
.
class ProxyRatingSorter {
constructor() {
this.cache = []
}
async sorter() {
}
}
Étant donné que cet objet va nous permettre de gérer le cache, j’ai ajouté dans son constructor la propriété cache
.
Dans la vidéo ci-dessous, je vais vous montrer comment créer un Proxy Pattern pour un système de géolocalisation. J’utiliserai JS Bin pour réaliser mon exemple.
Vous pouvez retrouver le code de cette implémentation sur ce Gist GitHub.
Voilà, vous savez maintenant coder un Proxy Pattern ! À la différence des Decorators et des Adapters, les Proxy Patterns peuvent être un peu plus complexes à implémenter. La bonne nouvelle, c’est que vous allez avoir dès maintenant l’opportunité de vous exercer. :)
À vous de jouer !
C’est le moment de résoudre l’issue GitHub et d’implémenter un Proxy Pattern. Vous trouverez dans l’issue quatre User Stories à suivre. :)
J’ai déjà créé le fichier pour le Proxy :
js/proxy/ProxyRatingSorter
, ainsi que la méthodesorter
. C’est dans cette méthode que vous devez le coder.Une fois implémenté, vous pourrez modifier le template
js/templates/SorterForm
et plus précisément la constantesortedData
. Vous devrez appeler le proxy et non la librairie.
Une fois que vous aurez trouvé la solution ou suffisamment cherché, je vous invite à regarder la vidéo ci-dessous. :)
Le code source contenant la solution de cet exercice se trouve sur la branche partie-3/chapitre-3-fin
.
En résumé
Le Proxy Pattern permet de faciliter la communication entre deux objets en créant un objet plus simple à manipuler et à utiliser.
Grâce au Proxy Pattern, vous pouvez faciliter par exemple la gestion du cache de votre projet. Le cache permet de stocker le résultat d’une fonction et ainsi de réduire le temps de réponse.
Quand vous implémentez un Proxy Pattern dans votre base de code, vous ne communiquez plus avec l’objet proxifié (ici notre librairie de tri) : vous communiquez avec le proxy.
Vous venez de terminer la partie sur les Structural Design Patterns. Sachez qu’il en existe de nombreux autres que vous découvrirez petit à petit dans votre vie de développeur .:)