designs patterns comment rendre son code faiblement couplé, et maintenable

52
Designs Patterns comment rendre son code faiblement couplé, et maintenable...

Upload: briefbras-cochet

Post on 03-Apr-2015

108 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Designs Patternscomment rendre son code faiblement couplé,

et maintenable...

Page 2: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Pourquoi réinventer la roue, alors que nos douleurs quotidiennes ont été étudiées par d’autres avant nous ?

Par masochisme ? Par sadisme ?

Constat :

Hormis les algorithmes métier,les difficultés de l’ingénierie de code sont souvent identiques !

Les solutions mises en œuvres sont (trop) souvent dépendante de l’imagination du développeur…

Une solution : Les Designs Patterns !

Ce sont un ensemble de recettes permettant de résoudre les principaux problèmes liés à l’ingénierie de code,

Objectif :Garder un code ouvert au changement, mais fermé aux

modifications,

Page 3: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Fondements des DP

GOF (Gang of four)N’est pas le groupe de musique post-punk des années 70…Mais plutôt les 4 créateurs à l’origine des DP !

« Chaque patron décrit un problème qui se manifeste constamment dans notre environnement, et donc décrit le cœur de la solution à ce problème, d’une façon telle que l’on puisse réutiliser cette solution des millions de fois, sans jamais le faire deux fois de la même manière »

23 patterns de « base »

Quel que soit le langage, ou la technologie objet !

Tous les autres sont des dérivés... (MVVM, ...)

Page 4: Designs Patterns comment rendre son code faiblement couplé, et maintenable

3 Types

Création (Creational Patterns)Singleton, Factory, Abstract Factory, Prototype

Structural (Structural Patterns)Adapter, Facade, Proxy,...

Comportements (Behavioral Patterns)Strategy, Chain of responsability, Iterator, Observer, ...

Page 5: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Formalisme

Page 6: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Entrons dans le vif du sujet

Page 7: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Le pattern Sssssssss

Page 8: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Etape 3L’année suivante, le client désire ajouter une évolution : les canards savent voler...

Nom : Sssssssss

Type : Comportement

But : Encapsuler les comportements susceptible de changer, afin de les rendre interchangeables. Exercice :

Etape 1Un client désire une FPS de canards...Un canard a un nom, peut nager, cancaner et doit être affiché.Etape 2Lors de la release de la version, le client note que tout les canards nagent et cancanent de la même manière... c’est MAL !.

Bug ! les canards en plastique qui étaient dans l’application (des leurres en quelque sorte) se mettent à voler...

Nous avons donc un problème de conception !

Quelles solutions d’après vous pourraient apporter implémentation pérenne, en d’autres termes :

Disposer d’une application fermée aux modifications mais ouverte aux changements ?

Page 9: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Héritage ?Interfaces ?

Reprenons de la hauteur !Quel est le réel problème ?

Que proposez vous comme solutions ?

LE CHANGEMENT !

Nom : Sssssssss

Type : Comportement

But : Encapsuler les comportements susceptible de changer, afin de les rendre interchangeables.

Page 10: Designs Patterns comment rendre son code faiblement couplé, et maintenable

LA VRAIE question porte donc sur ce qui change :Quels sont les différences entre les différents canards ?

réponse : leur comportement... (vol, cancan, affichage)

Nom : Sssssssss

Type : Comportement

But : Encapsuler les comportements susceptible de changer, afin de les rendre interchangeables.

Page 11: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Stratégie (Strategy)Type : Comportement

But : Encapsuler les comportements susceptible de changer, afin de les rendre interchangeables.

Cancan

etc.

Page 12: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Stratégie (Strategy)Type : Comportement

But : Encapsuler les comportements susceptible de changer, afin de les rendre interchangeables.

Exemple de stratégie

Page 13: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Stratégie (Strategy)Type : Comportement

But : Encapsuler les comportements susceptible de changer, afin de les rendre interchangeables.

