Design poo togo_jug_final

97
Agnès CREPET @agnes_crepet Cyril LACÔTE @clacote 13 aout 2011 TogoJUG - Lomé Principes de la conception objet L'enjeu du design Les Design Patterns

description

Slides from Togo JUG talk on 2011 August 13th at Lomé Catholic University. Talk was co-presented with Cyril Lacote

Transcript of Design poo togo_jug_final

Page 1: 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

Page 2: Design poo togo_jug_final

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

Page 3: Design poo togo_jug_final

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 »)

Page 4: Design poo togo_jug_final

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

Page 5: Design poo togo_jug_final

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 ?

Page 6: Design poo togo_jug_final

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 !

Page 7: Design poo togo_jug_final

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 ...

Page 8: Design poo togo_jug_final

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

Page 9: Design poo togo_jug_final

Modularité

Factorisation de code, réutilisation

Fonction

Module

Sous-programme

Oblige à l'isolation

Traitements / données

FORTRAN 58, ALGOL 60, PASCAL 70, C 73

Page 10: Design poo togo_jug_final

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 !

Page 11: Design poo togo_jug_final

Démarche objet : pas si récente !

Années 60 : recherches au MIT

Modula : 1967

SmallTalk : 1972

C++ : 1981

Java : 1995

Page 12: Design poo togo_jug_final

Objet : motivations

Une idée fondatrice :

Proche du monde réel

demarrer( )freiner( )

vitessemodèle

Voiture

Abstraction

Page 13: Design poo togo_jug_final

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 !

Page 14: Design poo togo_jug_final

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 !

Page 15: Design poo togo_jug_final

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

Page 16: Design poo togo_jug_final

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

Page 17: Design poo togo_jug_final

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

Page 18: Design poo togo_jug_final

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

Page 19: Design poo togo_jug_final

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 !

Page 20: Design poo togo_jug_final

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.

Page 21: Design poo togo_jug_final

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

Page 22: Design poo togo_jug_final

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

Page 23: Design poo togo_jug_final

Moyens fondamentaux :

Encapsulation

Héritage

Polymorphisme

Prémisses de solution à la mise en œuvre des principes de bonne conception

Les fondements de l'objet

Page 24: Design poo togo_jug_final

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 !

Page 25: Design poo togo_jug_final

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

Page 26: Design poo togo_jug_final

L'encapsulation

Avantages :

Garantir l'intégrité des données

Changer d'implémentation

Limiter les effets de bord

Page 27: Design poo togo_jug_final

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

Page 28: Design poo togo_jug_final

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

Page 29: Design poo togo_jug_final

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()

Page 30: Design poo togo_jug_final

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

Page 31: Design poo togo_jug_final

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

Page 32: Design poo togo_jug_final

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

Page 33: Design poo togo_jug_final

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.

Page 34: Design poo togo_jug_final

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

Page 35: Design poo togo_jug_final

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

Page 36: Design poo togo_jug_final

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

Page 37: Design poo togo_jug_final

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

Page 38: Design poo togo_jug_final

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

Page 39: Design poo togo_jug_final

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...

Page 40: Design poo togo_jug_final

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

Page 41: Design poo togo_jug_final

Affectation des responsabilités

Page 42: Design poo togo_jug_final

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

Page 43: Design poo togo_jug_final

"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

Page 44: Design poo togo_jug_final

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

Page 45: Design poo togo_jug_final

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.

Page 46: Design poo togo_jug_final

Mesure l'interdépendance entre composants

G.R.A.S.P. : Faible couplage ( 1/2)

Page 47: Design poo togo_jug_final

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)

Page 48: Design poo togo_jug_final

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 !

Page 49: Design poo togo_jug_final

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

Page 50: Design poo togo_jug_final

Quelles solutions pour garantirun faible couplage

et une forte cohésion ?

Page 51: Design poo togo_jug_final

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

Page 52: Design poo togo_jug_final

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

Page 53: Design poo togo_jug_final

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.

Page 54: Design poo togo_jug_final

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

Page 55: Design poo togo_jug_final

Gestion des dépendancesInversion de contrôle

Page 56: Design poo togo_jug_final

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

Page 57: Design poo togo_jug_final

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?

Page 58: Design poo togo_jug_final

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]

Page 59: Design poo togo_jug_final

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

Page 60: Design poo togo_jug_final

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

Page 61: Design poo togo_jug_final

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

Page 62: Design poo togo_jug_final

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

Page 63: Design poo togo_jug_final

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

Page 64: Design poo togo_jug_final

Injection de dépendance : exemple

Exemple :

Un chat veut jouer...

Trois approches :

De base, sans injection

Avec injection manuelle

Avec injection par un conteneur

Page 65: Design poo togo_jug_final

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();

Page 66: Design poo togo_jug_final

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

Page 67: Design poo togo_jug_final

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();

Page 68: Design poo togo_jug_final

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)

Page 69: Design poo togo_jug_final

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

Page 70: Design poo togo_jug_final

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;

}

Page 71: Design poo togo_jug_final

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

“type-safe en annotations”?
Page 72: Design poo togo_jug_final

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)

Page 73: Design poo togo_jug_final

Design Pattern en vogueConvention over Configuration

Page 74: Design poo togo_jug_final

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*/ }

}

Page 75: Design poo togo_jug_final

Patterns d'architecture2 grandes familles(selon Adam Bien)

Page 76: Design poo togo_jug_final

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)

?

Page 77: Design poo togo_jug_final

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

Page 78: Design poo togo_jug_final

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

Page 79: Design poo togo_jug_final

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

Page 80: Design poo togo_jug_final

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

Page 81: Design poo togo_jug_final

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

Page 82: Design poo togo_jug_final

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

Page 83: Design poo togo_jug_final

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 !

Page 84: Design poo togo_jug_final

Bibliographie

Page 85: Design poo togo_jug_final

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

Page 86: Design poo togo_jug_final

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

Page 87: Design poo togo_jug_final

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

Page 88: Design poo togo_jug_final

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

Page 89: Design poo togo_jug_final

Best-Of Design Patterns

Page 90: Design poo togo_jug_final

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)

Page 91: Design poo togo_jug_final

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.

Page 92: Design poo togo_jug_final

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.

Page 93: Design poo togo_jug_final

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

Page 94: Design poo togo_jug_final

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.

Page 95: Design poo togo_jug_final

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.

Page 96: Design poo togo_jug_final

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/

Page 97: Design poo togo_jug_final

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/