0% ont trouvé ce document utile (0 vote)
3 vues22 pages

Introduction Aux Design Patterns

Les design patterns sont des solutions réutilisables à des problèmes courants de conception logicielle, facilitant la réutilisabilité, la maintenabilité et l'extensibilité du code. Ce document présente divers types de patterns, notamment les patterns créationnels, structurels et comportementaux, ainsi que les principes SOLID qui les sous-tendent. Chaque pattern est illustré par des définitions, des problèmes qu'ils résolvent et des solutions proposées.

Transféré par

Fabien Zoma
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
3 vues22 pages

Introduction Aux Design Patterns

Les design patterns sont des solutions réutilisables à des problèmes courants de conception logicielle, facilitant la réutilisabilité, la maintenabilité et l'extensibilité du code. Ce document présente divers types de patterns, notamment les patterns créationnels, structurels et comportementaux, ainsi que les principes SOLID qui les sous-tendent. Chaque pattern est illustré par des définitions, des problèmes qu'ils résolvent et des solutions proposées.

Transféré par

Fabien Zoma
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Introduction aux Design Patterns

Solutions éprouvées pour des problèmes récurrents


Les design patterns sont des solutions réutilisables à des problèmes
courants de conception logicielle.

Ils représentent les meilleures pratiques utilisées par les développeurs


expérimentés.

Cette présentation explore les patterns les plus importants et leur


application pratique.
Qu'est-ce qu'un Design Pattern ?

Définition : Un design pattern est une solution réutilisable à un problème récurrent dans la conception de logiciels. Le
concept a été popularisé par le livre "Design Patterns : Elements of Reusable Object-Oriented Software" du Gang of
Four (GoF).

Pourquoi les utiliser ?


Réutilisabilité : Vous n'avez pas besoin de réinventer la roue pour
chaque problème.

Maintenabilité : Le code devient plus facile à comprendre, à modifier


et à maintenir.

Extensibilité : Les patterns facilitent l'ajout de nouvelles


fonctionnalités sans modifier le code existant.

Vocabulaire commun : Ils offrent un langage partagé pour les


développeurs, simplifiant les discussions sur l'architecture logicielle.
Les principes SOLID

Les Design Patterns sont étroitement liés aux principes SOLID, qui sont un ensemble de cinq principes de conception qui visent à rendre le code plus compréhensible,
flexible et maintenable.

S Single Responsibility Principle


Une classe doit avoir une seule raison de changer.

O Open/Closed Principle

Les classes doivent être ouvertes à l'extension mais fermées à la modification.

L Liskov Substitution Principle

Les objets d'un programme doivent pouvoir être remplacés par des instances de leurs
sous-classes sans altérer le bon fonctionnement du programme.

I Interface Segregation Principle

Les clients ne doivent pas être forcés de dépendre d'interfaces qu'ils n'utilisent pas.

D Dependency Inversion Principle


Les Patterns Créationnels
Les patterns créationnels sont des solutions qui traitent des mécanismes de création d'objets, en
essayant de créer des objets de manière adaptée à la situation. Ils abstraient le processus
d'instanciation et aident à rendre un système indépendant de la façon dont ses objets sont créés.

Utilités principales
Encapsuler la connaissance : Ils encapsulent la connaissance à
propos des classes concrètes utilisées par le système.
Masquer la complexité : Ils cachent comment les instances de ces
classes sont créées et assemblées.

Flexibilité : Ils permettent de configurer un système avec différentes


familles d'objets.

Singleton Factory Method Builder


Garantit qu'une classe n'a qu'une
seule instance et fournit un point Définit une interface pour créer Sépare la construction d'un objet
d'accès global à cette instance. un objet, mais laisse aux sous- complexe de sa représentation
classes le soin de décider quelle pour créer différentes
classe instancier. représentations.

Prototype Abstract Factory


Permet de copier des objets Fournit une interface pour créer
existants sans que votre code des familles d'objets liés sans
dépende de leurs classes. spécifier leurs classes concrètes.
Pattern Singleton
Définition

Le Singleton est un pattern de conception créationnel qui garantit qu'une classe n'a qu'une seule
et unique instance et fournit un point d'accès global à cette instance.

Problème