Exemple de Contexte

Page 14: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Stratégie (Strategy)Type : Comportement

But : Encapsuler les comportements susceptible de changer, afin de les rendre interchangeables.

Exemples réels :Une application de paiement en ligne peut offrir différents moyens de paiements, il suffit de choisit la bonne stratégie en fonction du choix du client. Car hormis le mode de paiement, la suite du flux de commande demeure identique...

En .net, la classe ArrayList (contexte) est une bon exemple. La méthode sort par défaut offre une implémentation (stratégie concrète) par défaut. Cette méthode peut être substituée par l’implémentation fournie à l’exécution (implémentation de l’interface IComparer - stratégie)...

Page 15: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Privilégier le couplage faible favorise l’évolution...

Il est préférable

d’implémenter des

interfaces !

Retour sur les brèves de comptoir ...

L’héritage est un concept

qui s’applique au modèle

métier (le plus souvent).

Encapsuler ce qui change est un gage d’évolution !

Un code doit être ouvert au changement, mais

fermé aux modifications...

La composition est

préférable à l’héritage !

Nom : Stratégie (Strategy)Type : Comportement

But : Encapsuler les comportements susceptible de changer, afin de les rendre interchangeables.

Page 16: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Le pattern Aaaaaaa

Page 17: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Aaaaaaa

Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Reprenons notre SuperCanard...

Un jour, notre client favoris rachète un produit concurrent : Super Dindes.

Il vient nous voir, car il désire créer une édition spéciale :

Dindes VS Canards

Page 18: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Aaaaaaa

Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Reprenons notre précédent projet...

Quelle était le sujet de Super Canards ?

Quelles étaient les contraintes ?

Quelle solution(s) avons nous apporté ?

?

Page 19: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Aaaaaaa

Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure. Petit rappel...

La classe Duck, et les strategies de comportement...

Page 20: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Aaaaaaa

Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure. Petit rappel...

La classe Duck, et les strategies de comportement...

Page 21: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Privilégier le couplage faible favorise l’évolution...

Nom : Aaaaaaa

Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Il est préférable

d’implémenter des

interfaces !

Retour sur les brèves de comptoir ...

L’héritage est un concept

qui s’applique au modèle

métier (le plus souvent).

Encapsuler ce qui change est un gage d’évolution !

Un code doit être ouvert au changement, mais

fermé aux modifications...

La composition est

préférable à l’héritage !

Page 22: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Aaaaaaa

Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Quelles solutions pourraient apporter une solution simple, rapide... et

maintenable ?

VS

Page 23: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Aaaaaaa

Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Cela jacasse dur autour de ce concept !

Mais en termes d’implémentation cela donne quoi ?

Page 24: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Adaptateur (Adapter)Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

IHM gérant exclusivement des

canards...

Interface de canards...

Adaptateur canards-dinde Dinde

Page 25: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Aaaaaaa

Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Revenons à nos mouton...ou plutot à nos canards, et dindes...

En sachant ce que vous savez, quelle serait l’application du pattern Adapter ?

Page 26: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Adaptateur (Adapter)Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Solution = 3 adaptateurs :

- Adaptateur de comportement de nage,- Adaptateur de comportement Quack,- Adaptateur permettant de transformer une dinde en canard

Page 27: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Adaptateur (Adapter)Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Il est donc nécessaire d’adapter notre dinde aux concepts manipulés...

(comportements)(ceci est nécessaire pour adapter la dinde à l’implémentation

existante)Adaptateur pour passer d’un comportement lié à la classe au pattern stratégie

Interface Dinde - Duck différente... A l’initialisation,

fournir à l’adaptateur l’objet adapté !

Page 28: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Adaptateur (Adapter)Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Il est donc nécessaire d’adapter notre dinde aux concepts manipulés... (duck)

(ceci est nécessaire pour adapter la dinde à l’implémentation existante)

Page 29: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Adaptateur (Adapter)Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Utilisation...

