Plus de 500 000 exem­plaires de « Design Patterns: Elements of Reusable Object-Oriented Software » ont été vendus depuis sa pu­bli­ca­tion en 1994. Le livre, destiné aux dé­ve­lop­peurs de logiciels, décrit 23 patrons de con­cep­tion dif­fé­rents, les Design Patterns. Ils sont également connus dans les cercles pro­fes­sion­nels sous le nom de « Gang of Four » design patterns, un nom qui renvoie aux quatre auteurs : Erich Gamma, John Vlissides, Ralph Johnson et Richard Helm.

Parmi les nom­breuses stra­té­gies de con­cep­tion en­seig­nées dans cet ouvrage, on trouve le patron fabrique (en anglais, factory method) qui permet à une classe de déléguer la création d'objets à des sous-classes. Des in­for­ma­tions concrètes sur l’uti­li­sa­tion de cette méthode pratique sont notamment fournies par le patron factory, qui est main­te­nant souvent sim­ple­ment appelé le factory pattern.

Qu’est-ce que le factory pattern ?

Le factory pattern décrit une approche de pro­gram­ma­tion qui vous permet de créer des objets sans avoir à spécifier la classe exacte de ces objets. Cela permet d'échan­ger l’objet créé de manière souple et pratique. Pour la mise en œuvre, les dé­ve­lop­peurs ont recours au patron de con­cep­tion fabrique, également appelé factory pattern, qui donne son nom au modèle. Cette méthode est soit spécifiée dans une interface et im­plé­men­tée par une classe enfant, soit im­plé­men­tée par une classe de base et éven­tuel­le­ment écrasée (par des classes dérivées). Le patron se substitue ainsi au cons­truc­teur de classe habituel pour détacher la création d’objets des objets eux-mêmes, per­met­tant ainsi de suivre les principes dits SOLID.

Note

Les principes SOLID sont un sous-ensemble de principes de la pro­gram­ma­tion orientée objet (POO) qui visent à améliorer le processus de dé­ve­lop­pe­ment des logiciels orientés objet. L’acronyme "SOLID" désigne les cinq principes suivants :

- Principe de Single-Res­pon­si­bi­lity : chaque classe ne devrait avoir qu'une seule res­pon­sa­bi­lité.

- Principe de Open-Closed : les unités lo­gi­cielles doivent pouvoir être étendues sans avoir à modifier leur com­por­te­ment.

- Principe de Subs­ti­tu­tions de Liskov : une classe dérivée doit toujours être uti­li­sable à la place de sa classe de base.

- Principe de Interface-Se­gre­ga­tion : les in­ter­faces doivent être par­fai­te­ment adaptées aux besoins des clients qui y accèdent.

- Principe de Dependency-Inversion : les classes à un niveau d’abs­trac­tion supérieur ne devraient jamais dépendre de classes à un niveau d’abs­trac­tion inférieur.

Quel est l’objectif du factory pattern ?

Le factory pattern vise à résoudre un problème fon­da­men­tal lors de l’ins­tan­cia­tion, c’est-à-dire la création d’un objet concret d’une classe, dans la pro­gram­ma­tion orientée objet : créer un objet di­rec­te­ment au sein de la classe, qui a besoin de cet objet ou devrait l’utiliser, est possible en principe, mais très rigide. Il lie la classe à cet objet par­ti­cu­lier et rend im­pos­sible de modifier l'ins­tan­cia­tion in­dé­pen­dam­ment de la classe. Le factory pattern évite un tel code en dé­fi­nis­sant d'abord une opération distincte pour la création de l'objet : la fabrique. Une fois appelée, elle génère l’objet, au lieu du cons­truc­teur de classe mentionné plus haut.

Factory pattern : diagramme UML du patron factory

Ainsi, dans les logiciels qui suivent le factory pattern, le code d’un objet à créer (également appelé « produit » dans ce contexte) est séparé dans une classe propre. Cette classe abstraite, également appelée « Créateur » ou, selon le modèle, « Fabrique » délègue l’ins­tan­cia­tion de l’objet à une sous-classe (Créa­teur­Con­cret), qui décide en dernier ressort du produit à créer. À cette fin, le Créa­teur­Con­cret reprend la méthode crea­te­Pro­duct() et renvoie ensuite à un Pro­duit­Con­cret, qui peut éven­tuel­le­ment être complété par le Créateur avec un code de fa­bri­ca­tion avant d'être transmis à l’interface en tant que produit fini.

Le processus du Factory Pattern est plus clair grâce au diagramme de classes UML qui résume gra­phi­que­ment les relations et les processus décrits.

Les avantages et les in­con­vé­nients du factory pattern

Dans le factory pattern, l’appel d’une méthode de programme est com­plè­te­ment séparé de l’im­plé­men­ta­tion de nouvelles classes, ce qui présente certains avantages. Cela a notamment un effet sur l’ex­ten­si­bi­lité d’un logiciel : les instances du patron factory ont un degré élevé d’autonomie et per­met­tent d’ajouter de nouvelles classes sans que l’ap­pli­ca­tion ait à changer de quelque façon que ce soit, pa­ral­lè­le­ment à l'exé­cu­tion. Il suffit d’im­plé­men­ter l'in­ter­face de l'usine et d'ins­tan­cier le créateur en con­sé­quence (via le Créa­teur­Con­cret).

