Uploaded by issambachir

Présentation 4- Design patterns

advertisement
Master Génie Logiciel
Architecture et Développent de Logiciels
Cours 3: Design pattern
Mr : Y. GAFOUR
2023/2024
Plan
 Introduction
 Définition design pattern
 Catalogue du design pattern
 Creational Patterns :
 Singleton pattern
 Factory pattern
 Structural Patterns
 The Adapter Pattern
 Facade pattern
 Behavioral Patterns
 Iterator pattern
 Strategy pattern
 Autres design pattern
 Pattern de conception MVC (Modèle-Vue-Contrôleur)
 Data Access Object pattern or DAO
 Injection de Dépendances
 Conclusion
2
Introduction
 Les concepteurs experts en orientés objet diront qu'une
conception réutilisable et flexible (accepte les modifications
souhaitées) peut être difficile, mais ce n'est pas impossible à
réaliser dès la première tentative.
 Avant qu’une conception ne soit terminée, ils essaient
généralement de réutiliser des solutions plusieurs fois, en la
modifiant à chaque fois.
 Lorsqu'ils trouvent la bonne solution, ils l'utilisent plusieurs
fois. Par conséquent, vous trouverez des modèles récurrents
(‫ )متكررة‬de classes et d'objets dans nombreux cas de conception
en orientés objet.
3
Définition design pattern
 Les design pattern (Patron de conception ) sont des solutions
typiques (‫ )نموذجية‬aux problèmes
 Un modèle n'est pas une partie de code spécifique, mais un
concept (‫ )مفهوم‬général pour résoudre un problème particulier
courants dans la conception de logiciels
 Un algorithme définit un ensemble des instructions pouvant
atteindre un objectif. Par contre, un modèle est une description
de plus haut niveau d'une solution.
 Les modèles de conception ont d'abord été publiés pour la
première fois dans un livre scientifique il y a plus de 20 ans.
Les quatre auteurs du livre : Erich Gamma, Richard Helm,
Ralph Johnson et John Vlissides, ont depuis été surnommés
«The Gang of Four».
4
Importance de connaître et d'utiliser des design
patterns lors de la conception logicielle
 Il est important de connaître et d'utiliser des design patterns car ils
permettent de résoudre efficacement des problèmes courants en
conception logicielle.
 Il favorisent la réutilisabilité du code, améliorent la clarté et la
maintenabilité du code, et facilitent la communication entre les
développeurs
 Les design patterns peuvent aider à réaliser un couplage faible:
 En utilisant des interfaces ou des abstractions pour communiquer entre
eux, réduisant ainsi leur interdépendance.
5
Catalogue du design pattern
 Creational Patterns : Ces patrons sont utilisés pour résoudre des
problèmes liés à la création d'objets tout en minimisant le couplage
et en maximisant la flexibilité du code.
the ability to adapt to changing requirements and extend functionality without
breaking existing code
 Structural Patterns : Expliquent comment assembler des objets et
des classes dans des structures plus grandes et plus complexes tout en
permettant une meilleure flexibilité et maintenabilité du code.
 Par exemple Adapter Pattern : Permet à des interfaces incompatibles de
travailler ensemble en convertissant l'interface d'une classe en une autre
interface que le client attend.
6
Catalogue du design pattern
 Behavioral Patterns : sont des modèles de conception qui se
concentrent sur la communication entre les objets et la répartition des
responsabilités entre eux.
 Les Behavioral Patterns fournissent des mécanismes spécifiques pour
établir des interactions entre les objets.
 Ils définissent des rôles clairs pour chaque objet participant, indiquant
les responsabilités spécifiques de chaque objet dans le système.
7
Classification1
Creational
Structural
Behavioral
Abstract Factory
Adapter
Null Object
Factory method
Bridge
Command
Builder
Composite
Interpreter
Lazy instantiation
Decorator
Iterator
Object pool
Façade
Mediator
Prototype
Flyweight
Memento
Singleton
Proxy
Observer
Multiton
State
Resource acquisition is
initialization
Chain of responsibility
Strategy
Specification
Template method
Visitor
8
1. Creational Patterns
 Creational Patterns : Fournissent des mécanismes de création
d'objets qui accroître la flexibilité et la réutilisation du code
existant.
 Ces modèles concernent la manière dont les objets sont créés