Vous avez besoin qu'une classe n'ait qu'une seule instance disponible pour tous les clients, par
exemple, un objet unique de connexion à une base de données.

Solution
Rendre le constructeur privé et fournir une méthode statique qui retourne l'instance unique, en
la créant la première fois si elle n'existe pas. classe DatabaseConnection {
privé statique instance: DatabaseConnection
Applications privé constructeur() { /* initialisation */ }
Gestionnaires de logs Connexions à une base de données public statique méthode getInstance() {
si (instance == null) {
Fichiers de configuration instance = new DatabaseConnection()
}
retourner instance
}
}
Pattern Factory Method

Définition

Le Factory Method est un pattern créationnel qui fournit une interface pour la création d'objets
dans une super-classe, mais laisse aux sous-classes le soin de modifier le type des objets créés.

Problème
Une classe ne peut pas anticiper la classe des objets qu'elle doit créer. Par exemple, une
application de logistique peut avoir besoin de créer différents types de transport (Camion, classe abstraite TransportCreator {
public abstraite méthode createTransport(): Transport
Bateau).
public fonction operate() {
produit = createTransport()
Solution [Link]()
}
}
Remplacer les appels directs au constructeur par des appels à une méthode spéciale, la
"méthode de fabrique". Les sous-classes peuvent surcharger cette méthode. classe RoadLogistics extends TransportCreator {
public méthode createTransport(): Transport {
retourner new Truck()
Applications }
}

Dans un framework, pour permettre au code client d'étendre ses composants

Pour fournir aux utilisateurs d'une bibliothèque un moyen d'étendre ses composants
Pattern Builder

Définition

Le Builder est un pattern de conception créationnel qui permet de construire des objets
complexes étape par étape. Il permet de produire différentes représentations d'un objet en
utilisant le même code de construction.

Problème

Un constructeur avec une longue liste de paramètres devient ingérable. La plupart de ces
paramètres peuvent être inutilisés, rendant les appels au constructeur pénibles.

Solution

Extraire le code de construction de l'objet de sa propre classe et le déplacer dans des objets
séparés appelés "builders". Le processus de construction est décomposé en plusieurs étapes.

Applications

Construction d'objets complexes comme des requêtes SQL ou des documents XML

Création d'objets avec de nombreux paramètres optionnels


Pattern Prototype
Définition
Le Prototype est un pattern de conception créationnel qui permet de copier des objets existants
sans que votre code dépende de leurs classes.

Problème
Vous devez créer une copie exacte d'un objet, mais vous ne pouvez pas accéder directement à
son constructeur ou sa structure interne est complexe.

Solution

Le pattern Prototype délègue le processus de clonage aux objets qui sont clonés. Il déclare une interface Prototype {
interface commune pour tous les objets qui prennent en charge le clonage, permettant de copier méthode clone(): Prototype
un objet sans connaître sa classe concrète. }

classe ConcretePrototype implements Prototype {


privé field1: string
Applications privé field2: number

Création d'objets coûteux à initialiser constructeur(prototype) {


this.field1 = prototype.field1
Création d'objets avec des états initiaux similaires this.field2 = prototype.field2
}

public méthode clone(): Prototype {


retourner new ConcretePrototype(this)
}
}
Pattern Fabrique Abstraite
Définition
La Fabrique Abstraite est un pattern de conception créationnel qui permet de créer des familles
d'objets apparentés sans préciser leurs classes concrètes.

Problème

Comment créer des familles d'objets liés ou dépendants sans spécifier leurs classes concrètes et
en garantissant que les objets créés sont compatibles entre eux ?

Solution
interface AbstractFactory {
Déclarer une interface pour chaque type d'objet produit, puis créer une interface de fabrique méthode createProductA(): AbstractProductA
abstraite qui déclare des méthodes pour créer chaque type d'objet. Enfin, implémenter des méthode createProductB(): AbstractProductB
fabriques concrètes pour chaque variante de famille de produits. }

