« Par définition, un design pattern est une solution à un problème récurrent dans la conception d’application orientée objet. Il décrit alors la solution éprouvée pour résoudre un problème de conception de logiciel. A noter que les modèles de conception du GoF sont divisés en trois catégories: les modèles de création pour la création d’objets; Modèles structurels pour fournir une relation entre les objets; et enfin, des modèles de comportement pour aider à définir comment les objets interagissent. »
Au cours de cette série de step by step, nous aborderons plusieurs grands principes de conception et de développement du génie logiciel. Alors, dans le cadre de cette première, nous allons nous focaliser sur notre premier patron de conception (de l’anglais, Design Pattern) et, bien sûr, durant toute la série, nous verrons en détails la plupart des patrons de conception du GoF.
Alors, c’est quoi un Patron de conception ou Design Patterns? Avant même de répondre à cette question, je me permets de vous faire un bref historique. D’abord, sachez que pour parler de Design Pattern en français on utilise plusieurs thèmes comme: “motif de conception”, « modèle de conception” et couramment “patron de conception”.
Histoire des Design patterns
Maintenant, parlons de l’origine des Design Patterns qui remonte à 1970 avec les travaux de Christopher Alexander qui est à la fois anthropologue et architecte américain d’origine autrichienne. Christopher découvre que la phase de conception en architecture laisse place à des problèmes récurrents, alors, il va chercher à apporter des solutions à ces contraintes interdépendantes. Ainsi, ses solutions vont être utilisées dans le domaine de l’anthropologie, de l’histoire et du design (les types architecturaux).
Mais, au courant des années 90, l’idée de Christopher allait être reprise au domaine de conception de logiciel. Plus précisément, en 1995 dans un ouvrage publié par Gang of Four (GoF), dont le titre traduit en français est celui-ci: “Design patterns. Catalogue des modèles de conception réutilisables ». Dans cet ouvrage, sont présentés 23 motifs de conception qui sont aujourd’hui des références dans le monde informatique.
Définition
Par définition, un design pattern est une solution à un problème récurrent dans la conception d’application orientée objet. Il décrit alors la solution éprouvée pour résoudre un problème de conception de logiciel. A noter que les modèles de conception du GoF sont divisés en trois catégories: les modèles de création pour la création d’objets; Modèles structurels pour fournir une relation entre les objets; et enfin, des modèles de comportement pour aider à définir comment les objets interagissent.
A présent que nous avons appris ce qu’est un patron de conception, nous allons pouvoir enfin vous présenter notre premier Design pattern dans cette série. Pour ce faire, je vous présente le Design Pattern Composite, faisant partie de la catégorie des modèles de conception structurels. Le modèle de conception Composite vise à organiser les objets en structures arborescentes afin de représenter un hiérarchie et permet à la partie cliente de manipuler un objet unique et un objet composé de la même manière. En conséquence, ce patron de conception permet d’isoler l’appartenance à un agrégat.
Notre cas pratique
Alors, avant de passer au cas pratique d’aujourd’hui, essayons de mieux comprendre le patron de conception composite. Ainsi, commençons-donc par l’expliquer à partir d’un diagramme de classe UML:

Dans ce diagramme où chacune des classes a une responsabilité particulière, la classe Composant définit l’interface d’un objet pouvant être un composant d’un autre objet de l’arborescence. La classe Composite implémente un objet de l’arborescence ayant un ou des objets le composant. La classe Element implémente un objet sans objet le composant. Enfin, c’est à la partie cliente de manipuler ces objets par l’interface Composant.
Problème
Je souhaite mettre au point un module de gestion de facture pour les commandes des clients de mon site de vente en ligne. Mais, je veux d’abord prendre en compte le prix initial de la commande du client plus les frais d’expédition, de taxe au tout autres (assurance par exemple) liés à la commande en cours. En même temps, mon module doit prendre en compte si le client a une réduction (par voucher ou par coupon de réduction traditionnel) pour enfin soustraire la somme de la réduction au coût total de la commande.
Solution avec le Design pattern Composite
Notre diagramme de classe:

