Template Method - Laurent Henocque

laurent.henocque.com

Template Method - Laurent Henocque

Design Patterns

Laurent Henocque

http://laurent.henocque.free.fr/

Enseignant Chercheur ESIL/INFO France

http://laurent.henocque.perso.esil.univmed.fr/

mis à jour en Septembre 2009


Licence Creative Commons

Cette création est mise à disposition selon le Contrat

Paternité-Partage des Conditions Initiales à

l'Identique 2.0 France disponible en ligne

http://creativecommons.org/licenses/by-sa/2.0/fr/

ou par courrier postal à Creative Commons, 559

Nathan Abbott Way, Stanford, California 94305,

USA.


Préambule

• Ce support de cours présente de nombreux

diagrammes, dont certains peuvent contenir des

erreurs UML2

• Il n'est donc pas utilisable sans l'aide d'un

enseignant


Objectifs pédagogiques

• Permettre, en découvrant les design patterns, de

maîtriser totalement les diagrammes de classes

• Pré-requis pour l’étude des spécifications UML

• C’est un cours d’apprentissage de l’agilité à

comprendre et formuler des modèles abstraits


Contexte

• De très nombreux projets logiciels font apparaître des

éléments comparables

• Réinventer les meilleures solutions connues dans chaque

nouveau projet est inutile, et risqué

• Analysis Patterns

• Design Patterns

• Frameworks

• Workflow Patterns


Pourquoi les Patterns

• La réussite prime sur la nouveauté

• Importance de la clarté de la documentation

• Validation qualitative des acquis et de la

connaissance pratique

• Importance de la dimension humaine dans le

développement logiciel

• Faciliter la réutilisation de savoir faire


Sur la réutilisation

Les langages informatiques modernes orientés objet

permettent la réutilisation

• par la réutilisation d’interfaces (mixin)

• par importation de classes

• par héritage : extension / spécialisation

• par l'inversion de contrôle

• par les aspects

• par les architectures à plugins, etc...


Les patterns c'est quoi?

Design Pattern

=

Schéma de conception réutilisable

=

Organisation et hiérarchie de plusieurs modèles de

classes réutilisable par simple implémentation,

adaptation, extension


Comment?

• Les Design Patterns sont présentés en utilisant la

notation graphique standard UML

• Pour l'essentiel, seule la partie statique

(diagrammes de classes) de UML est utilisée


Diagrammes de Classes UML2

(éléments)

Classe_A

relation

Classe_B

héritage

Classe_C

attributs

fonctions

agrégat / composition

Classe_D

dépendance


Références


Références Web

• http://patterndigest.com/

• http://norvig.com/design-patterns

• http://www.industriallogic.com/papers/

index.html

• … google…


Exemples Simples : Intuition

Quelques exemples de "proto" patterns, ou

d'éléments de conception réutilisables non

officialisés


La Liste

• La liste (ce n'est pas un schéma, mais un

élément de conception orientée objet)

Ce modèle est largement criticable : quels sont ses

défauts?


Collection

Gestion de collections via une classe

Ce modèle ne respecte pas les conventions UML:

quels sont ses défauts?


Attribut Relation

• Définir un rôle d'une relation (binaire) par un

pointeur


Maître / Esclave

• Déléguer la gestion d'une relation à une classe

intermédiaire


Objet Relation

• Modéliser une relation importante par un objet

(on veut ignorer la façon dont la relation est

gérée)


Le “Méga Pattern MVC”

Model View Controller, au coeur de tous les

frameworks web: J2EE/Struts/... (Java), Ruby on

Rails, Code Ignitor,Yii (php)...


Model View Controller


Model View Controller

MVC peut être vu comme une combinaison de design patterns

• Les vues sont organisées selon Composite

• Le lien entre vues et modèles est l' Observer.

• Les contrôleurs sont des Strategy attachées aux vues.

MVC peut mettre en jeu encore d'autres patterns:

• Le modèle est souvent un Mediator

• Les arbres de vues mettent en œuvre Decorator