12 3

Attention : un canard

peut masquer une dinde...

Page 30: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Adaptateur (Adapter)Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Un oeil dans le code ? une démo ?

Page 31: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Adaptateur (Adapter)Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.... et dans la vraie vie... le concret du

réel... pouvez vous me donner des exemples

decette implémentation ...?Adaptateur .net - COM,

Adaptateur entre dll third party et main app,Fonctionnement des add ons,

Hors informatique ? des adaptateurs de prise UK - FR, les réducteurs de wc pour enfants, les réducteur pour dock d’ipod etc.

Page 32: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Privilégier le couplage faible favorise l’évolution...

Nom : Adaptateur (Adapter)Type : Structural

But : Permettre à deux instances de classes d'interagir entre elles, sans modification de structure.

Il est préférable

d’implémenter des

interfaces !

Retour sur les brèves de comptoir ...

L’héritage est un concept

qui s’applique au modèle

métier (le plus souvent).

Encapsuler ce qui change est un gage d’évolution !

Un code doit être ouvert au changement, mais

fermé aux modifications...La composition est

préférable à l’héritage !

Ce n’est ni à la classe métier, ni au contexte à

devoir s’adapter...

Page 33: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Le pattern eeeeeeee

Page 34: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : EeeeeeeeType : Creational

But : Centraliser l’instanciation d’objets.

Et où est le problème ?

Techniquement, nulle part... mais en ce qui concerne la gestion du

changementil s’agit d’une autre affaire !

Jusque là, pour instancier des objets nous placions des new là où nous en avions besoin...

Page 35: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : EeeeeeeeType : Creational

But : Centraliser l’instanciation d’objets.En implémentant des interfaces, nous isolons le code des changements qui peuvent se

produire en aval.

En s’appuyant sur une interface, le code client continuera de fonctionner lors du

remplacement d’une classe, et ce par polymorphisme.

Le couplage est donc faible.

Page 36: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : EeeeeeeeType : Creational

But : Centraliser l’instanciation d’objets.

En codant nos classes sans interface, il est nécessaire de « réouvrir » le code aux

modifications pour prendre en compte à chaque changement de classe.

Page 37: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : EeeeeeeeType : Creational

But : Centraliser l’instanciation d’objets.

Comment éviter le coté obscure ?

Identifier ce qui changeet

L’externaliser !

souvenez vous des patterns stratégie et adapteur...

PS : Cette règle vaut pour tous les patterns...

Page 38: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : EeeeeeeeType : Creational

But : Centraliser l’instanciation d’objets.

Bonjour Messieurs,J’ai l’honneur de vous annoncer que vous avez été sélectionnés pour la réalisation de notre application de gestion de pizzérias.Félicitations !Luigi Del Gusto

Page 39: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : EeeeeeeeType : Creational

But : Centraliser l’instanciation d’objets.

En tant pour bon concepteur, comment aller vous mettre en

oeuvre cette application de pizza ?

Page 40: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : EeeeeeeeType : Creational

But : Centraliser l’instanciation d’objets.

Pour fêter les transhumances, Luigi désire ajouter à la carte des spécialités régionnales : - pizza raclette, - pizza reblochonne, - pizza au gorgonzola

J’en ai l’eau à la bouche !

Evolution :

Page 41: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : EeeeeeeeType : Creational

But : Centraliser l’instanciation d’objets.

Luigi revient nous voir, il a monté des pizzerias dans les quatre coin de France et Navarre.

Il désire maintenant s’exporter...

Or les pizza allemande portent le même nom que les françaises, seul la composition peut varier...Le processus de fonctionnement des pizzerias demeure le même...

Scoop : Une nouvelle évolution pointe le bout de son nez :

Page 42: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : EeeeeeeeType : Creational

But : Centraliser l’instanciation d’objets.

Qu’allez vous mettre en place pour permettre d’étendre l’application, tout en gardant le code fermé au maximum ?