Un autre avantage est la bonne tes­ta­bi­lité des com­po­sants de la fabrique. Si un Créateur met en place trois classes, par exemple, leur fonc­tion­na­lité peut être testée in­di­vi­duel­le­ment et in­dé­pen­dam­ment de la classe d’appel. Dans le cas de ce dernier, il suffit de s’assurer qu’il appelle cor­rec­te­ment le Créateur, même si le logiciel est étendu à cette étape ul­té­rieu­re­ment. La pos­si­bi­lité de donner un nom sig­ni­fi­ca­tif au patron factory (con­trai­re­ment à un cons­truc­teur de classe) est également bénéfique.

La grande faiblesse du factory pattern est le fait que son im­plé­men­ta­tion entraîne une forte aug­men­ta­tion des classes incluses, car chaque Pro­duit­Con­cret nécessite toujours un Créa­teur­Con­cret. Aussi rentable que soit en principe l’approche du factory pattern en ce qui concerne l’extension d'un logiciel, elle est également dé­sa­van­ta­geuse en ce qui concerne l’effort à fournir : si une famille de produits doit être étendue, non seulement l'in­ter­face, mais aussi toutes les classes su­bor­don­nées du Créa­teur­Con­cret doivent être adaptées en con­sé­quence. Une bonne pla­ni­fi­ca­tion préalable des types de produits requis est donc in­dis­pen­sable.

Avantages In­con­vé­nients
Ex­ten­si­bi­lité modulaire de l’ap­pli­ca­tion Nombre élevé de classes requises
Bonne tes­ta­bi­lité L'ex­ten­sion de l’ap­pli­ca­tion est très complexe
Noms de méthodes sig­ni­fi­ca­tifs

Où utilise-t-on le factory pattern ?

Le factory pattern peut s'avérer précieux dans divers scénarios d'ap­pli­ca­tion. En par­ti­cu­lier, les logiciels pour lesquels les produits concrets à créer ne sont pas connus ou pas définis à l'avance bé­né­fi­cient de l'ap­proche al­ter­na­tive de la gestion des sous-classes. Les cas d’uti­li­sa­tion typiques sont donc les fra­me­works ou les bi­blio­thèques de classes, qui sont devenus pra­ti­que­ment in­dis­pen­sables comme cadre de base pour le dé­ve­lop­pe­ment d’ap­pli­ca­tions modernes.

Les systèmes d'au­then­ti­fi­ca­tion bé­né­fi­cient également des avantages du patron de con­cep­tion fabrique. Au lieu d’une classe centrale avec divers pa­ra­mètres qui varient en fonction de l’au­to­ri­sa­tion de l’uti­li­sa­teur, le processus d’au­then­ti­fi­ca­tion peut être délégué à des classes Fabrique qui prennent des décisions in­dé­pen­dantes con­cer­nant le trai­te­ment de l’uti­li­sa­teur respectif.

En outre, la con­cep­tion selon l’approche du factory pattern convient gé­né­ra­le­ment à tous les logiciels dans lesquels de nouvelles classes sont ajoutées de manière pro­gram­mée et régulière, surtout si ces classes doivent passer par le même processus de création.

Factory pattern : exemple (PHP)

Le patron Factory peut être utilisé dans des ap­pli­ca­tions de divers langages de pro­gram­ma­tion. Les exemples les plus connus sont Java, Ja­vaS­cript, C++, C#, Python et PHP. Ce dernier langage de script est également utilisé dans l'exemple pratique suivant, qui est basé sur un article du blog Php­mon­keys.

Dans ce cas, nous éta­blis­sons un scénario avec la classe abstraite « Car » (Créateur) et la classe Fabrique « Car­Fac­tory » (Créa­teur­Con­cret). Il est conçu aussi sim­ple­ment que possible et ne contient qu'un code per­met­tant de définir une couleur pour la voiture, couleur par défaut : blanc, et de la lire :

class Car {
	private $color = null;
	public function __construct() {
		$this->color = "white";
	}
	public function setColor($color) {
		$this->color = $color;
	}
	public function getColor() {
		return $this->color;
	}
}

La classe Fabrique introduit également des méthodes pour les voitures « rouges » (red) et « bleues » (blue), ainsi qu'une méthode privée pour la création de la classe pro­pre­ment dite :

class CarFactory {
	private function __construct() {
	}
	public static function getBlueCar() {
		return self::getCar("blue");
	}
	public static function getRedCar() {
		return self::getCar("red");
	}
	private static function getCar($color) {
		$car = new Car();
		$car->setColor($color);
		return $car;
	}
}

En option, cette classe Fabrique encore très claire peut main­te­nant, grâce au factory pattern, être étendue à diverses autres ca­rac­té­ris­tiques de la voiture, comme des couleurs sup­plé­men­taires, la marque de la voiture ou le prix.

Aller au menu principal