et instanciés.
 Ils offrent des solutions pour créer des objets d'une manière
qui soit flexible, réutilisable et adaptée à la situation.
 Exemples de patrons de création :
 Singleton pattern
 Factory pattern
9
Singleton pattern
 Le modèle singleton est l'un des modèles de conception les
plus simples.
 Ce modèle restreint l'instanciation d'une classe à un objet afin
d’avoir d'une seule instance de notre classe tout en s'assurant
qu'un seul objet est créé.
10
Exemple
Etape 1 :Créer une classe singleton.
public class SingleObject {
// Créer un objet de SingleObject
private static SingleObject instance = new SingleObject();
// Rendre le constructeur privé afin que cette classe ne puisse pas être instanciée
private SingleObject(){}
// Récupèrer le seul objet disponible
public static SingleObject getInstance(){
return instance;
}
public void showMessage(){
System.out.println("Hello World!");
}
}
11
Exemple
Étape 2 : Obtenir le seul objet de la classe singleton.
public class SingletonPatternDemo {
public static void main(String[] args) {
SingleObject object = SingleObject.getInstance();
// Afficher le message
object.showMessage();
}
}
12
Factory pattern
 Le Factory Design Pattern permet de séparer la création
d'objets dérivant d'une classe mère de leur utilisation.
 De ce fait, il crée plusieurs objets issus d'une même classe
mère.
 Il est un modèle de conception qui fournit une interface pour
créer des objets, mais permet aux sous-classes de modifier le
type d'objets qui seront créés.
Factory Method is a creational design pattern that provides an interface for creating
objects in a superclass, but allows subclasses to alter the type of objects that will be
created
13
Factory pattern
 Exemple de modèle de conception Design Pattern
 Dans cet exemple, nous allons créer une interface Shape qui sera
implémentée par plusieurs classes concrètes. ShapeFactory sera
utilisée pour récupérer les objets de cette famille :
14
Factory pattern
 Exemple de modèle de conception Design Pattern
public interface Shape {
void draw();
}
public class Circle implements Shape{
public void draw(){
System.out.println("Drawing circle");
} }
public class Rectangle implements Shape{
public void draw(){
System.out.println("Drawing Rectangle");
} }
public class Square implements Shape{
public void draw(){
System.out.println("Drawing Square");
} }
15
Factory pattern
 Exemple de modèle de conception Design Pattern
the problem here is that he's making
the creator class instanciate the classes
// ShapeFactory
pour créer des formes
}}
whereas it could be that the creator has
class ShapeFactory {
some business logic that concern
// Méthode statique pour obtenir une forme globally all the classes, so as a solution
public static Shape getShape (String shapeType) { we should make the creator class
abstract class with a factory
if (shapeType == null) {
method that is abstract
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
} else if (shapeType.equalsIgnoreCase("TRIANGLE")) {
return new Triangle();
}
return null;
}}
16
Factory pattern
 Exemple de modèle de conception Design Pattern
public class Main {
public static void main(String[] args){
ShapeFactory shapeFactory = new ShapeFactory();
Shape shape1 = shapeFactory.getShape("circle");
shape1.draw();//Drawing circle
Shape shape2 = shapeFactory.getShape("rectangle");
shape2.draw();//Drawing Rectangle
Shape shape3 = shapeFactory.getShape("square");
shape3.draw();//Drawing Square
}
}
check implementation in refactoring guru
17
2. Structural Patterns
 Structural Patterns : Expliquent comment assembler des
objets et des classes dans des structures plus importantes, tout
en conservant la flexibilité efficacité des structures.
 The Adapter Pattern
 Facade pattern
18
Adapter Pattern
 Permet à des interfaces incompatibles de travailler ensemble.
 Convertit l'interface d'une classe en une autre interface que le
client attend.
 Un composant intermédiaire est appelé «adaptateur» et fournit un
pont pour éliminer les incompatibilités dans deux systèmes
externes.
Adapter is a structural design pattern that allows objects with incompatible interfaces to
collaborate
19
Adapter Pattern
 Un exemple est de créer un adaptateur lorsqu'un objet existe