Page 43: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Fabrique (Factory)Type : Creational

But : Centraliser l’instanciation d’objets.

La solution : La notion de fabrique et le pattern « fabrique abstraite »

Page 44: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Fabrique simple (Factory)Type : Creational

App pizzeria

Pizza napolitaine

Pizza 4 froms

4 fromsFR

4 fromsDE

Fabrique pizza

fabrique Fr fabrique DE

NapoFR

NapoDE

Contrat : Interface ou classe abstraite (italique)

Contrat : Interface ou classe abstraite (italique)

Implémentation

de la fabrique

Implémentationdes pizzas sur base des contrats

Page 45: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Nom : Fabrique (Factory)Type : Creational

Une dernière notion : le client consomme la «bonne fabrique abstraite» via une méthode «

fabrique »

consomme

Page 46: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Un oeil dans le code ? une démo ?

Nom : Fabrique (Factory)Type : Creational

Page 47: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Pourquoi favoriser l’utilisation des principes de fabrique et fabrique abstraite ?

Nom : Fabrique (Factory)Type : Creational

Les constructeurs sont assez limités dans leur processus de création : ils retourne une instance de xxx.

Pour permettre une plus grande évolutivité, les fabriques permettent de découpler les logiques d'interactions, de l’implémentation...

Ce qui permet de masquer l’implémentation au consommateur de classes...

Page 48: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Pourquoi favoriser l’utilisation des principes de fabrique et fabrique abstraite ?

Nom : Fabrique (Factory)Type : Creational

Régulièrement, nous sommes confrontés à des incertitudes du client. Les choix permettant de levés ces incertitudes peuvent être repoussés à plus loin, sans pour autant bloquer le développement des applications.

Exemple : Ado.net permet de masquer, et de paramétrer l’implémentation utilisée via les chaines de connexions.Pour ce faire, nous pouvons utiliser l’espace de nom Db : DbConnection, DbCommand, DbDataAdapter

Page 49: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Pourquoi favoriser l’utilisation des principes de fabrique et fabrique abstraite ?

Nom : Fabrique (Factory)Type : Creational

Les constructeurs ne laissent pas toujours deviner de leurs intentions réelles. Imaginons une classe, avec de multiples constructeurs :

public Vehicle (int passengers)public Vehicle (int passengers, int horsePower)public Vehicle (int wheels, bool trailer)public Vehicle (string type)

Page 50: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Pourquoi favoriser l’utilisation des principes de fabrique et fabrique abstraite ?

Nom : Fabrique (Factory)Type : Creational

La factory clarifie rapidement l’intention du développeur

public Vehicle CreateCar (int passengers)public Vehicle CreateSuv (int passengers, int horsePower)public Vehicle CreateTruck (int wheels, bool trailer)public Vehicle CreateBoat ()public Vehicle CreateBike ()

Page 51: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Pourquoi favoriser l’utilisation des principes de fabrique et fabrique abstraite ?

Nom : Fabrique (Factory)Type : Creational

Vous verrez que derrière le terme de fabrique, nous retrouvons souvent à la fois des fabriques abstraites et des méthodes de fabriques.En .net, les méthodes fabriques sont surtypées par Factory.

Page 52: Designs Patterns comment rendre son code faiblement couplé, et maintenable

Privilégier le couplage faible favorise l’évolution...

Il est préférable

d’implémenter des

interfaces !

Retour sur les brèves de comptoir ...

Les interfaces sont des

contrats remplis par

certaines instances, et

consommés par d’autres

Encapsuler ce qui change est un gage d’évolution !

Un code doit être ouvert au changement, mais

fermé aux modifications...

Les composants applicatifs consomment les instances, mais ne sont pas responsables de leur instanciation

Nom : Fabrique (Factory)Type : Creational

Centraliser les créations d’instances favorise la

dissociation entre modèle et comportement.

Le « new » n’est pas si anodin que cela !