0% ont trouvé ce document utile (0 vote)
5 vues86 pages

Design Patterns en Java : Singleton et Plus

Le document présente l'implémentation des principaux design patterns en Java, en se concentrant sur leur utilité, leurs types et des exemples pratiques. Il détaille notamment le Singleton Design Pattern, qui assure qu'une classe n'a qu'une seule instance, et fournit des exemples d'utilisation, ainsi que des alternatives pour éviter les limitations de ce pattern. Les design patterns sont classés en trois catégories : création, structuration et comportement, offrant des solutions éprouvées à des problèmes de conception courants.

Transféré par

oelmoussawi
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)
5 vues86 pages

Design Patterns en Java : Singleton et Plus

Le document présente l'implémentation des principaux design patterns en Java, en se concentrant sur leur utilité, leurs types et des exemples pratiques. Il détaille notamment le Singleton Design Pattern, qui assure qu'une classe n'a qu'une seule instance, et fournit des exemples d'utilisation, ainsi que des alternatives pour éviter les limitations de ce pattern. Les design patterns sont classés en trois catégories : création, structuration et comportement, offrant des solutions éprouvées à des problèmes de conception courants.

Transféré par

oelmoussawi
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

JAVA – Implémentation des principaux

design patterns
1. À quoi servent les design patterns
2. Types de design patterns
3. Les principaux design patterns
ENSA Oujda ▪ Singleton Design Pattern
Cycle d’ingénieur - DSCC 1ère Année ▪ Dao Design Pattern
▪ Abstract Dao Design Pattern
▪ Decorator Design Pattern
POO en java ▪ Composit Design Pattern

Implémentation des ▪
Strategy Design Pattern
Observer Design Pattern
design patterns
Pour chaque design pattern, une démonstration qui montre:
▪ L’utilité du design pattern
▪ Le modèle: diagramme de classes
@[Link]@[Link] ▪ Un exemple : Modèle + son implémentation
▪AI - Data Science – Machine Learning – Deep Learning ▪ Un exercice avec solution
▪Java – J2EE – Angular - Design
▪Python - C- C++ - Data Structures - Optimization
Les design patterns: à quoi peuvent servir?
▪ Les design pattern présentent des bonnes pratiques de conception en se basant sur les expériences des autres
▪ Se sont des solutions éprouvées et réutilisables à des problèmes de conception courants.
▪ Ils offrent plusieurs avantages qui aident les développeurs à créer des systèmes robustes, flexibles et maintenables.
▪ Réutilisation: ils permettent de réutiliser des solutions éprouvées à des problèmes courants. En appliquant un pattern
approprié, les développeurs peuvent éviter de réinventer la roue et gagner du temps en utilisant des approches déjà
testées et validées.
▪ Maintenabilité: Les systèmes conçus en utilisant des design patterns sont généralement plus faciles à maintenir. Les
patterns fournissent une structure claire et compréhensible, ce qui facilite la compréhension du code et sa modification
ultérieure.
▪ Flexibilité: ils encouragent la conception de systèmes flexibles et extensibles
▪ Découplage: ils aident à réduire les dépendances entre les composants d'un système, ce qui facilite leur isolation, leur
testabilité et leur réutilisation.
▪ Communication facile: ils fournissent un vocabulaire commun pour décrire les solutions de conception.
▪ Résolution des problèmes complexes: Les design patterns offrent des stratégies éprouvées pour résoudre des problèmes
complexes de conception.
▪ Pour assurer ces points forts, les design patterns sont mis en place en se basant sur les interfaces et les classes abstraites
Les types de design patterns
▪ Il existe plusieurs design pattern
▪ Ils se sont classifiés en trois catégories:
▪ Les patterns de création
▪ Pour créer des objets de la manière la plus appropriée relativement au contexte
▪ Singleton, Factory, Abstract Factor, Builder, Prototype
▪ Les patterns de structuration
▪ Pour composer des objets avec des structures plus grande. Ils facilitent la création des relations entre les entités.
▪ Dao, Abstract Dao, Decorator, Composite, Adapter, Bridge, Façade, Flyweight, Proxy…
▪ Les patterns de comportements
▪ Pour décrire les interactions et la collaboration entre objets afin de répondre à des fonctionnalités complexes
▪ Observer, Strategy, State, Template Method, Visitor, Momento, Iterator..
JAVA – Implémentation des principaux
design patterns
1. À quoi servent les design patterns
2. Types de design patterns

ENSA Oujda
3. Les principaux design patterns
Cycle d’ingénieur - DSCC 1ère Année
▪ Singleton Design Pattern
▪ Dao Design Pattern
POO en java ▪ Abstract Dao Design Pattern
▪ Decorator Design Pattern
Implémentation de ▪ Composit Design Pattern
Singleton ▪ Strategy Design Pattern

Design Pattern Observer Design Pattern

Pour chaque design pattern, une démonstration qui montre:


▪ L’utilité du design pattern
▪ Le modèle: diagramme de classes
@[Link]@[Link] ▪ Un exemple : Modèle + son implémentation
▪AI - Data Science – Machine Learning – Deep Learning ▪ Un exercice avec solution
▪Java – J2EE – Angular - Design
▪Python - C- C++ - Data Structures - Optimization
POO en java
Présentation et Implémentation de
Singleton Design Pattern
Le design pattern singleton: à quoi peut servir?
▪ Le design pattern Singleton est utilisé pour garantir qu'une classe n'a ClasseSingleton
qu'une seule instance et fournit un point d'accès global à cette instance
{Class final}
▪ L’objectif est de partager des ressources (data) au sein de la même application
- instance: ClasseSingleton
▪ Pour réussir à répondre à ce besoin:
- data: type
1. Le constructeur doit être private: il faut le surcharger
2. Ajouter un attribut private static de type ClasseSingleton : instance qui
représente la ressource partagée - ClasseSingleton()
3. Fournir une méthode qui permet de créer l’instance sil elle n’existe pas et +getInstance(): ClasseSingleton
de la renvoyer: méthode qui doit être static +Operations():type
▪ Cette instance permet l’accès à la partie data qui est unique dans toute
l’application
▪ Avec cette modélisation,
▪ La classe Program, la classe A et toute autre classe peuvent utiliser la même A B Program
instance
▪ La méthode f(), la méthode g() et le main utilisent la même référence « instance » +f():void
▪ Et ainsi, toutes ces méthodes partagent la même « data » +g():void
▪ Data peut être un seul attribut, ou plusieurs attributs
Pendant l’exécution ClasseSingleton
@7852e922 - data: type
Une data
Une instance de ClassSingleton
Avoir
… dans toute l’application
Ref créée

Au lieu de
@15db9742 @6d06d69c @7852e922

Une data Une data Une data

… … …
Ref créée avec class1 Ref créée avec class2 Ref créée avec class3
Sans singleton ClasseNotSingleton
class A { final class ClasseNotSingleton { - data: type
public void f(){ private String data="une data";
ClasseNotSingleton s=new ClasseNotSingleton(); public ClasseNotSingleton(){
[Link]("ref créée dans f: "+s); + ClasseNotSingleton()
} }
} public String getData() {
+getData():type
class B { return data; +setData(type):void
public void g(){ }
ClasseNotSingleton s=new ClasseNotSingleton(); public void setData(String data){
[Link]("ref créée dans g: "+s); [Link] = data;
} }
} A B Program
public class Program { } +g():void
+f():void
public static void main(String[] args) {
ClasseNotSingleton s=new ClasseNotSingleton();
▪ Combien d’instance de de la classe S sont créées suite à l’exécution de
[Link]("ref créée dans main: "+s);
A a =new A(); ce code source?
a.f();
▪ Modifier le code source de manière à ce que une seule instance de
B b=new B();
b.g();
ClasseNotSingleton soit créé et qui peut servir à la classe A, B et
} Program
} ▪ Comment procéder?
Mise en œuvre d’un Singleton (1/3)
ClasseSingleton class ClasseSingleton { Class A
private String data="une data";
private ClasseSingleton(){ Public void f(){
- instance: ClasseSingleton } ClasseSingleton s=new ClasseSingleton();
- data: type public String getData() { }
return data;
} Class B
- ClasseSingleton() public void setData(String data){
[Link] = data; Public void g(){
+getInstance(): ClasseSingleton } ClasseSingleton s=new ClasseSingleton();
+Operations():type }
public ClasseSingleton getInstance(){
Class Program
}
Public static void void main(Stirnt T[]){
A B Program ClasseSingleton s=new ClasseSingleton();
}
}
+f():void +f():void