(l'adaptee) qui fournit la fonctionnalité souhaitée par le client, mais
n'implémente pas l'interface (cible) requise par le client.
 Supposons que nous ayons une interface MediaPlayer représentant un lecteur
multimédia avec des méthodes pour lire, mettre en pause et arrêter la lecture.
 Nous avons également une classe VLCPlayer qui implémente cette interface
avec sa propre implémentation spécifique.
 Maintenant, imaginons que nous voulions utiliser une classe MP3Player
existante qui a une interface différente mais que nous voulons toujours l'utiliser
comme lecteur multimédia dans notre application.
 Nous pouvons utiliser le Adapter Pattern pour adapter l'interface de MP3Player
à celle de MediaPlayer.
20
duck classes
turkey classes
Adapter Pattern
turkeyAdapter
// Interface représentant un lecteur multimédia standar
interface MediaPlayer {
void play();
void pause();
void stop();
}
// Classe représentant un lecteur VLC
class VLCPlayer implements MediaPlayer {
@Override
public void play() {
System.out.println("Lecture VLCPlayer");
}
@Override
public void pause() {
System.out.println("Pause VLCPlayer");
}
@Override
public void stop() {
System.out.println("Arrêt VLCPlayer");
} }
21
Adapter Pattern
// Classe représentant un lecteur MP3 existant avec une interface
différente
class MP3Player {
void playMP3() {
System.out.println("Lecture MP3Player");
}
void pauseMP3() {
System.out.println("Pause MP3Player");
}
void stopMP3() {
System.out.println("Arrêt MP3Player");
}
}
22
Adapter Pattern
// Adaptateur pour convertir l'interface MP3Player en une interface MediaPlayer
class MP3PlayerAdapter implements MediaPlayer {
private MP3Player mp3Player;
public MP3PlayerAdapter(MP3Player mp3Player) {
this.mp3Player = mp3Player;
}
@Override
public void play() {
mp3Player.playMP3();
}
@Override
public void pause() {
mp3Player.pauseMP3();
}
@Override
public void stop() {
mp3Player.stopMP3();
}
}
23
Adapter Pattern
// Utilisation du lecteur multimédia avec le Adapter Pattern
public class Main {
public static void main(String[] args) {
// Utilisation du lecteur VLCPlayer
MediaPlayer mediaPlayer1 = new VLCPlayer();
mediaPlayer1.play();
mediaPlayer1.pause();
mediaPlayer1.stop();
// Utilisation du lecteur MP3Player avec l'adaptateur
MP3Player mp3Player = new MP3Player();
MediaPlayer mediaPlayer2 = new
MP3PlayerAdapter(mp3Player);
mediaPlayer2.play();
mediaPlayer2.pause();
mediaPlayer2.stop();
}
}
24
Facade pattern
 Le modèle de façade cache les complexités du système et
fournit une interface au client à laquelle le client peut accéder
au système, cachant ainsi la complexité du sous-système aux
clients.
 Il permet de cacher les détails d'implémentation complexes du
sous-système aux clients, ce qui facilite son utilisation.
25
Facade pattern
Facade is a structural design pattern that provides a simplified interface to a library, a
framework, or any other complex set of classes.
 Dans l’exemple montré dans la figure ci-dessous, nous allons
créer une interface Shape et des classes concrètes
implémentant l'interface Shape.
 Une classe de façade ShapeMaker est définie dans l’étape
suivante.
26
Facade pattern
Étape 1 :Créer une interface.
Shape.java
public interface Shape {
void draw();
}
Etape 2 : Créer des classes concrètes implémentant la même interface.
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Rectangle::draw()");
}
}
27
Facade pattern
Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square::draw()");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Circle::draw()");
}
}
28
Facade pattern
Étape 3 :Créer une classe de façade: ShapeMaker.java
public class ShapeMaker {
private Shape circle;
private Shape rectangle;
private Shape square;
public ShapeMaker() {
circle = new Circle();
rectangle = new Rectangle();
square = new Square(); }
public void drawCircle(){
circle.draw(); }
public void drawRectangle(){
rectangle.draw(); }
public void drawSquare(){
square.draw(); } }
29
Facade pattern
Étape 4 : Utiliser la façade pour dessiner différents types de formes.
FacadePatternDemo.java
public class FacadePatternDemo {
public static void main(String[] args) {
ShapeMaker shapeMaker = new ShapeMaker();
shapeMaker.drawCircle();
shapeMaker.drawRectangle();
shapeMaker.drawSquare();
}
}
30
3. Behavioral Patterns
 Behavioral Patterns : Les modèles comportementaux prennent soin