classe ConcreteFactory1 implements AbstractFactory {


public méthode createProductA(): AbstractProductA {
Applications retourner new ConcreteProductA1()
}
Création de familles de produits compatibles public méthode createProductB(): AbstractProductB {
retourner new ConcreteProductB1()
Bibliothèques d'interface utilisateur multi-plateformes }
}
Les Patterns Structurels

Les patterns structurels sont des solutions réutilisables qui expliquent comment assembler
différentes classes et objets pour former des structures plus grandes et plus flexibles.

Utilités principales

Réduire la complexité : Ils aident à gérer de grands systèmes en les


découpant en morceaux plus simples.

Faciliter la maintenance : L'impact des modifications sur le reste du


système est minimisé.

Améliorer la flexibilité : Adapter le comportement sans modifier le


code existant.

Adapter Decorator Facade


Fournit une interface simplifiée à
Permet à des objets ayant des Ajoute dynamiquement des
un ensemble complexe de
interfaces incompatibles de responsabilités à un objet.
classes.
collaborer.

Bridge Composite Flyweight

Réduit la consommation de
Sépare une abstraction de son Compose des objets en structures
mémoire en partageant les
implémentation pour qu'elles arborescentes pour représenter
données communes entre
puissent varier indépendamment. des hiérarchies partie-tout.
plusieurs objets.
Pattern Adapter
Définition
L'Adapter est un pattern de conception structurel qui permet à des objets ayant des interfaces
incompatibles de collaborer.

Problème
Vous voulez utiliser une classe existante, mais son interface n'est pas compatible avec le reste de
votre code.

Solution

Créer une classe "adaptateur" qui s'intercale entre votre application et la classe incompatible.
Cet adaptateur implémente l'interface attendue par votre code.
interface NewApi {
méthode displayInformation()
}
Applications
classe OldApi {
Intégration de bibliothèques tierces public méthode showData() { ... }
}
Réutilisation de sous-classes existantes
classe ApiAdapter implements NewApi {
privé adaptee: OldApi

public méthode displayInformation() {


[Link]()
}
}
Pattern Decorator
Définition

Le Decorator est un pattern de conception structurel qui permet d'ajouter dynamiquement de


nouveaux comportements à des objets sans modifier leur classe.

Problème
Vous souhaitez pouvoir ajouter des responsabilités supplémentaires à un objet de manière
dynamique et transparente, sans affecter les autres objets.

Solution
Placer l'objet cible dans un autre objet "enveloppeur" (wrapper) qui imite l'interface de l'objet
cible. Ce wrapper peut ensuite ajouter son propre comportement avant ou après avoir délégué
l'appel à l'objet enveloppé.
interface Coffee {
Applications méthode getCost(): number
méthode getDescription(): string
Ajout de fonctionnalités à des composants graphiques }

Classes de flux de données (FileInputStream, BufferedInputStream) classe SimpleCoffee implements Coffee { ... }

classe CoffeeDecorator implements Coffee {


protégé wrappee: Coffee

public méthode getCost() {


retourner [Link]()
}
}
Pattern Facade
Définition

La Façade est un pattern de conception structurel qui fournit une interface simplifiée à une
bibliothèque, un framework ou tout autre ensemble complexe de classes.

Problème
Vous avez besoin de travailler avec un sous-système complexe qui comporte de nombreuses
classes et dépendances. Interagir directement avec ce sous-système est compliqué et source
d'erreurs.

Solution
classe VideoSystem { méthode turnOn() { ... } }
classe AudioSystem { méthode setVolume(level) { ... } }
Créer une classe Facade qui offre une interface simple et limitée au sous-système. La façade classe LightSystem { méthode dim(level) { ... } }
reçoit les appels du client et délègue le travail aux classes appropriées du sous-système, cachant
ainsi sa complexité. classe HomeCinemaFacade {
privé video: VideoSystem
privé audio: AudioSystem
Applications privé lights: LightSystem

Fournir une interface simple à un sous-système complexe public méthode watchMovie() {


[Link](10)
Découpler le code client des composants internes d'un sous-système [Link]()
[Link](5)
}
}
Pattern Bridge (Pont)
Définition

Le Bridge est un pattern de conception structurel qui permet de séparer une abstraction de son
implémentation afin que les deux puissent varier indépendamment.

Problème

Comment éviter un couplage permanent entre une abstraction et son implémentation ?


Comment permettre à l'abstraction et à l'implémentation de varier indépendamment ?

Solution

Séparer l'abstraction de son implémentation en plaçant ces deux concepts dans des hiérarchies
de classes distinctes. L'abstraction contient une référence à l'implémentation et délègue le travail
à cet objet d'implémentation.
classe Abstraction {
protégé implementor: Implementor

Applications constructeur(implementor: Implementor) {


[Link] = implementor
Éviter un lien permanent entre abstraction et implémentation }

Étendre une classe dans plusieurs dimensions orthogonales public méthode operation(): void {
[Link]()
}
}

interface Implementor {
méthode operationImpl(): void
}
Pattern Composite
Définition

Le Composite est un pattern de conception structurel qui permet de composer des objets en
structures arborescentes pour représenter des hiérarchies partie-tout et traiter les objets
individuels et les compositions d'objets de manière uniforme.

Problème

Comment représenter des hiérarchies d'objets partie-tout ? Comment permettre aux clients de
traiter de manière uniforme les objets individuels et les compositions d'objets ?

Solution
Définir une interface commune pour tous les objets de la composition (composants simples et
composites). Les composites délèguent le travail à leurs composants enfants et traitent les
résultats intermédiaires. interface Component {
méthode operation(): void
}
Applications classe Leaf implements Component {
public méthode operation(): void {
Structures arborescentes (interfaces graphiques, documents) // Opération sur une feuille
}
Opérations récursives sur des structures hiérarchiques }
classe Composite implements Component {
privé children: List
public méthode add(component: Component): void { ... }
public méthode remove(component: Component): void { ... }

public méthode operation(): void {


pour chaque child dans children {
Pattern Flyweight (Poids Mouche)
Définition

Le Flyweight est un pattern de conception structurel qui permet de réduire la consommation de


mémoire en partageant les données communes entre plusieurs objets similaires.

Problème

Comment supporter efficacement un grand nombre d'objets fins qui partagent une partie de leur
partie de leur état, tout en minimisant la consommation de mémoire ?

Solution

Séparer l'état intrinsèque (partagé) de l'état extrinsèque (unique). Stocker l'état intrinsèque dans
intrinsèque dans des objets partagés (flyweights) et passer l'état extrinsèque aux méthodes qui
méthodes qui l'utilisent.

Applications
Éditeurs de texte (partage des caractères)

Jeux vidéo (partage des textures, modèles 3D)

classe Flyweight {
privé sharedState: any

constructeur(sharedState: any) {
[Link] = sharedState
Les Patterns Comportementaux
Les patterns comportementaux sont des solutions qui se concentrent sur la manière dont les
manière dont les objets et les classes communiquent et s'organisent pour accomplir une tâche.
une tâche. Plutôt que de s'intéresser à la structure des objets, ils gèrent leurs interactions et la
interactions et la distribution des responsabilités.

Utilités principales

Améliorer la communication : Ils définissent des schémas clairs


pour la communication entre les objets.

Faciliter l'ajout de fonctionnalités : En découplant les objets, on


peut modifier leurs interactions sans toucher au code existant.

Rendre le code plus maintenable : La séparation des responsabilités


rend chaque partie du code plus simple.

Observer Strategy Iterator

Définit un mécanisme de
souscription pour notifier Transforme un ensemble de Permet de parcourir les éléments
plusieurs objets des événements comportements en objets et les d'une collection sans exposer sa
qui arrivent à l'objet qu'ils rend interchangeables à représentation sous-jacente.
observent. l'intérieur de l'objet de contexte
original.

Mediator Visitor
Pattern Observer
Définition
L'Observer est un pattern de conception comportemental qui permet de définir un mécanisme
de souscription pour notifier plusieurs objets des événements qui arrivent à l'objet qu'ils
observent.

Problème

Un objet (le sujet) doit notifier d'autres objets (les observateurs) de ses changements d'état, mais
sans être couplé aux classes concrètes de ces observateurs.

Solution

Le pattern Observer propose que l'objet "Sujet" maintienne une liste de ses "Observateurs".
Lorsqu'un changement d'état se produit, le sujet parcourt sa liste et appelle une méthode de
notification (update()) sur chaque observateur.

Applications
Systèmes de gestion d'événements (GUI, frameworks web)

Architecture Modèle-Vue-Contrôleur (MVC)

interface Subject {
méthode attach(observer: Observer)
méthode detach(observer: Observer)
méthode notify()
Pattern Strategy
Définition

La Stratégie est un pattern de conception comportemental qui transforme un ensemble de


ensemble de comportements en objets et les rend interchangeables à l'intérieur de l'objet de
l'objet de contexte original.

Problème

Vous avez une classe qui peut faire quelque chose de plusieurs manières différentes (en utilisant
(en utilisant différents algorithmes), et vous voulez pouvoir changer d'algorithme à l'exécution.
l'exécution.

Solution interface PaymentStrategy {


méthode pay(amount: number)
Extraire tous les algorithmes pour les placer dans des classes séparées appelées "stratégies". La }
"stratégies". La classe originale, appelée "contexte", contient une référence vers l'une des
classe CreditCardStrategy implements PaymentStrategy { ... }
l'une des stratégies et lui délègue le travail.
classe PaypalStrategy implements PaymentStrategy { ... }

classe PaymentContext {
Applications privé strategy: PaymentStrategy
Implémentation de différents algorithmes de tri ou de compression public méthode setStrategy(strategy: PaymentStrategy) {
[Link] = strategy
Gestion de différentes règles de validation ou de systèmes de paiement }

public méthode executePayment(amount: number) {


[Link](amount)
}
}
Pattern Iterator (Itérateur)
Définition

L'Itérateur est un pattern de conception comportemental qui permet de parcourir les éléments
d'une collection sans exposer sa représentation sous-jacente (liste, pile, arbre, etc.).

Problème
Comment accéder séquentiellement aux éléments d'une collection sans exposer sa structure
interne ? Comment permettre plusieurs parcours simultanés et indépendants d'une même
collection ?

Solution
interface Iterator
Extraire le comportement de parcours d'une collection dans un objet séparé appelé itérateur. En {
plus de l'implémentation du parcours, l'itérateur encapsule tous les détails du parcours. méthode hasNext(): boolean
méthode next(): T
}

Applications interface Aggregate {


méthode createIterator(): Iterator
Parcours de collections complexes }

Parcours simultanés d'une même collection


Pattern Mediator (Médiateur)
Définition

Le Médiateur est un pattern de conception comportemental qui réduit les dépendances


chaotiques entre objets en les forçant à communiquer indirectement, via un objet médiateur.

Problème

Comment réduire le couplage entre des objets qui doivent communiquer entre eux ? Comment
? Comment éviter que les objets se référencent explicitement les uns les autres ?

Solution interface Mediator {


méthode notify(sender: Component, event: string): void
Définir un objet médiateur qui encapsule les interactions entre un ensemble d'objets. Les objets }
d'objets. Les objets ne communiquent plus directement entre eux, mais via le médiateur, ce qui
médiateur, ce qui réduit les dépendances. classe ConcreteMediator implements Mediator {
privé componentA: ComponentA
privé componentB: ComponentB
Applications
constructeur(componentA, componentB) {
Interfaces utilisateur (communication entre composants) [Link] = componentA
[Link] = componentB
Systèmes de contrôle du trafic aérien
[Link](this)
[Link](this)
}

public méthode notify(sender, event) {


if (event === "A") {
[Link]()
}
if (event === "B") {
Pattern Visitor (Visiteur)
Définition
Le Visiteur est un pattern de conception comportemental qui permet de séparer les algorithmes
des objets sur lesquels ils opèrent, permettant d'ajouter de nouvelles opérations sans modifier
les classes des objets.

Problème
Comment définir une nouvelle opération sur une structure d'objets sans changer les classes de
ces objets ? Comment ajouter de nouvelles fonctionnalités à une hiérarchie de classes sans la
modifier ?

Solution

Placer le nouvel algorithme dans une classe séparée appelée visiteur. Les objets originaux
interface Visitor {
doivent seulement fournir une méthode "accept" qui accepte un visiteur et appelle la méthode méthode visitElementA(element: ElementA): void
spécifique du visiteur correspondant à la classe de l'objet. méthode visitElementB(element: ElementB): void
}

interface Element {
Applications méthode accept(visitor: Visitor): void
}
Opérations sur des structures d'objets complexes
classe ConcreteElementA implements Element {
Parseurs et compilateurs public méthode accept(visitor: Visitor): void {
[Link](this)
}

public méthode operationA(): void { ... }


}

classe ConcreteVisitor implements Visitor {

Vous aimerez peut-être aussi