▪ Compléter le code source de getInstance() afin de garantir qu’une seule instance de instance soit créée
Mise en œuvre d’un Singleton (2/3)
ClasseSingleton class ClasseSingleton { Class A
private static ClasseSingleton
instance; public void f(){
- instance: ClasseSingleton private String data="une data"; ClasseSingleton obj=[Link]()
}
- data: type private ClasseSingleton(){
}
public String getData() { Class B
- ClasseSingleton() return data; public void f(){
}
+getInstance(): ClasseSingleton public void setData(String data){
ClasseSingleton obj=[Link]()
}
+Operations():type [Link] = data;
}public static ClasseSingleton
getInstance() {
if (instance == null) Class Program
instance = new ClasseSingleton();
return instance; public static void void main(Stirnt T[]){
A B Program } ClasseSingleton obj=[Link]()
}
+f():void +f():void
}
▪ Compléter le code de manière à prendre le cas d’accès concurrent à la mémoire: synchronization
Mise en œuvre d’un Singleton (3/3)
class ClasseSingleton {
ClasseSingleton private static ClasseSingleton
instance;
- instance: ClasseSingleton private String data="une data";
- data: type private ClasseSingleton(){
}
public String getData() { public static ClasseSingleton
- ClasseSingleton() return data; getInstance() {
} if (instance == null) {
+getInstance(): ClasseSingleton public void setData(String data){ synchronized ([Link]) {
+Operations():type [Link] = data; if (instance == null) {
}public static ClasseSingleton instance = new ClasseSingleton();
getInstance() {
}
if (instance == null)
instance = new ClasseSingleton();
}
return instance; }
A B Program } return instance;
}
+f():void +f():void
}
▪ Ce code source utilise la technique de Double-Checked Locking
Quelques cas d’utilisation du design pattern singleton (1)
▪ Gestion des ressources partagées : Code
▪ une ressource partagée unique, comme: client 1
Connection DB
▪ Connexion à une base de données Code
client 1
▪ un gestionnaire de fichiers

▪ etc.
▪ Le design pattern singleton garantit qu'une seule instance de cette DataBaseConnection
ressource et elle est utilisée à travers toute l'application.
- instance: DataBaseConnection
▪ Ainsi, la connection est unique dans toute l’application: partie en - connection: Connection
bleue
- DataBaseConnection()
▪ Ceci évite le serveur de créer plusieurs connections (problème +getInstance(): DataBaseConnection
mémoire) +Operations():type

Program ClientManagement ProductManagement

+getAll(): List<Client> +getAll(): List<Client>


… …
Connexion à une base de données: Avec Singleton et sans singleton
Au lieu de

ProgUser1
Connexion
Instance 1
ProgUser2
Instance 2
Instance 3
ProgUser3

Utiliser le Singleton

ProgUser1
Connexion

ProgUser2 Une seule instance

ProgUser3

NB. selon la taille de l’application, le singleton de connexion peut présenter des limites
Accès aux bases de données: utiliser le design pattern Singleton (1/2)
package part2.chap9.design_patterns.singleton.example2;
import [Link];
import [Link]; public static DataBaseConnection getInstance() {
import [Link]; if (instance == null) {
public class DataBaseConnection { synchronized ([Link]) {
private static DataBaseConnection instance; if (instance == null) { instance = new
private Connection connection = null; DataBaseConnection();}
} getInstance
private DataBaseConnection() { }
String url = "jdbc:mysql://localhost:3306/store"; return instance;
String user = "root"; }
String password = ""; Constructeur privé: Operations
Il initialise la connection public Connection getConnection() {
try { return connection;
connection = [Link](url, user, password); }
} catch (SQLException e) { [Link]();}
}
}
Accès aux bases de données: utiliser le design pattern Singleton (2/2)
package part2.chap9.design_patterns.singleton.example2;
import [Link];
import [Link];
import [Link];
import [Link];
public class Program {
public static void main(String[] args) {
DataBaseConnection dbConnection=[Link]();
Connection connection =[Link]();
String sql="select * from product where price>?";
try {
PreparedStatement prst=[Link](sql);
[Link](1, 1000);//les produits dont le prix >200
ResultSet rs=[Link]();
while([Link]()){
[Link]([Link]("designation")+ " "+[Link]("price"));
}
} catch (SQLException e) {
[Link]();
}
}
}
Accès aux bases de données: Limites du design pattern Singleton
▪ Peut devenir un goulot d'étranglement si l'application nécessite de Code
nombreuses connexions simultanées. client 1
▪ La connexion unique peut entraîner des problèmes de performance Connection DB
Code
et de scalabilité
client 1
▪ Rend le code moins flexible et plus difficile à tester, notamment en
raison de la difficulté de mocker une instance Singleton dans les
tests unitaires.

Alternatives
1. Pool de Connexions: gérer un ensemble de connexions réutilisables, améliorant ainsi la performance et la
scalabilité
2. Injection de Dépendances: améliorer la flexibilité et la testabilité et permet de remplacer facilement les
dépendances
3. Framework-Managed Connections: Hibernate, Sprind Data
Quelques cas d’utilisation du design pattern singleton (2)
▪ Informations de configuration : Code
▪ Un objet ayant ces informations est unique pour toute l’application, client 1
comme: Config File
Code
▪ Paramétrage du stock client 1

▪ Le design pattern singleton garantit qu'une seule instance de cet
objet de configuration utilisée à travers toute l'application.
ConfigStock
▪ Ainsi, les informations de configurations sont uniques dans toute
- instance: ConfigStock
l’application: partie en bleue
- yearOfStock: int
- tva: double
- ConfigStock()
+getInstance(): ConfigStock
+Operations():type

Product Program
-name:String OtherProgram …
-price:double
+methode():type
Quelques cas d’utilisation du design pattern singleton (2)
Soit le code source suivant de la classe ConfigStock
public class ConfigStock { Code
private int yarOfStock; client 1
private double tva=0.2; Config File
public void printConfig(){ Code
[Link]("Year:"+yarOfStock); client 1
[Link]("Tva:"+tva); …
}
}
ConfigStock
Questions: - instance: ConfigStock
1. Pourquoi ce code ne permet pas d’avoir la même configuration dans - yearOfStock: int
toute l’application? - tva: double
2. Modifier ce code afin d’assurer la création d’une seule configuration
dans toute l’application? - ConfigStock()
+getInstance(): ConfigStock
+Operations():type