de la communication efficace.
 Dans ces modèles de conception, l'interaction entre les objets devrait
toujours être faiblement couplé.
 Les Behavioral Patterns fournissent des mécanismes spécifiques pour
établir des interactions entre les objets.
 Ils définissent des rôles clairs pour chaque objet participant, indiquant
les responsabilités spécifiques de chaque objet dans le système.
 Exemples de Behavioral Patterns :
 Iterator pattern
 Strategy pattern
31
Iterator pattern
 Ce modèle est utilisé pour obtenir un moyen d'accéder aux
éléments d'un objet de collection de manière séquentielle sans
avoir besoin de connaître sa représentation interne (liste, pile,
arbre, etc.).
 Il est un patron de conception comportemental qui fournit un
moyen de parcourir séquentiellement les éléments d'une
collection sans exposer les détails de sa structure interne.
32
Iterator pattern
 Il permet d'itérer sur les éléments d'une collection de manière
uniforme, quel que soit le type de collection ou sa structure
sous-jacente (‫)بنيتها األساسية‬.
 C’est un modèle de conception relativement simple et
fréquemment utilisé.
 Il existe de nombreuses structures / collections de données
disponibles.
33
Iterator pattern
 Chaque collection doit fournir un itérateur qui lui permet de
parcourir ses objets. Cependant, ce faisant, il doit s'assurer
qu'il n'expose pas son implémentation.
 Quelle que soit sa structure, une collection doit fournir un
moyen d’accéder à ses éléments pour permettre au code de les
utiliser.
34
Iterator pattern
 Il y a plusieurs manières de parcourir une même collection .
 Iterator pattern fournit une manière générique (‫)طريقة عامة‬
d'itérer sur une collection indépendante de son type.
35
Iterator pattern
- first create iterator interface with all the iteration methods you want (make sure next(),
hasNext() are always present)
- then create the classes that represent the origins of objects you want to iterate
through whether it's list, linked list, tree, graph ..., then add a method to it called
generally createIterator that will return the specific iterator for each object
- then create an iterator for each of those objects, that implements iterator interface
- now go to main class, instanciate the objects and call createIterator on them then use
the methods of the iterator interface to interate through the objects
36
Strategy pattern
 Dans ce modèle, il crée des objets qui représentent diverses
stratégies et un objet de contexte dont le comportement varie
en fonction de son objet de stratégie.
 L'objet de stratégie modifie l'algorithme d'exécution de l'objet
de contexte.
Strategy is a behavioral design pattern that lets you define a family of algorithms, put
each of them into a separate class, and make their objects interchangeable
37
Strategy pattern
38
Strategy pattern
 Nous allons créer une interface Stratégie définissant une action et
des classes de stratégie concrètes implémentant l'interface Stratégie.
 Le contexte est une classe qui utilise une stratégie.
 La classe StrategyPatternDemo, utilisera des objets de contexte et
de stratégie pour démontrer le changement de comportement de
contexte en fonction de la stratégie qu'il utilise.
39
Strategy pattern
Étape 1 : Créer une interface.
Strategy.java
public interface Strategy {
public int doOperation(int num1, int num2);
}
Étape 2 :Créer des classes concrètes implémentant la même interface.
OperationAdd.java
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
} }
40
Strategy pattern
OperationSubstract.java
public class OperationSubstract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
OperationMultiply.java
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
41
Strategy pattern
Étape 3 : Créer une classe de contexte.
Context.java
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
42
Strategy pattern
Étape 4 : Utilisez le contexte pour voir le changement de comportement lorsqu'il
change de stratégie.
StrategyPatternDemo.java
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubstract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
43
Autres design pattern
Pattern de conception MVC (Modèle-Vue-Contrôleur)
Data Access Object pattern or DAO
Injection de Dépendances
44
Pattern de conception MVC
(Modèle-Vue-Contrôleur)
 MVC (Model-View-Controller) est une méthode de
conception qui organise l’interface homme-machine (IHM)
d’une application logicielle. Ce modèle d’architecture impose
la séparation entre : Données, Présentation, Traitements.
Cette séparation donne trois parties fondamentales:
 Modèle : représente les données. Il peut également représenter
un objet ou JAVA POJO transportant des données.
 Vue : représente l’interface utilisateur,
 Elle