• On a souvent besoin d' Adapter pour convertir l'interface d'un Modèle de

façon à ce qu'elle soit adaptée aux vues.


Document View Pattern

• Document View est une version simplifiée de

MVC où la vue agit selon le pattern Observer, et

est mise à jour en fonction de l'état du document

• (Mis en œuvre dans les MFC)


Emergence du Beau

La modélisation objet a fait émerger de nouvelles

constructions remarquables


Le Méta Méta Modèle noyau

de UML

• Ce diagramme auto-descriptif est une perfection

ontologique


Le pattern Composite

• Le plus petit diagramme décrivant un principe

de portée générale


7 Design Patterns

Fondamentaux


3 grandes catégories de

Patterns

• Patterns structuraux

• décrivent une organisation de classes dans l'optique

"structure de données"

• Patterns de création

• décrivent des approches de création déléguée d'objets

• Patterns dynamiques

• décrivent une organisation de classes gérant les aspects

dynamiques d'un système


Un noyau de 7 Design

Patterns Fondamentaux

• On débute par 7 schémas d'utilisation très répandue

• Composite

• Iterator

• Command

• Adapter

• Singleton

• Factory Method

Template Method


Composite

Composer des structures de données récursives


Composite

• Composer des structures de données récursives


Composite : exemples

• Toute structure de données récursive

• classes collections

• conteneurs graphiques

• structure de document (chapitre/section/

paragraphe...)

• container conceptuel (états composites dans les

diagrammes d’état UML)


Analyse

• Composite superpose :

• une hiérarchie de types (taxonomie) et

• une hiérarchie de conteneurs (partonomie).


Exercices

• Définir une hiérarchie de classes récursive pour

des interfaces homme machine (trois classes

suffisent)

• Définir un modèle pour des expressions

arithmétiques


Iterator

Parcourir des conteneurs en masquant

l'implantation


Iterator

• Parcourir des conteneurs en masquant

l'implantation


Iterator

• Un Pattern qui met en oeuvre une collaboration


Iterator : exemples

• Toute logique de parcours de container

• Exemples nombreux en Java

• On veut enlever des structures de données toute

information relative à son parcours, et ainsi

permettre de faire varier les modes de parcours


Analyse

• Itérator sépare la logique de l’itération dans un

objet indépendant dont les états logiques et

physiques correspondent.

• Sert de nombreux impératifs de bonne

conception (séparation, masquage, couplage

faible)

• Permet de définir des hiérarchies d’itérateurs


Itérator est un cas complexe

• Une caractéristique fondamentale d’itérator

consiste à déléguer la création au conteneur

• Ce principe est isolé dans plusieurs patterns

“créationaux”, dont “factory”


Exercices

• Lister les différents services attendus des

itérateurs

• Définir un modèle compatible avec itérator pour

deux classes liste et vecteur et deux itérateurs

pour chacune d’elles


Command

Encapsuler une requête dans un objet


Function Object

• Encapsuler une fonction dans un objet

• Les pointeurs de fonctions revisités dans

un “proto” pattern

FunctionObject

_____________________

execute(param)

ConcreteFunctionObject

_____________________

state

_____________________

execute(param)


Command

• Encapsuler une requête dans un objet


Command : exemples

• Command remplace les pointeurs vers fonctions dans

tous les langages objet évolués.

• Command interface l'appel d'une opération via une

méthode virtuelle.

• Utilisé dans les interfaces homme machine pour

attacher un comportement à un objet


Exercices

• Imaginer une api pour mettre en place des

callbacks dans une interface au moyen de

«!command!»

• Imaginer un mécanisme basé sur command

permettant d’appeler une chaîne d’opérations

automatiquement


(Class) Adapter

Convertir une interface par héritage multiple


(Class) Adapter

• Convertir une interface par héritage multiple


Adapter : exemples

• Toute situation où l'on veut réutiliser du code,

mais pas son interface de programmation.

• Par exemple, dans le cas où un code ancien, ou

tiers, ne respecte pas notre charte de

présentation


