Design poo togo_jug_final
-
Upload
duchess-france -
Category
Documents
-
view
333 -
download
2
description
Transcript of Design poo togo_jug_final
Agnès CREPET @agnes_crepetCyril LACÔTE @clacote13 aout 2011 TogoJUG - Lomé
Principes de la conception objetL'enjeu du design
Les Design Patterns
Programme de la session
Un peu d'histoire
Qu'est-ce qu'une bonne conception objet?
Les grands principes de la conception objet
Pas de catalogue des Design Patterns!
La gestion des dépendances
L'inversion de contrôle
Les patterns d'architecture
Un peu d'histoire
Open (« interface-File)
Read:
read (enreg)
if (eof)
go to Fin-Fichier
if (cd-Enreg == « FACTURE »)
go to Facture
if (cd-Enreg == « AVOIR »)
go to Avoir
if (cd-Enreg == « PROFORMAT»)
go to Read
Au début était le Go To
Facture: Traitement facture go to Calcul Avoir: Traitement avoir go to CalculCalcul: Lecture du compte Calcul du solde Mise à jour compte go to Read:Fin-Fichier: close (« interface-File »)
Au delà du GOTO
« Go To Statement Considered Harmful »
Edsger W. Dijkstra, 1968
Tout programme ayant une seule entrée peut être construit uniquement par les structures suivantes :
séquence
boucle
if – else
Le programmation structurée
Open (« interface-File)
read (enreg)
while (eof == false)
if (cd-Enreg == « FACTURE »)
Traitement facture
else if (cd-Enreg == « AVOIR »)
Traitement avoir
else
continue
end-if
ReadCompte()
Calcul du solde
UpdateCompte()
read (enreg)
end-while
close (« interface-File »)
ex : langage C
Fonctions réutilisables
Structures de contrôle
Méthodologie ?
Approche top-down
Approche par décomposition
Problème découpé en sous problèmes
À chaque tâche est appliqué le même principe
→ décomposition en arbre
Diviser pour régner !
Approche top-down
Ouverture fichier
Traitement fichier
Fermeture fichierTant qu ’il y a des enregistrements
Traitement Facture Traitement Avoir
Traitement du solde
ReadCompte Calcul Solde UpdateCompte
Traitement du solde ...
Approche top-down
Méthode Warnier (1974)
De (très) gros programmes COBOL
Bonne fiabilité dans la construction
Mais très faible évolutivité :
Ne met pas en relief le code à factoriser
Tout changement demande une modification de tous les programmes
Modularité
Factorisation de code, réutilisation
Fonction
Module
Sous-programme
Oblige à l'isolation
Traitements / données
FORTRAN 58, ALGOL 60, PASCAL 70, C 73
Vers l'encapsulation
Faible couplage entre les données et la structure des traitements
La programmation n'est plus guidée par les traitements
Contrairement à MERISE ou au COBOL
Consécration : l'objet !
Démarche objet : pas si récente !
Années 60 : recherches au MIT
Modula : 1967
SmallTalk : 1972
C++ : 1981
Java : 1995
Objet : motivations
Une idée fondatrice :
Proche du monde réel
demarrer( )freiner( )
vitessemodèle
Voiture
Abstraction
Pourquoi l'objet ?
Doc
Conception
Test
Code
Autre
Révision & Maintenance
Source: DP Budget, Vol. 7, Dec 1998.
Maintenable
Flexible
Extensible
Coût d'un projet :
15% développment
70% maintenance !
Conception objet
Enjeu du design :
Construire un système capable d'évoluer
En maximisant la réutilisation
Pour des gains de qualité et de productivité
Faciliter la maintenance !
Une bonne conception objet
Pas de solution absolue :
Des principes plus que des règles
Des pratiques méthodologiques
Des architectures reconnues
Des « recettes éprouvées » : les Design Patterns
Les Design Patterns
Paire nommée « problème / solution »
Figures types de relation entre des classes
Au design ce que l'algorithme est à la programmation
23 patterns historiques
Gang Of Four (GoF) : Erich Gamma, Richard Helm, Ralph Johson, John Wlissides, "Design Pattern. Elements of Reusable Object-oriented sofware", 1995
L'intérêt des Design Patterns
Des catalogues entiers
Les énumérer :
fastidieux, ennuyeux, donc inutile ici !
Essayons plutôt d'en comprendre les enjeux
L'enjeu des Design Patterns
Syndrôme du « not invented here »
Formalise une expertise
Accessible à un non-expert
Facilite la communication : langage commun
Pensé pour la réutilisation et la maintenance
Indépendant des langages
Mettent en œuvre des principes généraux
Un principe fondateur : l'OCP (1/2)
Open - Close Principle (OCP)
Tout module (package,classe,méthode) doit :
Être ouvert aux extensionsPouvoir ajouter de nouveaux comportements
→ S'adapter aux changements !
Être fermé aux modificationsLe code existant ne peut être modifié, seul
l’ajout est permis.
→ Ne pas casser ce qui fonctionne !
Un principe fondateur : l'OCP (2/2)
Pas de recette de construction
Mais une philosophie à respecter pour construire un logiciel maintenable.
Tous les autres principes sont des applications de ce principe fondateur.
KISS : Keep It Simple, Stupid !
La simplicité est un objectif clé
Un code simple est :• Moins long à écrire
• Moins sujet au bug
• Plus facile à comprendre et faire évoluer
Principes d'une bonne conception
DRY : Don't Repeat Yourself
Proscrire les répétitions de code
Privilégier les abstractions
YAGNI : You Aren't Gonna Need It !
Ne pas présupposer un besoin futur
Privilégier un design pragmatique
Principes d'une bonne conception
Moyens fondamentaux :
Encapsulation
Héritage
Polymorphisme
Prémisses de solution à la mise en œuvre des principes de bonne conception
Les fondements de l'objet
L'encapsulation
Objet « Boîte noire »
Interface :
Ce que je sais faire
Ce qu'on peut me demander de faire
Implémentation :
Ca ne te regarde pas !
Fonce !
Freine ! Tourne !
L'encapsulation
Masquage des détails d'implémentation
Données encapsulées :
Attributs privés
Le monde extérieur ne peut pas y toucher
Méthodes publiques :
Service offert à l'extérieur
Seuls points d'accès
L'encapsulation
Avantages :
Garantir l'intégrité des données
Changer d'implémentation
Limiter les effets de bord
SANSAVEC
class Adresse {
public String nom;
….
}
class Adresse {
private String nom
public setNom (String aNom) {
nom = aNom;
}
// Saisie des livraisonsAdresse adrLiv = new Adresse();...adrLiv.nom = « Dupond »;
// Saisie des livraisonsAdresse adrLiv = new Adresse();...adrLiv.setNom (« Dupond »);
// Saisie de facturationAdresse adrFac = new Adresse();...adrFac.nom = « Dupond »;
// Saisie de facturationAdresse adrFac = new Adresse();...adrFac.setNom (« Dupond »);
Encapsulation : exemple
SANS AVEC
class Adresse {
public String nom;
….
}
class Adresse {
private String nom
public setNom (String aNom) {
nom = aNom.toUpperCase();
}
// Saisie des livraisonsAdresse adrLiv = new Adresse();...adrLiv.nom = « Dupond ».toUpperCase();
// Saisie des livraisonsAdresse adrLiv = new Adresse();...adrLiv.setNom (« Dupond »);
// Saisie de facturationAdresse adrFac = new Adresse();...adrFac.nom = « Dupond ».toUpperCase();
// Saisie de facturationAdresse adrFac = new Adresse();...adrFac.setNom (« Dupond »);
Encapsulation : exemple
L'héritage
Partage de caractéristiques communes
Attributs & Comportements
Personne nom : chaîne age : entier seMarie()
Personne nom : chaîne age : entier seMarie()
Employé nom : chaîne age : entier société : chaîne seMarie() estPromu()
Employé nom : chaîne age : entier société : chaîne seMarie() estPromu()
Personne nom : chaîne age : entier seMarie()
Personne nom : chaîne age : entier seMarie()
Employé société : chaîne estPromu()
Employé société : chaîne estPromu()
Véhicule moteur
VéhiculeTerrestre nombreRoues
VéhiculeMaritime VéhiculeAérien altitudeMax
Voiture Camion Paquebot cabines
Péniche Avion ailes
Hélicoptère rotors
Généralisation
Spécialisation
L'héritage
Liskow Substitution Principle : LSP
Il doit être possible de substituer à n’importe quel objet instance d’une super-classe, n’importe quel objet instance d’une sous classe sans que la sémantique du programme écrit dans les termes de la super-classe ne soit affectée
[Barbara Liskow, « Proceedings of OOPSLA’87 »]
Ce principe permet de déterminer si une relation d’héritage est bien employée pour la classification
Liskow Substitution Principle : LSP
Un module utilisant une classe doit pouvoir utiliser les sous-classes sans le savoir
C’est-à-dire :
Toute classe de la hiérarchie doit honorer tous les rôles de sa classe parente
Une classe fille ne doit pas être une restriction de la classe parente
→ Une sous-classe peut substituer une super-classe
Le polymorphisme
Une invocation de méthode :
Déclenchera un traitement différent selon le type
L'implémentation est choisie par l'objet invoqué
Les objets doivent collaborer :
sans connaitre leur type réel
traitant ceux du même genre de la même manière.
Une Interface :
ensemble de méthodes abstraites publiques
pouvant être implémentées par différentes classes
Notion de « contrat de service »
Polymorphisme sans héritage
public interface Dessinable {
void draw (); // public abstract implicite
}
La voie du polymorphisme
Article
PrixRevient
+PrixRevient():Article
+calculPrixRevient():real
+PrixRevient():Article
+calculPrixRevient():real
1
PrixAchat
+PrixAchat(In article:Article)
+calculPrixAchat():real
PrixFabrication
+PrixFabrication(In article:Article)
+calculPrixFabrication():real
Comment réaliser des extensions sans modifier l'existant ?
L'enjeu d'un bon Design
Rappel : le challenge de l'OCP
PrixAchat prixAchat = new PrixAchat(article);
PrixFabrication prixFabrication = new PrixFabrication(article);
...
double calculPrixRevient()
{
if ("Article.ACHAT".equals(getArticle().getType()))
return prixAchat.calculPrixAchat() * coef;
else
return prixFabrication.calculPrixFabrication() * coef;
}
calculPrixRevient() n'est pas fermée aux modifications
Article
PrixRevient
+PrixRevient():Article
+calculPrixRevient():real
+PrixRevient():Article
+calculPrixRevient():real
1
PrixAchat
+PrixAchat(In article:Article)
+calculPrixAchat():real
PrixFabrication
+PrixFabrication(In article:Article)
+calculPrixFabrication():real
<<interface>>
PrixRevientBrut
+calculPrixBrut() PrixFabrication
+PrixFabrication(In article:Article)
+calculPrixFabrication():real
+calculPrixBrut()
PrixAchat
+PrixAchat(In article:Article)
+calculPrixAchat():real
+calculPrixBrut()
Comment réaliser des extensions sans modifier l'existant ?
L'enjeu d'un bon Design
Rappel : le challenge de l'OCP
double calculPrixRevient () {
return prixRevientBrut.calculPrixBrut() * coef;
}
calculPrixRevient() est ouvert aux extensions
Le polymorphisme via l'introduction d'une interface a été la solution
Rappel : le challenge de l'OCP
if ("Article.ACHAT".equals(getArticle().getType()))
PrixRevientBrut prixRevientBrut
= new PrixAchat(article);
else
PrixRevientBrut prixRevientBrut
= new PrixFabrication(article);
Mais il faut bien a un moment donné choisir l'implémentation réelle...
L'application des grands principes
Un vœux pieux !
Le code ne peut pas être complètement fermé
Le choix de la violation est stratégique
Évaluer les probabilités de changement
L'O.C.P. est un but à atteindre
la condition de la réutilisation dans un cadre évolutif
Affectation des responsabilités
Comment assigner les rôles aux classes?
Qui fait quoi?
→ General Responsibility Assignment Software Patterns
[Graig Larman, "Applying UML and Patterns", 1998]
Affectation des responsabilités
"Savoir" (Knowing)
Connaissance des objets privés
Connaissance des objets liés
Connaissance de résultats de calculs ou dérivés
"Savoir Faire" (Doing)
Faire quelque chose soit même
Initialiser les actions d'autres objets
Coordonner les activités d'autres objets
Eventuellement répartie sur plusieurs classes
Classement des responsabilités
G.R.A.S.P : Expert
Quel est le principe pour donner une responsabilité ?
→ Donner la responsabilité à la classe qui connaît l’information permettant de la réaliser.
"Celui qui sait, fait" (Knowing is doing)
C’est le principe élémentaire
G.R.A.S.P : Creator
Qui doit créer une instance de classe ?
→ Donner à B la responsabilité de la création de A si
• A est un attribut de B
• B a les données d'initialisation de A
• B utilise toujours (souvent) A
Si besoin, les données (Objets) nécessaires à la création de A doivent être fournies à B pour qu'il puisse réaliser la création de A.
Mesure l'interdépendance entre composants
G.R.A.S.P. : Faible couplage ( 1/2)
Un fort couplage est pénalisant :
Compréhension, maintenance, réutilisation
Important lorsqu'on dépend d'un composant instable
Être fortement couplé à un composant stable n'est pas critique.
G.R.A.S.P. : Faible couplage (2/2)
G.R.A.S.P. : Forte cohésion
Mesurer la cohésion des responsabilités d'une classe
La cohésion diminue quand :
les responsabilités d'une classe sont disparates
une responsabilité est diluée dans plusieurs classes
But à atteindre : forte cohésion
Chacun son métier !
Attention à l'obésité !
Obésité :
Si les responsabilités sont disparates
Le couplage augmente pour les assumer
Une évolution impactera d'autres fonctionnalités
Faible couplage / fort cohésion sont liés
Plus de cohésion → moins de couplage
Quelles solutions pour garantirun faible couplage
et une forte cohésion ?
Interface Segregation Principle : ISP
Les clients ne doivent pas être impactés par des interfaces qu’ils n’utilisent pas
[Bertrand Meyer, 1988]
Séparation des services de l'interface :
Chaque client ne doit "voir" que les services qu'il utilise réellement
ISP : exemple gestion de commandes
La responsabilité de Commande est mal définie
Perte de cohésion et obésité
Si modification de affectationTransporteur()
Impact sur IHMCommande qui n'est pas concernée
→ Je ne peux livrer la saisie des commandes sans livrer la logistique
Commande
calculMtHT()
affectationTransporteur()
IHMLogistique
IHMCommande
TarifArticle
RechercheTransporteur
calculMtHT()
affectationTransporteur()Service Logistique
Saisie des commandes
ISP : Techniques de séparation
Deux techniques principales :
Héritage multiple : impossible en Java !
Délégation : Design Pattern « Adapter »
Séparation par Délégation / Adapter :
Les services peuvent être représentés par des classes de délégation.
ISP : exemple gestion de commandes
Respect de l'ISP :
Séparation des interfaces
Service Logistique
Saisie des commandes
HIMCommande Commande.
+calculMtHT()
IHMLogistique.CommandeLogistique
+affectationTransporteur()
RechercheTransporteur
TarifArticle
Permet la saisie de
+calculMtHT()
necessite
Obtient des informations de
+affectationTransporteur()
Est aidé par
Gestion des dépendancesInversion de contrôle
Dépendances : conséquences
Dépendance A → B
Impossible
d'installer A sans B
de réutiliser A sans B
Une modification de B
Effet de bord sur A
Recompilation de A
A
A
A
utilise
lié à
hérite de
B
B
B
Dépendances : un choix stratégique !
A B
A B
?
Nécessité de mettre de l'ordre
Surtout quand elles se multiplient
Plus de classes → plus de dépendances !
Tendre vers le faible couplage (toujours!)
ou?
Dependency Inversion Principle
Les modules de hauts niveaux ne doivent pas dépendre de modules de bas niveaux
Les abstractions ne doivent pas dépendre de détails. Les détails doivent dépendre d’abstractions
[Robert C. Martin,"Object Oriented Design Quality Metrics", 1995]
DIP : haut / bas niveau
Plus un composant est proche du fonctionnel, plus il est de haut niveau
Un module fonctionnel ne doit pas dépendre des niveaux présentation ou physique
La richesse de l'application vient du métier !
Il est plus risqué d'impacter le métier si les couches basses évoluent
DIP : abstraction/détail
Les abstractions ne doivent pas dépendre de détails.
Les détails doivent dépendre d’abstractions
Une abstraction est une interface
Un détail est un objet concret
Un objet abstrait est de niveau intermédiaire
DIP : mise en oeuvre
Composants « métier » et interfaces sont des objets de haut niveau.
Démarche de construction :
Définir les besoins des composants de hauts niveauxexemple : sauvegarder en BDD
Concrétiser ces besoins par des interfacesexemple : interface Persistence
Implémenter cette interface dans les modules de bas niveaux
dépendant des drivers de BDD
Inversion de contrôle : principe
Principe de Hollywood :
« Do not call us, we'll call you »
L'inversion de contrôle est un terme générique
Plusieurs représentations
La plus connue : injection de dépendances
Les objets ne vont pas « chercher » leurs dépendances
Elles leurs sont fournies par un tiers
Inversion de contrôle : mise en oeuvre
Un conteneur de Bean peut injecter ces dépendances
Ces dépendances seront satisfaites après la création d'un Bean
par les paramètres des constructeurs
ou par appel des setters après instanciation
C'est le rôle des conteneurs dits « légers »
Spring, Guice, Weld
Injection de dépendance : exemple
Exemple :
Un chat veut jouer...
Trois approches :
De base, sans injection
Avec injection manuelle
Avec injection par un conteneur
Injection de dépendances : sans
package com.injection.none;
import com.injection.none.jeu.Souris;
public class Chat {
private Souris souris = new Souris();
public void jouer() {
souris.jouer();
}
}
Utilisation : Chat monChat = new Chat();
monChat.jouer();
Injection de dépendance : bilan
Sans injection de dépendances :
Modélisation fermée
Le chat ne peut jouer qu’avec une souris
Fort couplage (relation, création, utilisation)
Dépendance vis-à-vis de la souris
Impossibilité de changer de jouet sans recompiler le chat
Injection de dépendance : manuelle
package com.injection.with;
import com.injection.with.jeu.IJouet;
public class Chat {
private IJouet jouet;
public void jouer() {
jouet.jouer();
}
public void setJouet(IJouet jouet) {
this.jouet = jouet;
}
}
Utilisation :
Chat monChat = new Chat();
IJouet jouet = new Souris(); // Souris implémente IJouet
monChat.setJouet(jouet);
monChat.jouer();
Injection manuelle : bilan
Avantages de l'injection manuelle :
Le chat expose sa dépendance avec setJouet()
Aucune dépendance vers des implémentations
Il peut donc jouer avec n’importe quel jouet
Inconvénients
L’utilisation est figée (recompilation nécessaire pour changer de jeu)
Injection de dépendance : conteneur
La modélisation est la même
Seule l’utilisation change :
Configuration en XML ou par annotations
Chargement du contexte
Récupération du chat
Injection de dépendance : conteneur
Configuration XML (exemple : Spring) : <beans>
<bean id="leJouet" class="com.injection.with.jeu.Souris" />
<bean id="chat" class="com.injection.with.Chat">
<property name="jouet" ref="leJouet" />
</bean>
</beans>
Configuration par annotations (normalisées JEE6): public class Chat {
@Inject
private IJouet jouet;
}
Injection de dépendance : bilan
Mêmes avantages que l’injection manuelle
Tout est paramétré
Il faut tout de même configurer l’injection!
Elle est centralisée en XML
Elle est type-safe en annotations
Il n’est pas même pas nécessaire de recompiler en configuration XML
Inversion de contrôle : avantages
Couplage faible
Facile de remplacer des composants
Maintenance simplifiée
Implémentations indépendantes des contextes d’utilisation
Composants réutilisables
Développement incrémental et modulaire
Tests simplifiés :
Dépendances déjà isolées
Mock-objects (bouchons)
Design Pattern en vogueConvention over Configuration
Convention over configuration
Par convention, les frameworks fonctionnent avec une configuration par défaut.
Moins de fichiers de configuration
Simplification
Utilisation des annotations
Tendance Java EE 6
EJB 3.1 le plus simple possible : @Stateless
public class SimpleSample {
public void doSomething() { /*business logic*/ }
}
Patterns d'architecture2 grandes familles(selon Adam Bien)
Exemples d'architecture applicative
Application Java web
Couches Applicatives (présentation,
service, métier…
HTML/ JavaScript
HTTP
… et persistance)
SGBDR
JDBC
Navigateur web
Serveur d’application (ex : JBoss)
Serveur de base de données (Ex: Oracle)
Exterieur de l'application(Système
d'informationde l'entreprise)
?
Des couches logicielles
Présentation
Façade
Service
Persistance
Page JSP
ContrôleurLogique applicative
Façades
Servicesmétier
Ob
jets
du
do
ma
ine
Repositoryaccès aux données
Ob
jets
du
do
ma
ine
Http
SGBDR
Des Patterns d'architecture
L’architecture des applications JEE6 est LIGHTWEIGHT
Architecture rapide, simple, légère, “facile”, lean (maigre)
Idéal pour le développement itératif et incrémental
Grâce :
Aux design patterns comme “Convention over Configuration”
À l’injection de dépendances
Aux annotations
Des Patterns d'architecture
Pilotée par le Service (SOA)
Service Oriented Architecture
le système d’information est un groupe de services
Pilotée par le Domaine (DDD)
Domain Driven Design
Les deux s’appuient sur le pattern ECB
Entity Control Boundary
Similaire au pattern MCV (Model View Contrôler)il n’est pas consacré qu’à la couche présentation
Des Patterns d'architecture
Entity :
Appelé également «objet du domaine »
Élément persistant
Eventuellement logique métier
Control :
Élément orchestrateur qui implémente un scénario (fonctionnel) donné
Correspond notamment aux services métier
Boundary :
Élément en périphérie du système
S’occupe de la communication avec l'extérieur
Lean Service Oriented Architecture (SOA)
Le Control (Services Métiers / Repository) est le composant le plus important
Les objets du domaine sont anémiques (Anemic Object Model)
Aucune logique métier
Le reflet de la base de données (POJO)
Programmation assez procédurale
JEE nous a jusque-la poussé « à oublier l'objet !
Façades
Servicesmétier
Repository
SGBDR
Ob
jets
du
do
ma
ine
Domain Driven Architecture
Les entités du domaine sont le socle de l’application
Gèrent leur état
Et la persistance de leur état
Et implémentent la logique métier
→ PDO (Persistent Domain Objet)
Les services (Control) perdent la logique de l’application
Possible que l’on n’ait plus besoin d’utiliser de service !
Repository
SGBDR
Objets du domaine
Conclusion
Les solutions?
Pas de recette miracle
Appréhender ces principes pour se poser les bonnes questions
On n’applique pas les designs patterns pour le plaisir
Répondre au besoin d'abord
avec une valeur ajoutée ensuite (maintenabilité toujours !)
Adopter une démarche par le Design
liée à de nouveaux cycles de développements
Méthodologies agiles
Rester petitmais penser grand !
Bibliographie
Bibliographie
Design Patterns - Catalogue des modèles de conceptions réutilisables [GOF], Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides ; Vuibert; Juillet 1997 ; ISBN: 2-7117-8644-7
Design Patterns CD - Elements of Reusable Object-Oriented Software De Erich Gamma, Richard Helm, Ralph Johnson et John Vlissides - Addison Wesley Mai 1998 -
Refactoring to patterns, J. Kerievsky ; Addison Wesley; Septembre 2004 ; ISBN: 2-7117-8644-7
Bibliographie
Patterns of Enterprise Application Architecture [PEAA] de Martin Fowler – 2002 – Hardcover
Refactoring : Improving the Design of Existing Code de Martin. Fowler - 1999 [PEAA] - Addison-Wesley
Bibliographie
"Real World Java EE Night Hacks - Dissecting the Business Tier"Adam Bien – 2009 - Press Adam Biem
"Real World Java EE Patterns - Rethinking Best Practices "Adam Bien – 2011- Press Adam Bien
Bibliographie : sites internet
Section sur les patterns du site de Jon Pearce : http://www.cs.sjsu.edu/~pearce/modules/patterns/
index.htm
Site de Martin Fowler :
http://martinfowler.com
Site d'Adam Bien :
http://www.adam-bien.com
Sur l'approche "Domain-Driven Design" :
http://domaindrivendesign.org
Best-Of Design Patterns
Design Pattern : « GoF » (1/2)
Les design patterns ont été présentés et formalisés pour la première fois en 1994 dans un livre : Design Patterns: Elements of Reusable Object-Oriented Software d’Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides surnommé le Gang of Four ou GoF.
Le livre présente les possibilités, limites et pièges des langages orientés objets et il présente 23 design patterns qui sont aujourd’hui connus et utilisés par tous les concepteurs et développeurs.
http://en.wikipedia.org/wiki/Design_Patterns_(book)
Design Pattern : « Gof » (2/2)
Les design patterns du GoF sont classés en 3 thèmes :
Creational patterns : instanciation des classes.
Abstract Factory, Builder, Factory Method, Prototype, Singleton.
Structural patterns : classes et composition des objets.
Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.
Behavioral patterns : gestion de la communication / interaction entre objets.
Chain of responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor.
Exemples Gof : Gestion des objetsFactory :
Problème : l’instanciation des objets peut devenir complexe et être répétée à plusieurs endroits dans le code pour une même classe.
Solution : centraliser l’instanciation des classes.
Singleton
Problème : il est parfois suffisant de n’instancier qu’une seule fois la classe.
Solution : contrôler via la factory une instanciation précédente d’un objet. Renvoyer l’objet précédemment instancier ou créer cette instance.
« L’inverse » du singleton est le prototype.
Design Pattern : PEAA (Martin Fowler, 2002)
Le livre Patterns of Enterprise Application Architecture (2002) de Martin Fowler est une présentation du développement d’application d’entreprise suivi d’un catalogue d’une quarantaine de patterns, classés par thème :
Domain Logic Patterns: Transaction Script, Domain Model, Table Module, Service Layer
Data Source Architectural Patterns: Table Data Gateway, Row, Data Mapper, etc.
Object-Relational Metadata Mapping Patterns: Metadata Mapping, Query Object, Repository.
Distribution Patterns: Remote Facade, Data Transfer Object
Base Patterns: Gateway, Mapper, Layer Supertype, Separated Interface, Registry, Value Object, Money, etc.
Etc.
http://www.martinfowler.com/books.html#eaa
Exemples PEAA : Accès aux données
Repository :
Problème : plus le modèle de domaine est complexe, plus la couche d’accès aux données est complexe même avec l’utilisation d’un Data Mapper
Solution : Créer une classe d’abstraction qui sépare la couche d’accès au données du modèle de domaine.
Exemples Gof/PEAA : Accès aux servicesFacade (Gof)
Problème : comment accéder de manière simple à une fonctionnalité qui peut être réalisée par n classes.
Solution : fournir via une classe un ensemble de services simplifiés d’accès.
Remote Facade (PEAA)
Problème : comment accéder de manière distante avec simplicité et performance à une fonctionnalité qui peut être réalisée par n classes.
Solution : fournir via une classe un ensemble de services d’accès distant.
Design Pattern : EIP (Gregor Hohpe et Bobby Woolf, 2003)
Le livre Enterprise Integration Patterns (2003) de Gregor Hohpe et Bobby Woolf est un catalogue de 65 design patterns destinés à la communication entre applications. Utilisés en particulier dans le cadre du développement autour de l’ESB et des briques de communication dans les applications. Ils sont classés dans les catégories suivantes :
Integration Styles.
Channel Patterns.
Message Construction Patterns.
Routing Patterns.
Transformation Patterns.
Endpoint Patterns.
System Management Patterns.
http://www.eaipatterns.com/
Design Pattern : DDD (Eric Evans, 2003)Le livre Domain-Driven Design, Tackling complexity in the heart of
software (2003) d’Eric Evans présente une approche des projets et du développement objet ainsi qu’un certain nombre de design patterns destinés aussi bien à la conception qu’à l’analyse.
Domain Model : entities, value object, services, module
Life cycle of Domain Object : aggregates, factories, repositories
Relating Design Patterns to the Model : strategy, composite
Etc.
http://domaindrivendesign.org/