Product Program
-name:String OtherProgram …
-price:double
+methode():type
Exercice - Singleton
Développer une application pour la gestion de la bourse.
1. L'application doit permettre de gérer les cours des actions, les transactions, et les paramètres de configuration de la bourse.
▪ Le code de cette partie est supposé donné
2. L’application doit garantir qu'il n'existe qu'une seule instance de la configuration de la bourse à travers l'application.
▪ Le programme principale créé une instance de la configuration et l’initialise
▪ La classe Other imprime la même configuration avec sa méthode Print
La configuration se trouve dans la classe MarketConfiguration et concerne les données suivantes :
Market Market Name: Global Action Exchange
Opening Time: 08:00
Closing Time: 18:00 Other
Transaction
* +print():void
Action +buyAction(string name, double price): void
-name:String +sellAction(String name):void
-price:double
MarketConfiguration
marketName: String
Program openingTime: String
Questions closingTime: String
1. Pourquoi cette modélisation n’assure pas la création d’une seule configuration
• Analyser le code source de Program +printConfig():void
2. Faire les modifications nécessaires afin d’assurer la création d’une seule
configuration
Le programme principal est:
public class Program { Résultat du programme:
public static void main(String[] args) {
[Link]("Config..."); Config main..
MarketConfiguration config = new Market : Global Action Exchange
MarketConfiguration("Global Action Exchange","08:00","18:00"); Opening Time: 08:00
[Link](); Closing Time: 18:00
// Gestion des transactions Gestion des transactions------
[Link]("Gestion des transactions--"); Acheter des actions
Transaction transaction = new Transaction(); achat action: AWS au prix: 150.0
// Acheter des actions achat action: GOOGLE au prix: 2800.0
[Link]("Acheter des actions"); liste des actions:
[Link]("AWS", 150.00); Action: AWS, Prix: 150.0
[Link]("GOOGLE", 2800.00); Action: GOOGLE, Prix: 2800.0
// Lister les actions achetées Vente de aws
[Link](); Vente action: AWS au prix: 150.0
// Vendre une action liste des actions:
[Link]("Vente de aws"); Action: GOOGLE, Prix: 2800.0
[Link]("AWS"); Config other..
// Lister les actions après vente Market : Global Action Exchange
[Link](); Opening Time: 08:00
[Link]("other..."); Closing Time: 18:00
Other other=new Other();
[Link]();
}
}
Le design pattern Singleton en data science
▪ Dans de nombreuses applications de data science (ex. prédiction, scoring, NLP...), il est
souvent nécessaire de charger un modèle entraîné en mémoire (fichier .model, .pkl, etc.).
▪ Or, ce modèle peut être coûteux à charger, donc on souhaite qu’une seule instance soit
créée et utilisée dans toute l’application.
JAVA – Implémentation des principaux
design patterns
1. À quoi servent les design patterns
2. Types de design patterns

ENSA Oujda
3. Les principaux design patterns
Cycle d’ingénieur - DSCC 1ère Année
▪ Singleton Design Pattern
▪ Dao Design Pattern
POO en java ▪ Abstract Dao Design Pattern
▪ Decorator Design Pattern
Implémentation de ▪ Composit Design Pattern
DAO ▪ Strategy Design Pattern

Design Pattern Observer Design Pattern

Pour chaque design pattern, une démonstration qui montre:


▪ L’utilité du design pattern
▪ Le modèle: diagramme de classes
@[Link]@[Link] ▪ Un exemple : Modèle + son implémentation
▪AI - Data Science – Machine Learning – Deep Learning ▪ Un exercice avec solution
▪Java – J2EE – Angular - Design
▪Python - C- C++ - Data Structures - Optimization
POO en java
Présentation et Implémentation de
Dao Design Pattern
Le design pattern Dao: à quoi peut servir? Product
<<entity>>
Class diagram
▪ Il permet de gérer les interactions avec une base de données en séparant -id:long
la logique d’accès aux données de la logique métier/ présentation de -designation:String
données -price:double
▪ Le code source pour manipuler les données à travers les
opérations CRUD (create, researsh, update, delete) est isolé
dans des classes spécifiques (les DAOs)
ProductDao
▪ Il permet de faciliter la maintenance du code: tout changement qui <<interface>>
concerne l’accès aux données n’influence pas sur la logique métier/ +addProduct(Product product):void
présentation de données. +deleteProduct(long id):void
+updateProduct(long id):void
▪ Réduire le risque d’introduire des bug +getOneProduct(long id):Product
▪ Il permet de favoriser la réutilisation du code: tout DAO implémenté +getAll():List< Product >
peut être utilisé par autre composants sans duplication de code. +getByKeyWord(String keyword):List<Produit>

ProductDAO

Business / Data Access


Presentaton ProductDaoImpl Business /
Layer
Presentaton
Une autre représentation graphique Layer
<<Component diagram>>
Remarque: DataBaseConnection
On suppose que le code DataBaseConnection est fourni <<singleton>>
Sans Dao
▪ Dans le cas où nous avons une application qui accèdent à une base de données, ne pas utiliser
Product
le design pattern peut entrainer des problèmes
<<entity>>
▪ Problème de maintenance: Les mêmes modifications seront dupliquées dans différentes
parties de code: ce qui complique la maintenance -id:long
▪ changement dans la structure de la base de données -designation:String
-price:double
▪ Changement de SGBD
▪ Manque de réutilisation : le développement d’un nouveau composant conduit à une
duplication inutile
▪ Violation du principe séparation de rôles
App2 App1

DataBaseConnection
<<singleton>>
Sans Dao ( code source 1/3)
public class DataBaseConnection { Product
private static DataBaseConnection instance; <<entity>>
private Connection connection = null; -id:long
private DataBaseConnection() { -designation:String
String url = "jdbc:mysql://localhost:3306/store"; -price:double
String user = "root";
String password = "";
try {
connection = [Link](url, user, password);
} catch (SQLException e) {[Link]();}
App2 App1
}
public Connection getConnection() {return connection;}
public static DataBaseConnection getInstance() {
if (instance == null) {
synchronized ([Link]) {
if (instance == null) { DataBaseConnection
instance = new DataBaseConnection(); <<singleton>>
}
}
}
return instance;
}
}
Sans Dao (code source 2/3)
public class App1 { Product
static List<Product> getAllProducts() { <<entity>>
DataBaseConnection dbConnection = [Link]();
Connection connection = [Link]();
-id:long
List<Product> products = new ArrayList<>(); -designation:String
String sql = "select * from product"; -price:double
try {
PreparedStatement prst = [Link](sql);
ResultSet rs = [Link]();
while ([Link]()) {
[Link](new Product([Link]("id"), App2 App1
[Link]("designation"), [Link]("price")));
}
} catch (SQLException e) {[Link]();}
return products;
}
public static void main(String[] args) { DataBaseConnection
List<Product> products=getAllProducts();
for(Product p:products)
<<singleton>>
[Link](p);
}
}
Sans Dao (code source 3/3)
public class App2 { Product
static List<Product> getAllProducts() { <<entity>>
DataBaseConnection dbConnection = [Link]();
Connection connection = [Link]();
-id:long
List<Product> products = new ArrayList<>(); -designation:String
String sql = "select * from product"; -price:double
try {
PreparedStatement prst = [Link](sql);
ResultSet rs = [Link]();
while ([Link]()) {
[Link](new Product([Link]("id"), App2 App1
[Link]("designation"), [Link]("price")));
}
} catch (SQLException e) {[Link]();}
return products;
}
public static void main(String[] args) { DataBaseConnection
List<Product> products=getAllProducts();
for(Product p:products)
<<singleton>>
[Link](p);
}
}

▪ Problèmes de maintenance qui peuvent avoir lieu


▪ Modifier la structure de la base de données
Design pattern DAO: isoler le code qui manipule Product
<<entity>>
la base données -id:long
-designation:String
▪ Éviter les problèmes de maintenance -price:double
▪ Séparer la logique d’accès aux données de la logique métier

ProductDao
<<interface>>
+addProduct(Product product):void
+deleteProduct(long id):void
+getOneProduct(long id):Product
+getAll():List< Product >
+getByKeyWord(String keyword):List<Produit>

ProductDaoImpl Business /
Presentaton
Layer

