Facade

La programmation avec design patterns

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com
La complexité de certaines applications web est telle qu'un temps d'intégration important est nécessaire à un nouveau développeur pour y entrer. Cependant, des design patterns visant à faciliter cette intégration existent. L'un d'eux s'appelle facade et ressemble beaucoup à la façade d'une maison.

Le design pattern facade (la façade) est la simplification de certains environnements. Imaginons une classe de contrôleur qui englobe les fonctionnalités d'autres classes, comme : la classe générant les URLs, la classe gérant les balises meta et la classe gérant le contenu d'une page. On a besoin de tous ces éléments pour constituer une page web. A la place de pointer séparément vers chacune de ces classes, on peut très bien appeler une des méthodes du contrôleur (par exemple : createWebPage()) qui s'occupera d'initialiser tous ces éléments. Si dans les cas des 3 classes, ce cas de figure est peu explicit, il suffit d'en rajouter une classe qui rajoute les balises <script />, une autre qui rajoute les feuilles de style, une troisième pour les animations Flash, la quatrième pour les images, la cinquième... Dans cette situation, l'utilisation d'un façade serait plus que justifiée.

Grâce à cette illustration on déduit facilement le plus grand avantage de la façade. Il s'agit de la simplicité. L'application peut devenir, entre autres grâce à lui, plus simple à utiliser (déployer, modifier), mais aussi à comprendre. Plusieurs fonctionnalités sont groupées dans un seul endroit, ce qui provoque que le développeur sait pourquoi est retourné un tel résultat et qu'est-ce qu'il faut faire pour retourner un autre.

Ce rassemblement des fonctions ramène aussi un autre point positif. Il réduit les dépendances. L'application utilise désormais la façade pour plusieurs opérations (comme génération d'une page web) et si demain on voudrait modifier un comportement, il suffit alors de changer un seul endroit. Imaginons que notre génération de page web passe par une librairie tiers. Cependant, pendant le fonctionnement du système on s'aperçoit que son équipe de développement abandonne le projet. Pour garantir la stabilité de notre système, on décide d'écrire une librairie maison pour remplacer celle qui a été délaissée. Si l'on utilise la façade, il suffira alors de remplacer l'ancienne par la nouvelle dans un seul endroit. Par contre, sans l'utilisation de la façade, il faudra alors refactoriser plein d'endroits du programme et, peut-être, causer les problèmes non-voulus (une exception, une valeur incorrecte etc.).

Exemple de facade
Maintenant quand on sait comment fonctionne ce patron de conception, on peut passer à son illustration. Pour ce faire, on prendra l'exemple de construction d'une maison. La construction est faite par plusieurs équipes, parmi lesquelles une sera chargée de poser les murs, une autre d'installer les fenêtres et la dernière va travailler l'intérieur. Regardons comment se présente le design pattern facade :

class Mason{
public static int getWorkDays(final int budget){
if(budget>300) return 4;
return 14;
}
}

class WindowWorker{
public static int getWorkDays(final int budget){
if(budget>300) return 2;
return 5;
}
}

class InteriorWorker{
public static int getWorkDays(final int budget){
if(budget>300) return 14;
return 21;
}
}

Ces classes représentent les composants de la façade. La construction d'une maison informatique se fera avec ces objets. Chacun retourne le nombre de jours qu'il aura besoin pour accomplir sa tâche. Ce nombre dépend du budget que le propriétaire du terrain peut allouer à chaque partie. Cependant, ce code est inutile sans la façade, présentée tout de suite après.


class HouseFacade{
public String constructHouse(final int budget){
final int avgBudget=budget/3;
final int constructingDays=Mason.getWorkDays(avgBudget)+WindowWorker.getWorkDays(avgBudget)+InteriorWorker.getWorkDays(avgBudget);
return "House will be constructed for "+constructingDays+" days";
}
}

On voit que cette façade est très simple. Sa seule méthode prend en compte le paramètre budget. Ensuite elle le divise par 3 et demande à ses composants le nombre de jours de travail. A la fin elle retourne un String avec l'information sur le nombre des jours devant être consacrés à la construction de la maison. Imaginons néanmoins que le critère d'attribution change. Il suffira alors de le modifier uniquement ici. Pareil si demain on décide de remplacer WindowWorker, trop cher, par un CheaperWindowWorker qui fera le travail deux fois plus vite pour deux fois moins cher. Il suffira alors de faire la modification dans la façade. Pareil si l'on décidera de rajouter des composants. Et voici, comment tout marche ensemble :


public class FacadeSample{
public static void main(final String[] args){
final HouseFacade houseBigger=new HouseFacade();
System.out.println(houseBigger.constructHouse(1500));
final HouseFacade houseSmaller=new HouseFacade();
System.out.println(houseSmaller.constructHouse(600));
}
}

La création d'une maison est désormais un jeu d'enfant. Si l'on vient d'arriver dans l'application ou si l'on n'a que besoin de construire une maison sans savoir comment, le design pattern facade est le moyen idéal.

Par contre, il faut rester vigilant pour que les objets du facade ne deviennent pas les "objets divins" qui est un exemple du code contre-productif. La classe de façade ne peut pas regrouper toutes les fonctionnalités clés de l'application. A la place de cela, elle devrait être une simplification pour des opérations complexes, comme le construction d'une maison et d'une page web (cas cité au début). Pour découvrir d'autres exemples de contre-productivité, vous pouvez consulter l'article design patterns : introduction.

Façade est un design pattern structurel qui vise à faciliter les opérations complexes. Cet enveloppeur permet de grouper une multitude de fonctionnalités pour en ressortir un seul résultat final. Cependant, il faut rester très attentif pendant l'utilisation de ce patron de conception. Il ne peut pas devenir un objet divin qui sait tout et contrôle tout le système. Le rôle principal de la façace consiste à simplifier l'exécution des opérations complexes et non pas à encapsuler le fonctionnement de tout le système.
Bartosz KONIECZNY 06-10-2013 16:21 design patterns
Moi

Développeur d'applications Internet et journaliste passionné par l'adjectif français. Un aigle polonais orienté vers la progression, volant très haut et écoutant du zouk après les matches du foot français.

Vous appréciez mon travail ?

Pour contribuer au développement de ce site, ou pour remercier pour des articles rédigés, vous pouvez faire un don.

Un conseil Symfony1

Comment afficher un template depuis le fichier d'action ?

Pour le faire il suffit d'appeler la méthode renderPartial() dans le return final.

return $this->renderPartial('ton_template', array('parametres' => 'un paramètre'));