Appuyez sur Entrée pour voir vos résultats ou Echap pour annuler.

Patron de conception: La fabrique

Les sources de cet article sont disponibles sur GitHub.

Présentation

Cet article est le premier d’une série touchant aux patrons de conception. Les design patterns sont aux développeurs ce que les outils sont aux menuisiers, alors il est primordial de les comprendre en détails afin de se doter d’un coffre à outils complet et de savoir lequel peut faire le travail face à un obstacle dans la conception du code.

Que diriez-vous à un menuisier qui visse à l’aide d’un marteau?

Les patrons de conception ont été mis au point afin de répondre à des problèmes spécifiques et réccurants dans les projets de développement logiciel. Plus vous les connaissez bien, plus vous trouverez la solution à vos problèmes rapidement.

La fabrique (Factory Pattern)

Une fabrique, ou factory, est un des patrons de conception les plus utilisés par les développeurs. Il permet notamment d’obtenir une instance de classe concrète sans se soucier de l’implémentation de cette dernière. Dans un exemple typique, la fonction de création d’instance de la fabrique ne contient qu’un seul paramètre qui peut être choisi par l’utilisateur, défini dans une configuration au niveau applicatif, ou reçu dans une itération.

Le problème

Lors d’un projet web, vous devez implémenter les validations des entités passées en dans le corps de chaque requête. Vous disposez de plusieurs types d’entité et votre méthode de validation est exécutée en amont de la requête. Vous pourriez être tempté d’implémenter une fonction isValid() dans l’interface commune des entités, leur délégant ainsi la responsabilité de se valider elles-mêmes.

Bien que cela puisse sembler une solution efficace, elle apporte un second problème. Dans les entités complexes, et dépendant du langage, elles peuvent vite devenir assez volumineuses (en SLOC). On pense notamment au accesseurs, mutateurs, fonctions de comparaison lors du tri, la surcharge des fonctions hashCode() et equals(), et souvent bien plus. Lui laisser la responsabilité de se valider elle-même brise le principe de responsabilité unique de la conception de logiciels.

La solution

Une solution simple à ce problème est d’encapsuler la logique de validation des entités dans des validateurs distincts. Par exemple, pour valider l’entité User, nous aurions un UserValidator implémentant une interface Validator déclarant une fonction validate(User userToValidate).

À ce point, nous avons une instance concrète à créer selon un paramètre, le type de l’entité, et nous n’avons pas à nous soucier de son implémentation puisque nous exécuterons la fonction déclarée au niveau de l’interface. C’est ici que la fabrique prend tout son sens:

À l’aide des types génériques, nous pouvons nous assurer que nous obtiendrons une instance de classe qui sera celle représentant un des sous types de Entity. Puis, à l’aide d’une condition comparant le type de l’entité, nous implémentons la création des validateurs. Pour valider l’entité dans le contexte de l’exemple ci-dessus, l’appel à la fonction de validation se ferait comme ceci:

Conclusion

En somme, la fabrique est un outil puissant pour réduire le couplage entre les classes et elle peut être utilisée lors de phases de réingénérie des applications obsolètes afin d’en améliorer l’architecture. Elle peut aussi être utilisée de pair avec un conteneur d’injection de dépendances afin d’éviter de coupler la couche métier avec le framework et ainsi soustraire les annotations de votre code.

N’hésitez pas à donner votre opinion dans les commentaires ci-dessous!

Code source

Les sources de cet article sont disponibles sur GitHub.

 

Suivez-nous par courriel!

Saisissez votre adresse courriel pour vous abonner au blog d'Ezo et recevoir une notification de chaque nouvel article par email.