DataBaseConnection
<<singleton>>
Design pattern DAO: code source (1/4) Product
<<entity>>
public class DataBaseConnection { -id:long
private static DataBaseConnection instance; -designation:String
private Connection connection = null; -price:double
private DataBaseConnection() {
String url = "jdbc:mysql://localhost:3306/store";
String user = "root";
String password = "";
ProductDao
try {
<<interface>>
connection = [Link](url, user, password);
} catch (SQLException e) {[Link]();} +addProduct(Product product):void
} +deleteProduct(long id):void
public Connection getConnection() {return connection;} +getOneProduct(long id):Product
public static DataBaseConnection getInstance() { +getAll():List< Product >
if (instance == null) { +getByKeyWord(String keyword):List<Produit>
synchronized ([Link]) {
if (instance == null) {
instance = new DataBaseConnection();
}
} ProductDaoImpl
} Business /
Presentaton
return instance;
Layer
}
}
DataBaseConnection
<<singleton>>
Design pattern DAO: code source (2/4) Product
<<entity>>
public class Product { -id:long
private long id; -designation:String
private String designation; -price:double
private double price;
public Product(long id, String designation, double price) {
[Link] = id;
[Link] = designation;
ProductDao
[Link] = price;
<<interface>>
}
//getters & setters +addProduct(Product product):void
@Override +deleteProduct(long id):void
public String toString() { +getOneProduct(long id):Product
return "Product [id=" + id + ", designation=" + designation + ", price=" + price + "]"; +getAll():List< Product >
} +getByKeyWord(String keyword):List<Produit>
}