Object Adapter (Wrapper)

• Convertir une interface par composition

• Variante d’adapter utilisable en l’absence

d’héritage multiple


Exercice

• Définir trois classes de formes géométriques

indépendantes, et n’appartenant pas à une

hiérarchie, puis définir une hiérarchie qui

réutilise les précédentes par adaptation


Singleton

Gérer une instance unique


Singleton

• Gérer une instance unique

Singleton

---------------------------

static instance()

return uniqueInstance

singletonOperation()

getSingletonData()

---------------------------

static uniqueInstance

singletonData


Singleton : exemples

• Singleton permet de gérer la création à la

demande (lazy) d'un objet unique.

• L'objet est créé au premier accès de façon

invisible

• Exemples : le spooler d'impressions, le système

de fichiers dans un OS


Exercice

• Définir une classe singleton en Java, avec

initialisation paresseuse (on ne crée l’unique

instance qu’au moment du premier accès)

• Id, mais avec une initialisation à priori


Factory Method

Définir une interface de création, mais laisser les

sous classes décider du type


Factory Method

• Définir une interface de création, mais laisser les

sous classes décider du type


Factory Method : exemples

• C'est un fragment de Abstract Factory (voir plus loin)

• C'est un exemple de "Template Method" (voir ci

après)

• Utile par exemple pour créer des itérateurs. Chaque

classe d'une hiérarchie de containers implante sa

version de "createIterator()", qui retourne un objet du

type adéquat.


Exercice

• Mettre en œuvre «!factory method!» dans le cas

d’itérateurs, en prévoyant plusieurs classes de

conteneurs et plusieurs catégories d’itérateurs


Template Method

Prévoir un squelette de fonction, et compléter

par les sous classes


Template Method

• Prévoir un squelette de fonction, et

compléter par les sous classes


Analyse

• Il s’agit d’une sorte d’héritage inversé

• Les sous classes héritent d’un algorithme

générique, dont elles implantent les éléments

spécifiques


Template method : exemple

• La logique de création et archivage par nécessité suivante

peut être définie par une super classe, et ses détails

implantés par des sous classes

Object get(String name){

}

Object o=find(name);

if (o) return o;

if (!canCreate(name)) return null;

o = create(name);

addToContainer(o);

return o;


Exercice

• Définir un exemple de template method

• (une boucle «!for» avec deux appels de

fonctions spécifiques)

Template method requiert de définir une classe

pour chaque mise en œuvre. Peut on adapter l’

exemple précédent de sorte qu’il utilise function

object à la place?


Autres Schémas de

Création

Présentation quasi alphabétique


Schémas de Création

• Abstract Factory :

• interface de création de familles d'objets de type exact inconnu

• Builder :

• séparer création et représentation

• Factory Method :

• interface de création spécifiée par des sous classes

• Prototype

• création par clonage

• Singleton

• classe à instance unique


Abstract Factory

• Interface de création de familles de produits


Abstract Factory : exemples

• Permet de changer le look and feel d'une

interface en changeant le type des objets créés en

changeant simplement d'object factory

• Peut aussi servir pour changer globalement les

types de containers utilisés par un programme

(listes ou tableaux ou hashtables) par exemple


Exercices

• Définir une api permettant de changer de type

de collection (basé sur les listes simples ou les

tableaux ou les tableaux associatifs) simplement

en changeant de container factory.

• La collection doit seulement implanter l’accès

aléatoire (valeur à une position «!i!»)


Builder

• Séparer la construction d'un objet complexe de

sa représentation


Builder : exemples

• L'exemple type est celui d'un convertisseur "à la

volée" de texte formaté.

• vers un autre format

• vers des formats avec perte (html -> texte seul)

• Le principe est qu'à chaque rencontre d'une unité

remarquable (balise, chaîne de caractères, texte

libre...) le parseur invoque le convertisseur. En

changeant ce dernier, on change le format de sortie.


Analyse

• Selon le schéma «!Builder!», le «!director!» garde

la maîtrise des appels au «!builder!».