Rapidement, identifions les différentes classes de notre diagramme:
- Les interfaces Composant ici sont “OrderPrice” et “OrderDiscount”, dans notre cas ce sont des interfaces implémentées par les classes “Invoice” et “FinalInvoice” qui elles sont deux classes Composite. A remarquer que la classe “FinalInvoice” implémente les deux interfaces présentes. Mais bon, ne vous en faites pas, plus tard vous allez comprendre pourquoi.
- Les classes Composite sont “Invoice” et “FinalInvoice”.
- Et toutes les autres classes présentes sont des classes Élément.
Les étapes du codage (en Java):
Création des interfaces Composant “OrderPrice” et “OrderDiscount” avec respectivement les méthodes “getPrice()” et “getDiscountPrice()”.
public interface OrderPrice {
public double getPrice();
}
public interface OrderDiscount {
public double getDiscountPrice();
}
Création des classes Composite “Invoice” et “FinalInvoice” .
Dans la classe “Invoice” :
Importons
Initialisation de notre collection “invoice” au niveau du constructeur de la classe.
Nous importons ici les mêmes packages.
Au lieu d’une variable de type collection, nous en créons deux cette fois, une pour la collection “finalInvoice” et une autre pour “disccount”.
// Class properties
private Collection finalInvoice;
private Collection discount;
Nous procédons à leur initialisation dans le constructeur de la classe.
public FinalInvoice() {
finalInvoice = new ArrayList();
discount = new ArrayList();
}
A cause que “FinalInvoice” soit liée avec nos deux interfaces, elle implémente les deux méthodes “getPrice” et “getDiscountPrice” respectivement de l’interface “OrderPrice” et “OrderDiscount”. A ne pas oublier l’annotation @Override, et la une ultime méthode “getTotal(double total)”
public double getDiscountPrice() {
double totalDiscount = 0;
for (Iterator i = discount.iterator(); i.hasNext(); ) {
Object object = i.next();
OrderDiscount discountPrice = (OrderDiscount)object;
totalDiscount += discountPrice.getDiscountPrice();
}
return totalDiscount;
}
Création des classe Element implémentant les interfaces “OrderPrice”, et “OrderDiscountPrice” respectivement.
Nous avons besoin d’une variable de type double pour le prix ou le prix réduit respectivement selon l’interface implémentée par la classe question.
Initialisation de la variable en question dans le constructeur de la classe.
Et, implémentation de la méthode “getPrice()” ou “getDiscountPrice”, toujours respectivement selon l’interface implémentée par la classe en question.
Enfin, nous créons la classe cliente, dans notre qui est “main” pour simuler notre programme.
class Main {
public static void main(String[] args) {
InitPrice initPrice = new InitPrice(50.00);
System.out.print(« \n« +« Offer price excluding tax : « );
System.out.print(initPrice.getPrice()+« $ »);
ShippingFees shippingFees = new ShippingFees(6.50);
System.out.print(« \n« +« Shipping fees : « );
System.out.print(shippingFees.getPrice()+« $ »);
TaxFees tva = new TaxFees(50*10/100);
System.out.print(« \n« +« Tax fees : « );
System.out.print(tva.getPrice()+« $ »);
Invoice invoice = new Invoice();
invoice.add(initPrice);
invoice.add(shippingFees);
invoice.add(tva);
System.out.print(« \n« +« Total price before discount : « );
System.out.println(invoice.getPrice()+« $ »);
Vouchers voucher = new Vouchers(50*25/100);
System.out.print(« \n« +« Vouchers promotions : « );
System.out.print(voucher.getDiscountPrice()+« $ »);
Coupons coupon = new Coupons(50*5/100);
System.out.print(« \n« +« Discount coupons : « );
System.out.print(coupon.getDiscountPrice()+« $ »);
FinalInvoice finalInvoice = new FinalInvoice();
finalInvoice.add(voucher);
finalInvoice.add(coupon);
System.out.print(« \n« +« Total reduction on the offer : « );
System.out.println(finalInvoice.getDiscountPrice()+« $ »);
System.out.println(« \n« +« Total price after discount : »+ » « +finalInvoice.getTotal(61.5–14.0)+« $ »);
}
}
Simulation

Conclusion
Et voilà, maintenant que nous avons simulé notre programme, nous constatons effectivement les possibilités du modèle de conception Composite. Les codes sont disponibles ici pour vous faciliter la pratique.
Prochainement, nous revenons vers vous avec un nouveau modèle de conception dans une nouvelle partie dans cette série sur les Design patterns dans la catégorie structurelle. En attendant de vous retrouver, je reste réceptif à vos questions, commentaires et suggestions.

Votre commentaire