Skip navigation

C’est en lisant l’article de Joan ZAPATA intitulé « Robust and readable architecture for an Android App » que j’ai eu envie d’écrire cet article. Joan expose l’architecture qu’il utilise au sein de l’application qu’il développe. Je ne développe pas sur Android, mais son article semble très intéressant, si vous développez sur cette plateforme je vous conseille fortement de le lire. C’est une partie plus précise de son article qui a attirée mon attention, celle concernant le cache.

Il expose une interface que l’on retrouve souvent sur les projets :

On retrouve aussi souvent cette interface pour l’accès à un contexte. L’interface n’est pas mauvaise mais elle pourrait être améliorée pour être plus lisible et plus robuste. Voici pourquoi :

Comme le montre les exemples ci-dessus il est possible d’insérer dans le cache le mauvais objet (insérer un objet de type Contact avec la clé « user »), et il est possible de demander le mauvais type d’objet pour une clé donnée (demander un objet de type Contact avec la clé « user »). La méthode de lecture pourrait aussi être plus lisible si elle n’introduisait pas une répétition entre le paramètre d’entrée de la fonction et le paramètre de retour.

Depuis l’introduction des génériques en Java il n’est plus nécessaire d’utiliser ce type d’interface pour un accès à un cache ou à un contexte (à moins que vous souhaitiez maintenir une rétro compatibilité de votre framework). L’idée est de faire porter le type de l’objet dans le cache par la clé en se servant des génériques :

On peut ensuite créer les clés qui nous serviront pour le cache :

Et ainsi créer l’interface suivante :

Un exemple d’implémentation avec une HashMap non synchronisée servant de cache (vous pouvez choisir d’implémenter le cache d’une autre façon c’est juste à titre d’exemple) :

Voyons ce que ça donne à l’utilisation :

Comme vous pouvez le comprendre, il n’est pas possible d’insérer ou de demander un objet d’un type incorrect au cache. L’application ne compilera tout simplement pas, il n’y a donc aucun risque de ClassCastException à l’exécution du code. De plus lors de la lecture vous n’avez pas besoin de passer en paramètre le type de l’objet à lire. L’interface est donc plus robuste et plus lisible, et ça ne coute pas grand-chose à mettre en place.