• La situation serait différente si la structure de

données était parcourue automatiquement


Prototype

• Créer des instances par clonage de prototypes


Prototype : exemples

• C'est la base de la mise en œuvre du copier/

coller dans les interfaces graphiques

• La copie de prototype est au cœur de la

simulation des classes en Javascript


Autres Schémas

Structuraux

Présentation alphabétique


Schémas Structuraux

• Adapter

– convertir une interface en une autre pour réutilisation

• Bridge

• découpler une abstraction de son implantation

• Composite

– structures arborescentes

• Decorator

• attachement dynamique de fonctionnalités

• Façade

• interface unique sur les interfaces d'un module

• Flyweight

• objets ultra légers

• Proxy


Bridge

• Découpler une abstraction de son implantation


Bridge : exemples

• On se trouve dans le cas où l'on doit maintenir en

même temps une hiérarchie d'abstractions et

plusieurs hiérarchies d'implantation différentes : par

exemple pour réaliser des interfaces graphiques

portables

• On peut aussi vouloir cacher des interfaces de

programmation (C++) : cas particulier type de la

classe "Handle"


Decorator

• Attacher des fonctionnalités dynamiquement


Decorator : exemples

• On veut attacher dynamiquement des traitements

effectués de manière récursive

• Exemple : dans les interfaces graphiques, l'affichage

des "décorations" : barre de saisie, ascenseurs,

transparence etc...

• Autre possibilité : pour la sérialisation : ajout de

balises html/xml autour du source généré par

exemple.


Façade

• Interfacer un sous système par une classe façade


Facade : exemples

• Votre compilateur C++ en ligne de commande

favori : permet l'invocation d'une session

complète, ou du préprocesseur seul, ou du

linker...


Flyweight

• Gérer des millions de pseudo objets associés à

des données de base


Flyweight exemples

• Dans un éditeur de textes, faire de chaque

caractère un objet.

• Dans un afficheur de signaux radars, faire de

chaque signal un objet.


Proxy

• Définir un représentant local d'un objet

accessible à distance


• interface des EJB

Proxy : exemples


Autres schémas

dynamiques

Présentation alphabétique


Schémas Dynamiques

• Chain of Responsibility

• découpler l'objet responsable d'un traitement

• Command

– objet fonction

• Interpreter

• représentation de la sémantique d'une grammaire

• Iterator

– accès séquentiel au contenu d'un container

• Mediator

• modélisation de l'interaction d'objets

• Memento

• support du undo


Schémas Dynamiques

• Observer

• gestion des notifications

• State

• définir les états par des classes

• Strategy

• définir des familles d'algorithmes interchangeables

Template Method

– définir le squelette d'un algorithme

• Visitor

• permettre d'appliquer une opération aux éléments d'une structure de

données


Chain of Responsibility

• Eviter de coupler le demandeur d'une requête et

son récepteur


exemples

• le système de prise en compte des événements

dans le logiciel hypercard

• toute ihm ou l'on voudrait que par défaut un

click s'il n'est pas traité par un bouton soit traité

par un script d'un conteneur englobant, à un

niveau quelconque


Interpreter

• Explorer un arbre syntaxique


Interpreter : exemples

• Utile pour la version "luxe" de "Builder". On a

fait une analyse syntaxique, et on veut exploiter

la structure de données hiérarchique qui a été

construite pour:

• compiler

• traduire

• ...


Mediator

• Alléger le coût d'une communication nxn par un

médiateur


Mediator


Mediator : exemples

• Dans une interface graphique, gérer des

dépendances complexes entre des composants

de saisie/visualisation


Memento

• Prévoir la restauration de l'état d'un objet (Undo)


Observer

• Définir une relation entre objets pour que chaque

mise à jour soit notifiée


Observer : exemples

• Toujours dans une interface graphique par

exemple, permettre la notification entre des vues

multiples éditables ou non d'une même donnée.

• Par exemple feuille de calcul/diagrammes


State

• Gérer les états par une hiérarchie de classes


State : exemples