public interface ProductDAO {


void addProduct(Product product);
Product getOneProduct(long id); ProductDaoImpl Business /
List<Product> getAllProducts(); Presentaton
List<Product> getByKeyWord(String key); Layer
void updateProduct(Product product);
void deleteProduct(long id); DataBaseConnection
} <<singleton>>
Design pattern DAO: code source (3/4) Product
<<entity>>
public class ProductDAOImpl implements ProductDAO {
Connection connection = [Link]().getConnection(); -id:long
@Override -designation:String
public void addProduct(Product product) { -price:double
String sql = "insert into product(designation,price) values(?,?)";
try {
PreparedStatement prst = [Link](sql);
[Link](1, [Link]()); ProductDao
[Link](2, [Link]()); <<interface>>
[Link]();
} catch (SQLException e) {[Link]();} +addProduct(Product product):void
} +deleteProduct(long id):void
@Override +getOneProduct(long id):Product
public Product getOneProduct(long id) { +getAll():List< Product >
Product product = null; +getByKeyWord(String keyword):List<Produit>
String sql = "select * from product where id=?";
try {
PreparedStatement prst = [Link](sql);
[Link](1, id);
ResultSet rs = [Link](); ProductDaoImpl Business /
if ([Link]()) { Presentaton
product = new Product([Link]("id"), [Link]("designation"), [Link]("price")); Layer
}
} catch (SQLException e) {[Link]();}
return product; DataBaseConnection
}... <<singleton>>
Design pattern DAO: code source (3/4) Product
<<entity>>
@Override -id:long
public void updateProduct(Product product) { -designation:String
String sql = "update product set designation=?,price=? where id=?";
-price:double
try {
PreparedStatement prst = [Link](sql);
[Link](1, [Link]());
[Link](2, [Link]());
ProductDao
[Link](3, [Link]());
<<interface>>
[Link]();
} catch (SQLException e) { [Link](); } +addProduct(Product product):void
} +deleteProduct(long id):void
@Override +getOneProduct(long id):Product
public void deleteProduct(long id) { +getAll():List< Product >
String sql = "delete from product where id=?"; +getByKeyWord(String keyword):List<Produit>
try {
PreparedStatement prst = [Link](sql);
[Link](1, id);
[Link]();
} catch (SQLException e) { [Link]();}
ProductDaoImpl Business /
}
Presentaton
Layer

DataBaseConnection
<<singleton>>
Design pattern DAO: code source (3/4) Product
<<entity>>
@Override -id:long
public List<Product> getByKeyWord(String key) { -designation:String
List<Product> products = new ArrayList<>(); -price:double
String sql = "select * from product where designation like ?";
try {
PreparedStatement prst = [Link](sql);
[Link](1, "%"+key+"%");
ResultSet rs = [Link](); ProductDao
while ([Link]()) { <<interface>>
[Link](new Product([Link]("id"), [Link]("designation"),
[Link]("price"))); +addProduct(Product product):void
} +deleteProduct(long id):void
} catch (SQLException e) { +getOneProduct(long id):Product
+getAll():List< Product >
[Link]();
+getByKeyWord(String keyword):List<Produit>
}
return products;

ProductDaoImpl Business /
Presentaton
Layer

DataBaseConnection
<<singleton>>
Design pattern DAO: code source (4/4) Product
<<entity>>
public class Program { -id:long
public static void main(String[] args) { -designation:String
ProductDAO pdao=new ProductDAOImpl(); -price:double
[Link]("add:");
[Link](new Product(0,"Chemise Titi",150));
[Link]("getById:");
Product p=[Link](113); ProductDao
<<interface>>
[Link](p);
[Link]("getAllByKey:"); +addProduct(Product product):void
List<Product> products=[Link]("Chemise"); +deleteProduct(long id):void
for(Product pr:products) +getOneProduct(long id):Product
[Link](pr); +getAll():List< Product >
+getByKeyWord(String keyword):List<Produit>
}
}

ProductDaoImpl Business /
Presentaton
Layer

DataBaseConnection
<<singleton>>
Design pattern DAO: code source (4/4) client
<<entity>>
-id:long
-firstName:String
-lastName:String
-[Link]
-email:String

ClientDao
<<interface>>
+addClient(Client client):void
+deleteClient(long id):void
+getOneClient(long id):Client
+getAll():List< Client >
+getByKeyWord(String keyword):List<Client>

ClientDaoImpl Business /
Presentaton
Layer

DataBaseConnection
<<singleton>>
POO- JAVA: Présentation et Implémentation de
Dao design pattern
Exercice
Ajouter le module gestion des clients qui permet la manipulation de la table client de la même
base de données en utilisant Dao Design pattern
JAVA – Implémentation des principaux
design patterns
1. À quoi servent les design patterns
2. Types de design patterns

ENSA Oujda
3. Les principaux design patterns
Cycle d’ingénieur - DSCC 1ère Année
▪ Singleton Design Pattern
▪ Dao Design Pattern
POO en java ▪ Abstract Dao Design Pattern
▪ Decorator Design Pattern
Implémentation de ▪ Composit Design Pattern
Abstract DAO ▪ Strategy Design Pattern

Design Pattern Observer Design Pattern

Pour chaque design pattern, une démonstration qui montre:


▪ L’utilité du design pattern
▪ Le modèle: diagramme de classes
@[Link]@[Link] ▪ Un exemple : Modèle + son implémentation
▪AI - Data Science – Machine Learning – Deep Learning ▪ Un exercice avec solution
▪Java – J2EE – Angular - Design
▪Python - C- C++ - Data Structures - Optimization
POO en java
Présentation et Implémentation de
Abstract Dao Design Pattern
Le design pattern Abstract Dao: à quoi peut servir?
▪ Il fournit une structure générique pour les DAOs concrets GenericDao<T>
Product
<<interface>>
▪ Il peut centraliser les parties communes entre les DAO concrets +add(T obj):void -id:long
▪ La logique d’accès aux données +delete(long id):void -designation:String
+getOne(long id):T -price:double
▪ Il est possible de définir les éléments spécifiques dans les Daos +getAll():List<T>
concrets
▪ getByKeyWord(String keyword) dans la classe ProductDao
▪ La méthode getUser(String login, String password) dans la
classe User ProductDao
<<interface>>
▪ Il permet d’intégrer autres modules en minimisant la duplication du
code +getByKeyWord(String keyword):List<Produit>

▪ Exemple: Ajouter un module pour la gestion des utilisateurs

ProductDaoImpl Business /
Presentaton
Layer

DataBaseConnection
AbstractDao <<singleton>>
Le design pattern Abstract Dao: à quoi peut servir?
GenericDao<T>
User Product
<<interface>>
-id:long +add(T obj):void -id:long
-login:String +delete(long id):void -designation:String
-password:String +getOne(long id):T -price:double
+getAll():List<T>

UserDao ProductDao
Business / <<interface>> <<interface>>
Presentaton
+getUser(String login, String password): User +getByKeyWord(String keyword):List<Produit>
Layer User

▪ Le module de gestion des utilisateurs est ajouté


facilement
▪ La même logique peut s’appliquer à autres UserDaoImpl ProductDaoImpl
modules Business /
Presentaton
Layer Product
▪ Sois structuré et réfléchi comme un
« architect coder »
▪ Ne sois pas impulsif et désorganisé comme DataBaseConnection
AbstractDao <<singleton>>
un « vibe coder ».
POO- JAVA: Présentation et Implémentation de
Abstract Dao design pattern
Exercice

Ajouter le module gestion des clients qui permet la manipulation de la table client de la même
base de données en utilisant Abstract Dao Design pattern
Le design pattern Abstract DAO en data science
▪ dans un projet de Data Science appliqué et déployé, où l'on gère des volumes de données et
des résultats à stocker durablement, le pattern DAO structure le code, isole les
responsabilités et rend le système évolutif.
▪ Stocke dans une base de données :
▪ Les données d'entraînement,
▪ Les résultats de prédictions,
▪ Les métriques d’évaluation du modèle.
JAVA – Implémentation des principaux
design patterns
1. À quoi servent les design patterns
2. Types de design patterns

ENSA Oujda
3. Les principaux design patterns
Cycle d’ingénieur - DSCC 1ère Année
▪ Singleton Design Pattern
▪ Dao Design Pattern
POO en java ▪ Abstract Dao Design Pattern
▪ Decorator Design Pattern
Implémentation de ▪ Composit Design Pattern
Decorator ▪ Strategy Design Pattern

Design Pattern Observer Design Pattern

Pour chaque design pattern, une démonstration qui montre:


▪ L’utilité du design pattern
▪ Le modèle: diagramme de classes
@[Link]@[Link] ▪ Un exemple : Modèle + son implémentation
▪AI - Data Science – Machine Learning – Deep Learning ▪ Un exercice avec solution
▪Java – J2EE – Angular - Design
▪Python - C- C++ - Data Structures - Optimization
POO en java
Présentation et Implémentation de
Decorator Design Pattern
IComponent
Le design pattern decorator: à quoi peut servir? Component +methodes()
▪ Il permet d’ajouter ou de modifier des fonctionnalités sans modifier les classes d'origine #structure
o il favorise « open/closed principle »
+methodes ()
▪ Il permet donc de créer des objets flexibles et extensibles en minimisant le risque de bugs
1 ConcretComponent
▪ Il permet de responsabiliser les objets: chaque décorateur est responsable d’une seule
fonctionnalité ou d’un petit groupe de fonctionnalité
o Il favorise « single responsibility principle »
AbstractDecorator
Objet Objet
décoré décoré

ConcreteDecorator

Objet de
base Objet
décoré

Objet de Objet a Objet b Objet c


base: a décoré: b décoré: c décoré: d

▪ Ajouter à l’objet de base des objets qui le décorent


Sans utiliser le design pattern decorator
▪ Modèle classique: modifier la structure de la classe de base et les classes filles

Repas{abstract} Couscous
Carotte
sauce
Viande
Ognon Courgette
raisinSec Big courgette rouge
… …
+getCout():double {abstract}
+getDescription():String {abstract} Tajine
Olive
Citron

▪ À chaque fois, on modifie la structure de base


o Risques de bug
o Maintenance difficile
Utiliser le design pattern decorator: une application pour commander des repas personnalisés
IRepas{interface}
▪ À partir d’un objet de base (ayant un sens), on ajoute
+getDescription():String
des décorateurs pendant l’EXECUTION
+getCout():double
▪ Le décorateur est un objet qui décore un autre objet
▪ Le résultat de chaque opération (décorer) est un
décorateur Repas{abstract}
DecoratorRepas{abstract}
▪ Une utilisation isolée du décorateur n’as pas de sens #cout:double
1
+Repas(double c) +DecoratorRepas(Repas repas,double c)

Couscous Carotte Sauce


Tajine
Viande
Ognon

Courgette
RaisinSec

Couscous + sauce+ carotte+ courgette+ viande Olive


Price:80.0
Citron
Design pattern Decorator: Code JAVA (1/3)
public interface IRepas { IRepas{interface}
public String getDescription(); +getDescription():String
public double getCout(); +getCout():double
}
public abstract class Repas implements IRepas{
protected double cout; Repas{abstract}
public Repas(double cout){ DecoratorRepas{abstract}
[Link]=cout; #cout:double
}
1
+Repas(double c) +DecoratorRepas(Repas repas,double c)
@Override
public double getCout(){
return cout;
} Couscous Carotte Sauce
Tajine
}
Viande
public class Couscous extends Repas { Ognon
public Couscous(double cout) {
super(cout); Courgette
RaisinSec
}
@Override Olive
public String getDescription() {
return "Couscous "; public class Tajine extends Repas {
Citron
} ...
} }
Design pattern Decorator: Code JAVA (2/3)
public class Viande extends DecoratorRepas { IRepas{interface}
public Viande(Repas repas,double cout) {
super(repas,cout); +getDescription():String
} +getCout():double
@Override
public String getDescription() {
return [Link]() + "+ viande";
}
@Override Repas{abstract}
public double getCout() {
DecoratorRepas{abstract}
#cout:double
return [Link]() + cout; 1
} +Repas(double c) +DecoratorRepas(Repas repas,double c)
}

public class Courgette extends DecoratorRepas{


public Courgette(Repas repas,double cout) { Carotte
super(repas,cout); Tajine Couscous Sauce
}
@Override Viande
public String getDescription() {
Ognon
return [Link]()+ "+ courgette";
Courgette
} RaisinSec
@Override
public double getCout() { Olive
return [Link]()+cout;
} ▪ La même logique d’implémentation pour les Citron
} autres classes filles de DecoratorRepas
Design pattern Decorator: Code JAVA (3/3)
IRepas{interface}
+getDescription():String
public class Program { +getCout():double
public static void main(String[] args) {
Repas repas=new Couscous(45);//objet de base:(couscous,45)
repas=new Sauce(repas,5); //décorator :(sauce,5)
repas=new Carotte(repas,5); //décorator:(carrote,5)
repas=new Courgette(repas,10); //décorator:(courgette,10) Repas{abstract}
repas=new Viande(repas,15); //décorator: (viande,15)
DecoratorRepas{abstract}
#cout:double
[Link]( [Link]()); 1
[Link]( "Price:"+[Link]()); +Repas(double c) +DecoratorRepas(Repas repas,double c)
}
}

Carotte
▪ Créer un objet de base Tajine Couscous Sauce
▪ Puis le décorer par autres objets
Viande
Ognon
Résultat de l’exécution:
Couscous + sauce+ carotte+ courgette+ viande Courgette
Price:80.0 RaisinSec

Olive

Citron
POO- JAVA: Présentation et Implémentation de
Decorator Design Pattern
Exercice 1:
Vous travaillez pour une agence de voyages qui souhaite développer un système de gestion de packages
touristiques.
Le système doit permettre d'ajouter dynamiquement des options supplémentaires aux packages de base sans
modifier leur code de base. Un package de base est un séjour avec un nombre de nuits. Le prix à la nuit est à gérer.
Chaque option doit modifier le coût et la description du package.
Exemples d’options: visites guidées, des repas, des assurances voyage, etc.
Travail demandé:
1. Proposer le modèle sous forme d’un diagramme de classes
2. Donner une implémentation
3. Tester votre code source:
▪ Créer un package de base
▪ Ajouter autres packages
▪ Afficher la description finale du package: description + prix
Le design pattern Decorator en data science
1. Dans le Pipeline de transformations de données (Data preprocessing):
▪ Souvent, on doit appliquer plusieurs traitements successifs à des datasets (extraction de features, normalisation,
nettoyage, encodage, etc.).
▪ Avec le pattern Decorator, on peut enchaîner dynamiquement des transformations sans modifier les classes de
base.
▪ Chaque étape ajoute une « couche » de traitement en décorant la précédente.
Par exemple, dans des frameworks ML ou personnalisés, chaque préprocesseur est un décorateur qui ajoute sa
fonction à la chaîne.

2. Extension dynamique de modèles prédictifs


▪ Pour créer un modèle de machine learning, on peut partir d’un modèle de base simple (base model)
▪ puis l’améliorer progressivement en lui ajoutant des fonctionnalités ou des optimisations.
▪ Chaque amélioration peut être vue comme un décorateur qui vient envelopper le modèle initial, ajoutant un
nouveau comportement sans modifier le modèle de base.
▪ Cela permet de construire des modèles complexes de façon modulaire, tout en réutilisant efficacement le code.
▪ Ce mécanisme peut aider à économiser des ressources de calcul, car on applique uniquement les améliorations
nécessaires, sans dupliquer ou recalculer inutilement l’ensemble du modèle."
JAVA – Implémentation des principaux
design patterns
1. À quoi servent les design patterns
2. Types de design patterns

ENSA Oujda
3. Les principaux design patterns
Cycle d’ingénieur - DSCC 1ère Année
▪ Singleton Design Pattern
▪ Dao Design Pattern
POO en java ▪ Abstract Dao Design Pattern
▪ Decorator Design Pattern
Implémentation de ▪ Composit Design Pattern
Composit ▪ Strategy Design Pattern

Design Pattern Observer Design Pattern

Pour chaque design pattern, une démonstration qui montre:


▪ L’utilité du design pattern
▪ Le modèle: diagramme de classes
@[Link]@[Link] ▪ Un exemple : Modèle + son implémentation
▪AI - Data Science – Machine Learning – Deep Learning ▪ Un exercice avec solution
▪Java – J2EE – Angular - Design
▪Python - C- C++ - Data Structures - Optimization
POO en java
Présentation et Implémentation de
Composit Design Pattern
Le design pattern composit: à quoi peut servir? Composant{abstract}
▪ Le design pattern Composite appartient à la famille des designs pattern structurale #description
Feuille
▪ Le design pattern Composite est un design pattern de partitionnement et décrit un groupe
+Composant(…)
d'objets traités de la même manière comme étant une instance unique ayant le même
+operations() {abstract}
type.
fils*
▪ Le but de ce design pattern est “composer” des objets dans une structure hiérarchique
parent 1
▪ Il permet aux clients (code source) de traiter des objets individuels et des compositions Composite
d’objets d’une manière uniforme
+add(Composant):void
▪ il favorise « open/closed principle » +remove(Composant):void
+getComposants():List<Composant
▪ Il permet donc de créer des objets flexibles et extensibles en minimisant le risque de bugs >
▪ Il peut favoriser « single responsibility principle »
▪Il est composé des éléments suivants:
▪ Composant: Définit l'interface pour tous les objets dans la composition, qu'ils soient
simples ou composites
▪ Composite: Représente les objets composites (ceux qui peuvent avoir des enfants).
▪ Feuille: Représente les objets primitifs de la composition. Une feuille n'a pas d'enfants.
▪ Chaque objet est une hiérarchie
Exemples: ▪ un objet enfant est créé de la même logique qu’un
1. Décrire le contenu d’un livre objet parent
2. Gestion de l’organisation d’une école ▪ Un objet feuil n’as pas d’enfant
Le design pattern composit: composition d’un livre
▪ Sans utilisation de design pattern composit,
▪ la création de tels structure est difficile
Livre
▪ Et peut entrainer à un modèle difficile
▪ Ce qui rend difficile la maintenance du code
Titre
contenu titre titre
contenu contenu
Chapitre 1
section111
titre
section112
Titre contenu
contenu

Section11 titre
contenu titre
Section12 section121
contenu
titre

Chapitre2
Section13
section131
section112

Sans Composite design pattern: Model 1
1..*
Livre Chapitre
titre titre
Contenu contenu
operations()
operations()
▪ Modèle pour représenter le contenu d’un livre 1..*
▪ Le contenu est hiérarchique
Section
▪ Chaque niveau est géré de la même logique que son ascendant Titre
▪ Problèmes: contenu
operations()
▪ Le nombre de niveaux est fixe!!
▪ Tous les livres issus de ce modèle doivent avoir le même *
nombre de niveaux SousSection
▪ Beaucoup d’objets à gérer Titre
contenu
▪ Difficulté de maintenance du code
operations()
▪ Difficulté d’évolution
Avec Composite design pattern: Model 2
Composant{abstract}
#titre Composite
#contenu
+add(Composant):void
#niveau
+remove(Composant):void
* 1 +getComposants():List<Composant
+Composant(String,String,int)
+operation():void{abstract} >
fils parent
+getMarge():String

Feuille

▪ Modèle pour représenter le contenu d’un livre


▪ Le contenu est hiérarchique
▪ Chaque niveau est géré de la même logique que son ascendant
▪ C’est une Solution aux problemes rencontrés en utilisant le modèle 1
Exemple: Description du livre JAVA en action

Livre

Java en action
Ce livre… Classe-objet classe
… …
Chapitre 1
section111
objet
section112
Principaux concepts de POO …
les concepts de la POO...

Section11 Héritage –ca,int


… Héritage
Section12 section121
...
titre

Chapitre2
Section13

section132

Quand utiliser le pattern composite
▪ Si on s'aperçoit qu’on utilise plusieurs objets de la même manière et
qu'ils ont souvent un code presque identique pour les manipuler, le
composite est un bon choix.

▪ Dans ce cas, il est moins complexe de traiter les primitives et les


composites de manière homogène.
Exemple d’utilisation : structure d’un livre
▪ En utilisant le design pattern Compost, écrire le code source pour créer cette structure

Livre

Java en action
Ce livre… Classe-objet classe
… …
Chapitre 1
section111
objet
section112
Principaux concepts de POO …
les concepts de la POO...

Section11 Héritage –ca,int


… Héritage
Section12 section121
...
titre

Chapitre2
Section13

section132

Exemple d’utilisation : structure d’un livre (Code 1/2)

public class Program {


public static void main(String[] args) {
Composite livre=new Composite("Java en action","ce livre permet de ...");

Composite chapitre1=new Composite("Principaux concepts de POO", "les concepts de la


POO...");
Composite section11=new Composite("Classe - objet", "le concept de classe-objet...");
Composite section111=new Composite("Classe", "c'est un élement abstrait...");

Composite section112=new Composite("Objet", "c'est une instance concrète ayant...");


[Link](section111);[Link](section112);
Composite section12=new Composite("Héritage - Classes abstraites - interfaces","factoriser
les traitement et la structure....");
Composite section121=new Composite("Héritage","basé sur le concept classe mère et classe
fille....");
[Link](section121);
[Link](section11); [Link](section12);
[Link](chapitre1);
[Link]();
}
}
Exemple d’utilisation : structure d’un livre (Code 2/2)
public abstract class Composant { Composant{abstract}
protected String titre;
protected String contenu; #titre Compo
public Composant(String titre,String contenu) { #contenu
+add(Composant):v
[Link] = titre; #niveau
+remove(Composan
[Link]=contenu;
* 1 +getComposants():L
+Composant(String,String,int)
} +operation():void{abstract} >
fils parent
public abstract void printContent(); +getMarge():String
}
public class Composite extends Composant{
public Composite(String titre,String contenu) {
super(titre,contenu); Feuille
}
private List<Composant> composants=new ArrayList<>();
@Override
public void printContent() {
public class Element extends Composant {
[Link](titre);
[Link]("- - "+contenu); public Element(String titre, String contenu) {
for(Composant comp:composants){ super(titre, contenu);
[Link](" "); }
[Link]();
}
@Override
}
public void add(Composant comp){
public void printContent() {
[Link](comp); [Link](titre);
} }
}
Composite vs Decorator
IComponent
Component +methodes() Composant{abstract}
#structure #description
Feuille
+methodes () +Composant(…)
ConcretComponent +operations() {abstract}
1
fils*
parent 1
AbstractDecorator Composite
+add(Composant):void
+remove(Composant):void
+getComposants():List<Composant
>
ConcreteDecorator
Composite
Decorator
Composite vs Decorator
Etape 1 Etape 2 Etape 3 Etape 4

▪ Dans décorator, on enveloppe un objet


▪ Dans composite, on développe une hiérarchie
▪ Dans décorator, l’objet résultat est un décorateur
▪ Dans composite, l’objet résultat est un composant
POO- JAVA: Présentation et Implémentation de
Composit Design Pattern
Exercice : Gestion de l'organisation d'une école

Vous êtes chargé de développer un système pour gérer l'organisation d'une école. Cette
organisation comprend des départements, des filières, des niveaux d'étude, des modules, des
professeurs et des étudiants. Vous allez utiliser le design pattern Composite pour traiter ces
entités de manière uniforme.

Objectif
Implémenter les classes nécessaires pour représenter l'organisation de l'école en utilisant le
design pattern Composite.
Permettre de calculer le nombre total de modules, de professeurs et d'étudiants dans une
structure donnée (département, filière, niveau d'étude, etc.).
Permettre d'afficher la structure de l'école de manière hiérarchique.
JAVA – Implémentation des principaux
design patterns
1. À quoi servent les design patterns
2. Types de design patterns

ENSA Oujda
3. Les principaux design patterns
Cycle d’ingénieur - DSCC 1ère Année
▪ Singleton Design Pattern
▪ Dao Design Pattern
POO en java ▪ Abstract Dao Design Pattern
▪ Decorator Design Pattern
Implémentation de ▪ Composit Design Pattern
Strategy ▪ Strategy Design Pattern

Design Pattern Observer Design Pattern

Pour chaque design pattern, une démonstration qui montre:


▪ L’utilité du design pattern
▪ Le modèle: diagramme de classes
@[Link]@[Link] ▪ Un exemple : Modèle + son implémentation
▪AI - Data Science – Machine Learning – Deep Learning ▪ Un exercice avec solution
▪Java – J2EE – Angular - Design
▪Python - C- C++ - Data Structures - Optimization
POO en java
Présentation et Implémentation de
Strategy Design Pattern
Le design pattern strategy: à quoi peut servir?
Program
▪ Il permet de définir une famille d'algorithmes,
d'encapsuler chacun d'eux et de les rendre
interchangeables. LoanContext
LoanContext(strategy: InterestCalculationStrategy)
▪ Les points clés de ce design pattern: +executeStrategy(m: double, rate:double , years: int):void
▪ Séparation des préoccupations: Il permet aux
algorithmes de varier indépendamment des clients
1
qui les utilisent: séparer les algorithmes de leur InterestCalculationStrategy
utilisation, ce qui favorise une meilleure organisation <<interface>>
du code et une réduction des couplages: code
+calculateInterest(double m, double rate, int year):double
modulaire et simple à maintenir
▪ Flexibilité et extensibilité: il permet d'ajouter de
nouveaux algorithmes ou de modifier les existants
sans avoir à modifier le code client, ce qui rend le
système plus flexible et extensible HomeLoanStrategy PersonalLoanStrategy AutoLoanStrategy

▪ Facilitation des tests unitaires : Il simplifie les tests -attributs?

unitaires en permettant de tester chaque algorithme


de manière indépendante.
Sans Strategy design Pattern
Exemple : Système de Calcul de Crédits Bancaires

Vous travaillez dans une banque et vous devez développer un système de calcul de crédits
bancaires. La banque propose différents types de crédits (prêt personnel, prêt immobilier, prêt
auto, etc.) et chacun a sa propre méthode de calcul des intérêts.
Objectif
Proposer un programme Java pour calculer les intérêts pour chaque type de crédit.

Pour résoudre ce problème, une première réflexion peut avoir la forme suivante:
Sans Strategy design Pattern

LoanCalculator
+calculateInterest(loanType: String, principal: double, rate: double, years : int): double
public class LoanCalculator { Class Program{
public double calculateInterest(String loanType, double public static void main(String[] args) {
principal, double rate, int years) { LoanCalculator calculator = new LoanCalculator();

if ([Link]("personal")) { double personalLoanInterest = [Link]("personal",


return principal * rate * years / 100; 10000, 5, 2);
} else if ([Link]("home")) { [Link]("Personal Loan Interest: " + personalLoanInterest);
return principal * [Link](1 + rate / 100, years) - principal;
} else if ([Link]("auto")) { double homeLoanInterest =[Link]("home",
return (principal * rate * years / 100) * 0.9; 200000, 3.5, 20);
} else {
[Link]("Error Type"); [Link]("Home Loan Interest: " + homeLoanInterest);
}
} double autoLoanInterest = [Link]("auto", 15000, 4, 5);

[Link]("Auto Loan Interest: " + autoLoanInterest);


}
}
Avec Strategy design Pattern – Code 1/2
public interface InterestCalculationStrategy {
double calculateInterest(double principal, double rate, int years);
Program
}

//Stratégie de calcul des intérêts pour prêt immobilier


LoanContext
public class HomeLoanStrategy implements
InterestCalculationStrategy { LoanContext(strategy: InterestCalculationStrategy)
@Override +executeStrategy(m: double, rate:double , years: int):void
public double calculateInterest(double principal, double
rate, int years) { 1
return principal * [Link](1 + rate / 100, years) -
principal; InterestCalculationStrategy
} <<interface>>
}
+calculateInterest(double m, double rate, int year):double
package part2.chap9.design_patterns.[Link];

//Stratégie de calcul des intérêts pour prêt personnel


public class PersonalLoanStrategy implements
InterestCalculationStrategy { HomeLoanStrategy PersonalLoanStrategy AutoLoanStrategy
@Override
public double calculateInterest(double principal, double //Stratégie de calcul des intérêts pour prêt auto
public class AutoLoanStrategy implements InterestCalculationStrategy {
rate, int years) { @Override
return principal * rate * years / 100; public double calculateInterest(double principal, double rate, int years)
} {
} return (principal * rate * years / 100) * 0.9;
}
}
public class Program {
Avec Strategy design Pattern – Code 2/2 public static void main(String[] args) {
// Stratégie pour prêt personnel
//Contexte qui utilise une stratégie de calcul des intérêts InterestCalculationStrategy personalLoanStrategy = new
public class LoanContext { PersonalLoanStrategy();
private InterestCalculationStrategy strategy; // Stratégie pour prêt immobilier
InterestCalculationStrategy homeLoanStrategy = new
public LoanContext(InterestCalculationStrategy strategy) { HomeLoanStrategy();
[Link] = strategy; // Stratégie pour prêt auto
} InterestCalculationStrategy autoLoanStrategy = new
AutoLoanStrategy();
public void setStrategy(InterestCalculationStrategy // Contexte pour prêt personnel
strategy) { LoanContext loanContext = new
[Link] = strategy; LoanContext(personalLoanStrategy);
} double personalLoanInterest =
[Link](10000, 5, 2);
public double executeStrategy(double principal, double rate, [Link]("Personal Loan Interest: " +
int years) { personalLoanInterest);
return [Link](principal, rate, // Changer de stratégie pour prêt immobilier
years); [Link](homeLoanStrategy);
} double homeLoanInterest =
} [Link](200000, 3.5, 20);
[Link]("Home Loan Interest: " +
homeLoanInterest);
// Changer de stratégie pour prêt auto
[Link](autoLoanStrategy);
double autoLoanInterest =
[Link](15000, 4, 5);
[Link]("Auto Loan Interest: " +
autoLoanInterest);
}
}
POO- JAVA: Présentation et Implémentation de
Strategy Design Pattern
Exercice : Système de vente en ligne

Vous travaillez sur une plateforme de commerce électronique qui doit permettre aux utilisateurs de payer leurs
achats en ligne en utilisant différentes méthodes de paiement telles que les cartes de crédit, PayPal, et les
virements bancaires. Vous devez implémenter le design pattern Strategy pour gérer ces différentes méthodes de
paiement de manière flexible et évolutive.

Pour résoudre ce problème, vous allez utiliser le design pattern Strategy afin de pouvoir choisir dynamiquement la
stratégie de paiement.
Objectif
1. Implémenter les classes nécessaires pour représenter les différents types de paiement en utilisant le design
pattern Strategy.
2. Permettre de réaliser le paiement en se basant sur le détail de chaque paiement. (voir les classes ci-dessous)
3. S’assurer que le système soit facilement extensible pour ajouter de nouvelles méthodes de paiement à l'avenir.
Virement CreditCardPayment PaypalPayment
-rib: String -cardNumber: String -emal: String
-expiryDate: String -passWord: String
-cvv: String
Strategy design Pattern – java code
// Implementation 1 // Interface Strategy
class CreditCardPayment implements PaymentStrategy { interface PaymentStrategy { ShoppingCart {context}
private String cardNumber; void pay(int amount);
private String expiryDate; private String cvv; }
+checkout(double amount):void
public CreditCardPayment(String cardNumber, String
expiryDate, String cvv) {
[Link] = cardNumber;
[Link] = expiryDate; [Link] = cvv; Program
}
1
@Override
public void pay(int amount) { PaymentStrategy
[Link](amount + " paid with credit <<interface>>
card");
} +pay(double amount): void
}
// Implementation 2
class PaypalPayment implements PaymentStrategy {
private String email; private String password;
public PaypalPayment(String email, String password) {
[Link] = email; [Link] = password;
} CreditCardPayment PaypalPayment
-cardNumber: String -emal: String
@Override
-expiryDate: String -passWord: String
public void pay(int amount) {
[Link](amount + " paid using Paypal"); -cvv: String
}
}
Strategy design Pattern – java code
// Context
class ShoppingCart { ShoppingCart {context}
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
+checkout(double amount):void
[Link] = paymentStrategy;
}
public void checkout(int amount) { Program
[Link](amount);
} 1
} PaymentStrategy
// Example usage <<interface>>
public class Main { +pay(double amount): void
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();

// Client selects payment method 1 (Credit Card)


[Link](new CreditCardPayment("1234567890", "12/24", "456"));
[Link](100);
// Client selects payment method 2 (Paypal)
CreditCardPayment PaypalPayment
[Link](new PaypalPayment("example@[Link]", -cardNumber: String -emal: String
"password")); -expiryDate: String -passWord: String
[Link](200); -cvv: String
}
}
JAVA – Implémentation des principaux
design patterns
1. À quoi servent les design patterns
2. Types de design patterns

ENSA Oujda
3. Les principaux design patterns
Cycle d’ingénieur - DSCC 1ère Année
▪ Singleton Design Pattern
▪ Dao Design Pattern
POO en java ▪ Abstract Dao Design Pattern
▪ Decorator Design Pattern
Implémentation de ▪ Composit Design Pattern
Observer ▪ Strategy Design Pattern

Design Pattern Observer Design Pattern

Pour chaque design pattern, une démonstration qui montre:


▪ L’utilité du design pattern
▪ Le modèle: diagramme de classes
@[Link]@[Link] ▪ Un exemple : Modèle + son implémentation
▪AI - Data Science – Machine Learning – Deep Learning ▪ Un exercice avec solution
▪Java – J2EE – Angular - Design
▪Python - C- C++ - Data Structures - Optimization
Observer
Design Pattern
Observer design Pattern
▪ Il est utilisé lorsque vous avez un objet (appelé le sujet - observable) qui maintient une liste de ses dépendants, appelés
observateurs (observer)
▪ Observable informe ses observers automatiquement de tout changement d'état
▪ Il les informe généralement en appelant l'une de leurs méthodes
▪ Ce pattern est utile dans de nombreuses situations, notamment pour implémenter des interfaces utilisateur réactives
▪ En termes de structure, l’observable fournit des méthodes pour ajouter, supprimer et notifier des observateurs.
▪ Les observateurs, à leur tour, doivent implémenter une interface commune qui définit la méthode appelée par le
sujet lorsqu'un changement d'état se produit.
Observer design Pattern
*
Subject Observer
+Observer(Subject)
-state
+update():void {abstract}
+attach(Observer):void
+detach(Observer):void
-notifyObservers():void
ConcreteObserver
+ConcerteObserver(Subject)
Observer Pattern – java code
import [Link];
import [Link];
// Subject/Observable
class Subject {
private List<Observer> observers = new ArrayList<>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
[Link] = state;
notifyObservers();
}
public void attach(Observer observer) {
[Link](observer);
}
public void detach(Observer observer) {
[Link](observer);
}
private void notifyObservers() {
for (Observer observer : observers) {
[Link]();
}
}
}
Observer Pattern – java code
// Observateur/Observer // Observateur concret/ConcreteObserver
abstract class Observer { class ConcreteObserver extends Observer {
protected Subject subject; public ConcreteObserver(Subject subject) {
super(subject);
public Observer(Subject subject) { }
[Link] = subject; @Override
[Link](this); public void update() {
} [Link]("State changed: " +
public abstract void update(); [Link]());
} }
}
Observer Pattern – java code

// Exemple d'utilisation
public class Main {
public static void main(String[] args) {
Subject subject = new Subject();

// Création des observateurs


ConcreteObserver observer1 = new ConcreteObserver(subject);
ConcreteObserver observer2 = new ConcreteObserver(subject);

// Changement d'état du sujet


[Link](5);
[Link](10);
}
}
Exercice
Supposez que vous développiez un système de gestion de stocks pour un magasin en ligne.
Vous avez besoin d'implémenter un mécanisme de notification pour informer les gestionnaires de stocks lorsqu'un produit est en
rupture de stock.
Utilisez le design pattern Observer pour réaliser cette fonctionnalité.
1. Définir le modèle
2. Implémenter le modèle
3. Tester le modèle
Source..
▪ Design Patterns : Elements of Reusable Object-Oriented Software,
▪ traduit en français sous le titre « Design patterns. Catalogue des
modèles de conception réutilisables »
▪ est un livre de méthodologie appliquée à la conception logicielle
▪ écrit par Erich Gamma, Richard Helm, Ralph Johnson et John Vlissides
▪ qui forment le surnommé « Gang of Four », abrégé GoF — « Bande
des quatre » en français
▪ et publié en 1994 chez Addison-Wesley.
▪ Cet ouvrage aborde le sujet de la programmation orientée objet et
introduit le concept des patrons de conception.
[Link]

Vous aimerez peut-être aussi