Principes de la conception objet L'enjeu du design Les Design Patterns Agnès CREPET @agnes_crepet Cyril LACÔTE @clacote 13 aout 2011 TogoJUG - Lomé
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 Calcul Calcul: 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 fichier Tant 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( ) vitesse modèle Voiture Abstraction
Pourquoi l'objet ? Maintenable Flexible Extensible Coût d'un projet : 15% développment 70% maintenance ! Doc Conception Test Code Autre Révision &  Maintenance Source: DP Budget, Vol. 7, Dec 1998.
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 extensions Pouvoir ajouter de nouveaux comportements ->  S'adapter aux changements ! Être fermé aux modifications Le 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
Encapsulation : exemple SANS AVEC class Adresse { public  String nom; … . } class Adresse { private   String nom public   setNom   (String aNom) { nom = aNom; } // Saisie des livraisons Adresse adrLiv = new Adresse(); ... adrLiv.nom  = « Dupond »; // Saisie des livraisons Adresse adrLiv = new Adresse(); ... adrLiv.setNom  (« Dupond »); // Saisie de facturation Adresse adrFac = new Adresse(); ... adrFac.nom   = « Dupond »; // Saisie de facturation Adresse 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 livraisons Adresse adrLiv = new Adresse(); ... adrLiv.nom  = « Dupond » .toUpperCase() ; // Saisie des livraisons Adresse adrLiv = new Adresse(); ... adrLiv.setNom  (« Dupond »); // Saisie de facturation Adresse adrFac = new Adresse(); ... adrFac.nom   = « Dupond ». toUpperCase() ; // Saisie de facturation Adresse adrFac = new Adresse(); ... adrFac.setNom   (« Dupond »);
L'héritage Partage de caractéristiques communes Attributs & Comportements Personne nom : chaîne age : entier seMarie() Employé nom : chaîne age : entier société : chaîne seMarie() estPromu() Personne nom : chaîne age : entier seMarie() Employé société : chaîne estPromu()
L'h éritage Généralisation Spécialisation Véhicule moteur VéhiculeTerrestre nombreRoues VéhiculeMaritime VéhiculeAérien altitudeMax Voiture Camion Paquebot cabines Péniche Avion ailes Hélicoptère rotors
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 La voie du polymorphisme public interface Dessinable { void draw (); // public abstract implicite }
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
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.
G.R.A.S.P. : Faible couplage ( 1/2) Mesure l'interdépendance entre composants
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 garantir un 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 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
Gestion des dépendances Inversion 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 ! 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!) A B A B ? 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 niveaux exemple : sauvegarder en BDD Concrétiser ces besoins par des interfaces exemple : 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=&quot;leJouet&quot; class=&quot;com.injection.with.jeu.Souris&quot; /> <bean id=&quot;chat&quot; class=&quot;com.injection.with.Chat&quot;> < property name=&quot;jouet&quot;  ref=&quot; leJouet &quot; /> </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 vogue Convention 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'architecture 2 grandes familles (selon Adam Bien)
Exemples d'architecture applicative Application Java web Couches Applicatives  (présentation, service, métier… HTML/ JavaScript HTTP  …  et persistance) JDBC Navigateur web Serveur d’application (ex : JBoss) Serveur de base  de données (Ex: Oracle) Exterieur de  l'application (Système d'information de l'entreprise ) ? SGBDR
Des couches logicielles Présentation Façade Service Persistance Page JSP Contrôleur Logique applicative Façades Services métier Objets du domaine Repository accès aux données Objets du domaine 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 Services métier Repository SGBDR  Objets du domaine
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 petit mais 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 &quot;Real World Java EE Night Hacks - Dissecting the Business Tier&quot; Adam Bien – 2009 - Press Adam Biem &quot;Real World Java EE Patterns - Rethinking Best Practices &quot; 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 &quot;Domain-Driven Design&quot; : 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 objets Factory :  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 services Facade (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/

Contenu connexe

PDF
AgileTour Toulouse 2012 : clean code en pratique
KEY
Introduction rapide à 'objet et à UML
ODP
Formation PHP
PPT
Design Patterns
ODP
Migration PHP4-PHP5
PDF
Trivial Java - Part 1
PPT
Duchess advice events_september2011
PDF
Presentation anniversaire duchess
AgileTour Toulouse 2012 : clean code en pratique
Introduction rapide à 'objet et à UML
Formation PHP
Design Patterns
Migration PHP4-PHP5
Trivial Java - Part 1
Duchess advice events_september2011
Presentation anniversaire duchess

Similaire à Design poo togo_jug_final (20)

PPT
Design Patterns Java
ODP
Formation PHP avancé - Cake PHP
PDF
Qualité logicielle
PDF
Tutoriel java
KEY
Design patterns
KEY
Design patterns
PPTX
Javascript un langage supérieur
PDF
Coder propre !
ODP
Patterns and OOP in PHP
PDF
Comment récupérer un projet Web pourri ... et réussir à travailler dessus.
PDF
Patrons de conception de la programmation fonctionnelle
PPTX
Hibernate
PPT
20111006 bonnes pratiques-gi_g_v1
PPTX
Drools
PDF
Wordcamp paris 2015 dev-pragmatique-bonnes-pratiques
PPT
Présentation Groovy
PPT
Présentation Groovy
PPT
Domain-Specific Languages avec Groovy
PPT
Sds Programme
PPTX
Cours Ynov JS B1_1
Design Patterns Java
Formation PHP avancé - Cake PHP
Qualité logicielle
Tutoriel java
Design patterns
Design patterns
Javascript un langage supérieur
Coder propre !
Patterns and OOP in PHP
Comment récupérer un projet Web pourri ... et réussir à travailler dessus.
Patrons de conception de la programmation fonctionnelle
Hibernate
20111006 bonnes pratiques-gi_g_v1
Drools
Wordcamp paris 2015 dev-pragmatique-bonnes-pratiques
Présentation Groovy
Présentation Groovy
Domain-Specific Languages avec Groovy
Sds Programme
Cours Ynov JS B1_1
Publicité

Plus de Duchess France (12)

PDF
Conding Dojo Fruit Shop
PPTX
Dans les coulisses de Google BigQuery
PDF
Hands-On Apache Spark
PDF
4 ans de Duchess France : Cassandra 2.0
PDF
BOF Duchess France à Devoxx France 2013
PDF
Gemfire Sqlfire - La Marmite NoSql
KEY
MongoDB - Marmite NoSql
PDF
Neo4 j - Marmite NoSql
PDF
Intro - La Marmite NoSql
KEY
2 ans de Duchess France - Ouverture
PDF
Ces nanas qui codent
PDF
Trivial Java - Part 2
Conding Dojo Fruit Shop
Dans les coulisses de Google BigQuery
Hands-On Apache Spark
4 ans de Duchess France : Cassandra 2.0
BOF Duchess France à Devoxx France 2013
Gemfire Sqlfire - La Marmite NoSql
MongoDB - Marmite NoSql
Neo4 j - Marmite NoSql
Intro - La Marmite NoSql
2 ans de Duchess France - Ouverture
Ces nanas qui codent
Trivial Java - Part 2
Publicité

Design poo togo_jug_final

  • 1. Principes de la conception objet L'enjeu du design Les Design Patterns Agnès CREPET @agnes_crepet Cyril LACÔTE @clacote 13 aout 2011 TogoJUG - Lomé
  • 2. 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
  • 3. 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 Calcul Calcul: Lecture du compte Calcul du solde Mise à jour compte go to Read: Fin-Fichier: close (« interface-File »)
  • 4. 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
  • 5. 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 ?
  • 6. 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 !
  • 7. Approche top-down Ouverture fichier Traitement fichier Fermeture fichier Tant qu ’il y a des enregistrements Traitement Facture Traitement Avoir Traitement du solde ReadCompte Calcul Solde UpdateCompte Traitement du solde ...
  • 8. 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
  • 9. Modularité Factorisation de code, réutilisation Fonction Module Sous-programme Oblige à l'isolation Traitements / données FORTRAN 58, ALGOL 60, PASCAL 70, C 73
  • 10. 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 !
  • 11. Démarche objet : pas si récente ! Années 60 : recherches au MIT Modula : 1967 SmallTalk : 1972 C++ : 1981 Java : 1995
  • 12. Objet : motivations Une idée fondatrice : Proche du monde réel demarrer( ) freiner( ) vitesse modèle Voiture Abstraction
  • 13. Pourquoi l'objet ? Maintenable Flexible Extensible Coût d'un projet : 15% développment 70% maintenance ! Doc Conception Test Code Autre Révision & Maintenance Source: DP Budget, Vol. 7, Dec 1998.
  • 14. 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 !
  • 15. 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
  • 16. 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, &quot;Design Pattern. Elements of Reusable Object-oriented sofware&quot;, 1995
  • 17. 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
  • 18. 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
  • 19. Un principe fondateur : l'OCP (1/2) Open - Close Principle (OCP) Tout module (package,classe,méthode) doit : Être ouvert aux extensions Pouvoir ajouter de nouveaux comportements -> S'adapter aux changements ! Être fermé aux modifications Le code existant ne peut être modifié, seul l’ajout est permis. -> Ne pas casser ce qui fonctionne !
  • 20. 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.
  • 21. 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
  • 22. 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
  • 23. Moyens fondamentaux : Encapsulation Héritage Polymorphisme Prémisses de solution à la mise en œuvre des principes de bonne conception Les fondements de l'objet
  • 24. 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 !
  • 25. 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
  • 26. L'encapsulation Avantages : Garantir l'intégrité des données Changer d'implémentation Limiter les effets de bord
  • 27. Encapsulation : exemple SANS AVEC class Adresse { public String nom; … . } class Adresse { private String nom public setNom (String aNom) { nom = aNom; } // Saisie des livraisons Adresse adrLiv = new Adresse(); ... adrLiv.nom = « Dupond »; // Saisie des livraisons Adresse adrLiv = new Adresse(); ... adrLiv.setNom (« Dupond »); // Saisie de facturation Adresse adrFac = new Adresse(); ... adrFac.nom = « Dupond »; // Saisie de facturation Adresse adrFac = new Adresse(); ... adrFac.setNom (« Dupond »);
  • 28. Encapsulation : exemple SANS AVEC class Adresse { public String nom; … . } class Adresse { private String nom public setNom (String aNom) { nom = aNom .toUpperCase() ; } // Saisie des livraisons Adresse adrLiv = new Adresse(); ... adrLiv.nom = « Dupond » .toUpperCase() ; // Saisie des livraisons Adresse adrLiv = new Adresse(); ... adrLiv.setNom (« Dupond »); // Saisie de facturation Adresse adrFac = new Adresse(); ... adrFac.nom = « Dupond ». toUpperCase() ; // Saisie de facturation Adresse adrFac = new Adresse(); ... adrFac.setNom (« Dupond »);
  • 29. L'héritage Partage de caractéristiques communes Attributs & Comportements Personne nom : chaîne age : entier seMarie() Employé nom : chaîne age : entier société : chaîne seMarie() estPromu() Personne nom : chaîne age : entier seMarie() Employé société : chaîne estPromu()
  • 30. L'h éritage Généralisation Spécialisation Véhicule moteur VéhiculeTerrestre nombreRoues VéhiculeMaritime VéhiculeAérien altitudeMax Voiture Camion Paquebot cabines Péniche Avion ailes Hélicoptère rotors
  • 31. 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
  • 32. 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
  • 33. 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.
  • 34. 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 La voie du polymorphisme public interface Dessinable { void draw (); // public abstract implicite }
  • 35. Comment réaliser des extensions sans modifier l'existant ? L'enjeu d'un bon Design
  • 36. Rappel : le challenge de l'OCP PrixAchat prixAchat = new PrixAchat(article); PrixFabrication prixFabrication = new PrixFabrication(article); ... double calculPrixRevient() { if (&quot;Article.ACHAT&quot;.equals(getArticle().getType())) return prixAchat.calculPrixAchat() * coef; else return prixFabrication.calculPrixFabrication() * coef; } calculPrixRevient() n'est pas fermée aux modifications
  • 37. Comment réaliser des extensions sans modifier l'existant ? L'enjeu d'un bon Design
  • 38. 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
  • 39. Rappel : le challenge de l'OCP if (&quot;Article.ACHAT&quot;.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...
  • 40. 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
  • 42. Comment assigner les rôles aux classes? Qui fait quoi? -> General Responsibility Assignment Software Patterns [Graig Larman, &quot;Applying UML and Patterns&quot;, 1998] Affectation des responsabilités
  • 43. &quot;Savoir&quot; (Knowing) Connaissance des objets privés Connaissance des objets liés Connaissance de résultats de calculs ou dérivés &quot;Savoir Faire&quot; (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
  • 44. 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. &quot;Celui qui sait, fait&quot; (Knowing is doing) C’est le principe élémentaire
  • 45. 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.
  • 46. G.R.A.S.P. : Faible couplage ( 1/2) Mesure l'interdépendance entre composants
  • 47. 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)
  • 48. 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 !
  • 49. 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
  • 50. Quelles solutions pour garantir un faible couplage et une forte cohésion ?
  • 51. 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 &quot;voir&quot; que les services qu'il utilise réellement
  • 52. 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 Service Logistique Saisie des commandes
  • 53. 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.
  • 54. ISP : exemple gestion de commandes Respect de l'ISP : Séparation des interfaces Service Logistique Saisie des commandes
  • 55. Gestion des dépendances Inversion de contrôle
  • 56. 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
  • 57. Dépendances : un choix stratégique ! 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!) A B A B ? ou ?
  • 58. 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,&quot;Object Oriented Design Quality Metrics&quot;, 1995]
  • 59. 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
  • 60. 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
  • 61. 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 niveaux exemple : sauvegarder en BDD Concrétiser ces besoins par des interfaces exemple : interface Persistence Implémenter cette interface dans les modules de bas niveaux dépendant des drivers de BDD
  • 62. 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
  • 63. 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
  • 64. Injection de dépendance : exemple Exemple : Un chat veut jouer... Trois approches : De base, sans injection Avec injection manuelle Avec injection par un conteneur
  • 65. 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();
  • 66. 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
  • 67. 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();
  • 68. 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)
  • 69. 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
  • 70. Injection de dépendance : conteneur Configuration XML (exemple : Spring) : <beans> <bean id=&quot;leJouet&quot; class=&quot;com.injection.with.jeu.Souris&quot; /> <bean id=&quot;chat&quot; class=&quot;com.injection.with.Chat&quot;> < property name=&quot;jouet&quot; ref=&quot; leJouet &quot; /> </bean> </beans> Configuration par annotations (normalisées JEE6): public class Chat { @Inject private IJouet jouet; }
  • 71. 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
  • 72. 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)
  • 73. Design Pattern en vogue Convention over Configuration
  • 74. 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*/ } }
  • 75. Patterns d'architecture 2 grandes familles (selon Adam Bien)
  • 76. Exemples d'architecture applicative Application Java web Couches Applicatives (présentation, service, métier… HTML/ JavaScript HTTP … et persistance) JDBC Navigateur web Serveur d’application (ex : JBoss) Serveur de base de données (Ex: Oracle) Exterieur de l'application (Système d'information de l'entreprise ) ? SGBDR
  • 77. Des couches logicielles Présentation Façade Service Persistance Page JSP Contrôleur Logique applicative Façades Services métier Objets du domaine Repository accès aux données Objets du domaine Http SGBDR
  • 78. 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
  • 79. 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
  • 80. 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
  • 81. 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 Services métier Repository SGBDR Objets du domaine
  • 82. 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
  • 83. 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 petit mais penser grand !
  • 85. 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
  • 86. 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
  • 87. Bibliographie &quot;Real World Java EE Night Hacks - Dissecting the Business Tier&quot; Adam Bien – 2009 - Press Adam Biem &quot;Real World Java EE Patterns - Rethinking Best Practices &quot; Adam Bien – 2011- Press Adam Bien
  • 88. 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 &quot;Domain-Driven Design&quot; : http://domaindrivendesign.org
  • 90. 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)
  • 91. 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.
  • 92. Exemples Gof : Gestion des objets Factory : 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.
  • 93. 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
  • 94. 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.
  • 95. Exemples Gof/PEAA : Accès aux services Facade (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.
  • 96. 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/
  • 97. 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/

Notes de l'éditeur

  • #2: Commentaires
  • #5: Dijkstra : « plus court chemin » dans un graphe, algorithme du banquier, sémaphore.
  • #34: Polymorphisme d&apos;héritage = Polymorphisme d&apos;inclusion  redéfinition/spécialisation de méthodes durant l&apos;héritage (overriding) Polymorphisme paramétrable  Les types génériques, introduits avec Java 5, donnent la possibilité de ne pas devoir contrôler le type d&apos;une valeur lors de l&apos;exécution, ils permettent de définir des comportements communs sur des objets sans devoir les typer Polymorphisme ad hoc = surcharge de méthodes (overloading)  capacité de distinguer des opérations par la signature (avec types et arguments différents) plutôt que par le seul nom
  • #75: une configuration par défaut (convention par règle de nommage) mais permettront aussi la substitution des valeurs par défaut via la configuration (à partir des fichiers ou une autre source de données).
  • #86: Expliquer l’origine historique du concept : issu de l’architecture de bâtiments.
  • #92: Creational patterns These patterns have to do with class instantiation. They can be further divided into class-creation patterns and object-creational patterns. While class-creation patterns use inheritance effectively in the instantiation process, object-creation patterns use delegation to get the job done. Abstract Factory groups object factories that have a common theme. Builder constructs complex objects by separating construction and representation. Factory Method creates objects without specifying the exact class to create. Prototype creates objects by cloning an existing object. Singleton restricts object creation for a class to only one instance.