• La fonction "display" d'une icône représentant

une connexion change selon l'état.

• Pour le code qui invoque display, il suffit de

changer dynamiquement l'objet qui implémente

l'état pour que cette particularité soit insensible


Strategy

• Varier dynamiquement les algorithmes


Strategy : exemples

• Les tris ont des plages d'optimalité.

• On peut changer une fois pour toutes l'algo de

tri attaché à un (itérateur de) vecteur par

exemple, dès que le nombre de constituants

dépasse 5

• On remplace ainsi un test par un pointeur de

fonction


Visitor

• Explorer une structure de données hiérarchique


Visitor : exemples

• permettre l'appel d'une fonction sur des

éléments d'une structure de données sans avoir à

réécrire l'algo de parcours à chaque fois.

• la fonction "map" de LISP


Autres Patterns Utiles


Inversion de dépendance

• L'inversion de dépendance permet de rendre un

code indépendant de ses conditions

d'initialisation , et des API précises des ses

données d'initialisation

• Utile dans les architectures multi couches

• Exemple:

• le framework Spring:

• http://www.theserverside.com/tt/articles/

article.tss?l=SpringFramework

• le projet Pico (http://www.picocontainer.org/)

• le projet Avalon


Inversion de Dépendance

par les setters


Inversion de Dépendance

par les constructeurs


GRASP

General Responsibility Assignment Software

Patterns or Principles


GRASP

• GRASP propose des guides généraux

d'organisation des interfaces de programmation

orientée par le concept de "responsabilité"

attachée aux classes.

• Les "patterns" GRASP fournissent une canevas

logique pour déployer des interfaces

garantissant un niveau amélioré de réutilisabilité


Information Expert

• Ce modèle représente le plus fondamental des

allocations de responsabilité:

• La responsabilité doit être attachée à la classe la

plus compétente (Information Expert)


Creator

• La classe responsable de créer de nouvelles

instances d'une classe C est celle qui:

• agrège, contient, enregistre les instances de C

• utilise les instances de C

• possède l'information nécessaire pour créer les

C


Controller

• La responsabilité de traiter les événements système

est déléguée à une classe non membre de l'interface

utilisateur qui représente le système entier ou un

scénario de cas d'utilisation

• Un contrôleur de use case doit être capable de gérer la

totalité des événements possibles d'un cas

d'utilisation.

• Un contrôleur peut gérer les événements de plusieurs

scénarios si nécessaire


Low Coupling

• Le "couplage faible" renvoie aux aspects de

l'organisation logicielle qui permettent:

• de limiter les dépendances entre classes

• de réduire l'impact du changement sur les autres classes

• d'augmenter la réutilisabilité

• Les stratégies qui le permettent sont variées, mais

reposent largement sur l'inversion de contrôle et les

design patterns de séparation (bridge, builder,

decorator, mediator etc...)


High Cohesion

• La "cohésion forte" est une stratégie

d'organisation des classes qui vise à associer au

sein d'une même classe des services fortement

voisins ou reliés


Polymorphisme

• Quand des variations de fonctionnalités sont

induites par le type des objets, la responsabilité

de ces variations est données à des sous classes

qui implantent le type, à une opération

surchargée dans chaque cas par la méthode

appropriée


Pure Fabrication

• Une "Pure Fabrication" est une classe ne faisant

pas partie des objets métier ou technique, mais

introduite pour les seuls besoins de satisfaire

"low coupling et/ou high cohesion" ou tout

autre besoin dicté par les GRASP


Indirection

• Utiliser un intermédiaire (pattern Mediator par

exemple) pour satisfaire les impératifs de

couplage faible


Protected Variations

• Protéger un ensemble logiciel des variations

d'un élément en groupant ses parties instables

dans une interface, dont les implantations

réalisent les variations


Trois principes liés aux design et

grasp patterns


Single-Responsibility

Principle

• Une classe doit n'avoir qu'une seule raison de

changer.

• Ce principe est une lecture du principe de "cohésion

forte". La classe ne doit offrir que des services

fortement reliés

• on ne combine pas rémanence et fonctionnalité par

exemple

• Ce principe contredit de facto l'usage de l'héritage

pour extension


Interface-Segregation

Principle

• Un programme ne doit pas dépendre de

méthodes qu'il n'utilise pas

• Principe également lié à la cohésion forte

• Conduit à la multiplication d'interfaces très

spécifiques et petites.


Open-Closed Principle

• Un code doit être "ouvert à l'extension, mais fermé à

la modification".

• En d'autres termes, tout ajout de fonctionnalité ou

évolution du logiciel doit se faire de façon

incrémentale, sans modifier une ligne de source

existante

• Une approche de ce principe se fait par les design

patterns "template method" et "strategy"!


Design Patterns J2EE


Les Patterns J2EE

• Java a popularisé une liste de Patterns utilisés

dans la mise en œuvre d'applications à base

d'EJB

Chaque Pattern n'est pas une collaboration au

sens propre, mais le nom d'une classe, dotée de

fonctionnalités particulières, et qui entre dans

des interactions spécifiques avec d'autres


http://java.sun.com/blueprints/

corej2eepatterns/Patterns/


http://java.sun.com/blueprints/

corej2eepatterns/Patterns/


http://java.sun.com/blueprints/

patterns/catalog.html

• Business Delegate Reduce coupling between Web and Enterprise JavaBeansTM tiers

• Composite Entity Model a network of related business entities

• Composite View Separately manage layout and content of multiple composed views

• Data Access Object (DAO) Abstract and encapsulate data access mechanisms

• Fast Lane Reader Improve read performance of tabular data

• Front Controller Centralize application request processing

• Intercepting Filter Pre- and post-process application requests

• Model-View-Controller Decouple data, behavior, and presentation

• Service Locator Simplify client access to enterprise business services

• Session Facade Coordinate operations between multiple business objects in a workflow

• Transfer Object Transfer business data between tiers

• Value List Handler Efficiently iterate a virtual list

• View Helper Simplify access to model state and data access logic


Références

• Mastering EJB 3.0

• http://www.theserverside.com/tt/books/

wiley/masteringEJB3/index.tss

• EJB Design Patterns

• http://www.theserverside.com/tt/books/

wiley/EJBDesignPatterns/index.tss

• L'ensemble du site est utile:

• http://www.theserverside.com/


Conclusion

Les patterns fournissent un outil puissant

• de documentation de savoir-faire

• de nommage de concepts universellement

utilisés

• de réutilisation pratique de modèles objet dans

les projets


Autres Pseudo Patterns référencés


• Prédéfinir les casts

Casting Method


Connected Group

• Gérer collectivement les connexions


Double Checked Locking

class Singleton {

public:

static Singleton * instance();

private:

static Singleton * self;

static SEMAPHORE key;

}

Singleton *Singleton::instance() {

if (self == 0) {

if ( lock(key) >= 0 ) {

if (self == 0 ); //double-check!

self = new Singleton;

unlock (key);

} } }


Flexible Service

• Faire d'une fonction une classe, évaluée de

manière retardée


Intelligent Children

• Eviter les down casts


Is Kind Of

• Fournir des informations de type


Multiton

class User {

public:

static const User * LogIn(const char * name, const char *

password);

protected:

virtual User * Lookup(const char *name);

private:

}

List * _instances;

class UserName : public ListItem {

}

User* instance;

char* name;


Mutual Friends

• Représenter une relation bidirectionnelle


Named Object


Null Object

• Représenter une relation partielle


Objectifier

• Permettre à un objet de faire varier

dynamiquement son comportement


RTTIVisitor

• Obtenir un cast sûr au moyen du pattern visitor


Sender Argument

• Permettre de s'identifier auprès d'autres objets

par passage d'une référence


Serializer

• Ecrire les objets dans des flux de données pour

les reconstruire plus tard


Timed Relationship

• Représenter une relation qui varie au cours du

temps


The End ...

More magazines by this user
Similar magazines