n’effectue aucun traitement.
 Elle affiche les données fournit par le modèle.
 Contrôleur : gère l’interface entre le modèle et la vue ainsi que
il garde la vue et le modèle séparés.
45
Pattern de conception MVC
(Modèle-Vue-Contrôleur)
46
Data Access Object pattern or DAO
 En supposant que nous ayons un projet d'application Web qui
utilise la base de données MySQL.
 Nous utiliserons donc le pilote de MySQL pour interagir avec la
base de données. Mais dans un autre beau jour, le client veut
utiliser une base de données supplémentaire telle que PostgreSQL,
alors, nous devons modifier notre code pour qu'il soit compatible
avec cette base de données.
 Cela rend nos couches étroitement liées à la couche de persistance
lorsque nous passons à une autre base de données.
 Par conséquent, quelle est la solution pour empêcher le couplage
étroit d'autres couches avec la couche de persistance ?
47
Data Access Object pattern or DAO
 DAO est un moyen de réduire le couplage entre la logique
métier et la logique de persistance. La logique métier de
l'application a souvent besoin d'objets de domaine qui sont
persistants dans la base de données.
 L’un des principaux avantages d'utilisation du modèle DAO
est lors de la modification d'un mécanisme de persistance, la
couche de service n'a même pas besoin de savoir d'où
proviennent les données. Par exemple, si vous envisagez de
passer de MySQL à MongoDB, toutes les modifications
doivent être effectuées uniquement dans la couche DAO.
48
Data Access Object pattern or DAO
49
Inversion de Contrôle (IoC)
 Qu'est-ce que la dépendance en les classes ?
 Une classe dépend d'une autre classe pour effectuer certains travaux,
par exemple :
public class ClientA {
ServiceB service;
public void doSomething() {
String info = service.getInfo();
}
public class ServiceB {
public String getInfo() {
return "ServiceB’s Info";
}
}
}
Ici, la classe ClientA utilise la classe
ServiceB qui s'écrit comme ci-dessus.
La classe ClientA est dite dépendante
de la classe ServiceB, et ServiceB est
appelée une dépendance de ClientA.
50
Dépendance en les classes
 Ce type de dépendance est très trivial en programmation. Cependant, lorsque
le code de l'application devient plus gros et plus complexe, la dépendance
codée en dur entre les classes présente certains inconvénients :
 Le code est inflexible: il est difficile à maintenir et à étendre car lorsqu'une
classe dépend en permanence d'une autre classe, le changement vers la classe
dépendante nécessite un changement vers la classe dépendante. Et il est
impossible de changer la classe dépendante plus tard sans mettre à jour et
recompiler le code.
 Le code est difficile pour les tests unitaires car lorsque vous souhaitez
tester uniquement les fonctionnalités d'une classe, vous devez également
tester d'autres classes dépendantes.
 Le code est difficile à réutiliser car les classes sont étroitement couplées.
51
Inversion de Contrôle
 Inversion de Contrôle (inversion of control, IoC) : est un
principe du génie logiciel qui transfère le contrôle d'objets d'un
programme à un conteneur ou à un framework.
 Nous l'utilisons le plus souvent dans le cadre de la
programmation orientée objet.
 Le modèle de conception IOC (Inversion de Contrôle) est un
principe de conception logicielle qui met l'accent sur
l'inversion du contrôle entre différents composants logiciels.
52
Injection de Dépendances
 Il existe plusieurs façons de mettre en œuvre l'IOC, la
Injection de Dépendances (DI) étant l'une des techniques les
plus courantes.
 Injection de Dépendances permet de supprimer les
dépendances fortes entre les classes et de rendre notre
application faiblement couplée, extensible et maintenable.
 Injection de Dépendances (DI) : La technique où les
dépendances d'un composant sont fournies de l'extérieur,
généralement par injection de constructeur, injection de setter
ou injection d'interface.
53
Conclusion
 Les designs patterns représentent les meilleures pratiques
expérimentés par les développeurs de logiciels orientés objet.
 Des solutions aux problèmes généraux rencontrés par les
développeurs lors du développement de logiciels, ce qui
permet de gagner du temps.
 Les designs patterns rendent notre code facile à comprendre et
à déboguer.
 Cela conduit à un développement plus rapide et les nouveaux
54
membres de l'équipe le comprennent facilement.
Download