Les patrons de conception: Représentation et mise - Latece

Transcription

Les patrons de conception: Représentation et mise - Latece
Les patrons de conception: Représentation et mise en oeuvre
Ghizlane El Boussaidi
Hafedh Mili
[email protected]
[email protected]
LAboratoire de recherche sur les TEchnologies du Commerce Electronique
Université du Québec à Montréal
Abstract
Design patterns are models of solutions to specific design problems in precise contexts.
Since their apparition, they have raised a lot of interest. Some studies have concentrated on
the classification, comparison and implementation of patterns, others have tried to specify
formally patterns and/or their application. In this report we review several works that have
studied the representation of patterns and the automation of their application while
integrating them in development tools or environments.
Résumé
Les patrons de conception sont des modèles de solution à des problèmes spécifiques de
conception dans des contextes précis. Depuis leur apparition, ils ont suscité beaucoup
d’intérêt. Certaines études se sont concentrées sur la classification, la comparaison et la
mise en œuvre des patrons, d’autres ont essayé de spécifier formellement les patrons et/ou
leur application. Dans ce rapport nous passons en revue plusieurs travaux qui se sont
intéressés à la représentation des patrons et à l’automatisation de leur application en les
intégrant dans des outils ou environnements de développement.
1. Introduction
Les patrons sont des solutions éprouvées à des problèmes spécifiques et récurrents. « Un patron
décrit un problème devant être résolu, une solution, et le contexte dans lequel cette solution est
considérée. Il nomme une technique et décrit ses coûts et ses avantages. Il permet à une équipe
d’utiliser un vocabulaire commun pour décrire leurs modèles » [Johnson 1997]. Ils capturent les
bonnes pratiques de conception et cela à différents niveaux d’abstraction en allant des patrons
architecturaux jusqu’au patrons d’implémentation. Par leur aspect générique, ils sont considérés
comme des micro-architectures qui visent à réduire la complexité, à promouvoir la réutilisation et
à fournir un vocabulaire commun aux concepteurs.
Les patrons orientés objet ont été introduits par K. Beck et W. Cunningham, ils représentent les
connaissances d’experts en orienté objet dans une forme pouvant être distribuée aux moins
experts. Ces patrons peuvent être appliqués à différents niveaux du processus de développement
logiciel. On distingue les patrons au niveau analyse, conception et implémentation. Il existe aussi
des patrons qui sont particuliers à un domaine. Notre objectif étant la génération d’un modèle de
conception à partir d’un modèle d’analyse, nous nous intéressons, dans notre étude, aux patrons
de conception.
Les patrons de conception ont été, généralement représentés sous forme de diagrammes avec des
notations objet comme OMT[Rumbaugh et al. 1996] ou UML[OMG]. Ces diagrammes décrivent
un ensemble de composants et leurs interactions. L’utilisation ou l’application d’un patron peut
être difficile ou inexacte. En effet, les diagrammes utilisés ne représentent pas les patrons d’une
façon formelle et ils n’indiquent pas comment appliquer un patron, ni quelles sont les
modifications que l’on peut apporter à une instance du patron.
LATECE Technical Report 2004
1
Dans ce rapport, nous faisons un état de l’art des travaux qui se sont intéressés à la représentation
des patrons et à l’automatisation de leur application. Le document est organisé de la manière
suivante. Nous commençons, d’abord, par présenter le formalisme dans lequel les patrons de
conception ont été exprimés. Nous énumérons quelques problèmes reliés à l’utilisation des
patrons ainsi décrits. Ensuite, nous présentons quelques-uns des travaux qui se sont intéressés à
cette problématique. Finalement, nous faisons une synthèse des travaux passés en revue.
2. La représentation des patrons et ses limites
Plusieurs travaux se sont intéressés à l’étude et la documentation des patrons [Coad 1992],
[Gamma et al. 1995], [Buschman et al. 1996], [Fowler 1997], [Johnson 1997]. Ces travaux ont
proposé différents formalismes pour la représentation des patrons. Cependant, en ce qui concerne
les patrons de conception, le travail de Gamma et al. a énormément contribué à leur émergence et
à leur acceptation. Nous nous limiterons, donc, à la description du formalisme utilisé par Gamma
et al. et nous donnerons un exemple de patron extrait de leur catalogue.
2.1 Description des patrons par Gamma et al.
Gamma et al. [Gamma et al. 1995] ont classé les patrons qu’ils proposent selon leur rôle et leur
domaine d’application (classe vs objet). Ils ont distingué entre patrons créateurs, structurels et
comportementaux. Les patrons créateurs concernent la création de classes ou d’objets. Les
patrons structurels s’intéressent à la composition d’objets ou classes pour réaliser de nouvelles
fonctionnalités. Finalement, les patrons comportementaux concernent les interactions entre
classes et l’affection des responsabilités.
Gamma et al. ont adopté une représentation uniforme et structurée. Chaque patron est décrit et
documenté de la même façon. Les propriétés utilisées sont :
Nom : le nom significatif du patron.
Intention : décrit ce que fait le patron, son but, quel problème particulier il résout.
Alias : énumère, s’il en existe, d’autres noms communs du patron.
Motivation : donne un exemple de problème de conception pouvant être résolu par application
du patron. L’illustration par un exemple facilite la compréhension de la description abstraite
(donnée par la suite) du patron.
Indications d’utilisation : décrit les situations où on peut utiliser le patron.
Structure : décrit la structure du patron en utilisant des diagrammes de classes. Des
diagrammes de collaboration sont aussi utilisés pour la description de l’interaction entre les
classes du patron.
Participants : définit les classes (ou objets) intervenantes dans le patron et leurs
responsabilités.
Collaborations : décrit comment les participants interagissent pour assumer leurs
responsabilités.
Conséquences : décrit comment le patron atteint ses objectifs, quels sont les compromis et les
résultats de son utilisation.
Implémentation : présente des astuces, techniques et pièges qu’il faut connaître lors de
l’implémentation du patron. Cette partie propose aussi, quand il en existe, des solutions
typiques du langage utilisé.
Exemple de code : donne des fragments de code pour illustrer la façon dont on peut
implémenter le patron en C++ ou Smalltalk.
LATECE Technical Report 2004
2
Utilisations connues : contient des exemples d’utilisation du patron dans des systèmes réels.
Patrons apparentés : cite les patrons qui sont reliés avec celui en cours de traitement et leurs
différences.
Exemple : Nous donnons ici comme exemple le patron Fabrique Abstraite qui appartient à la
classe des patrons créateurs. Nous n’aborderons pas toutes les rubriques mais celles qui sont
essentielles à la compréhension de ce patron.
Nom : Fabrique abstraite (Abstract Factory)
Intention : Ce patron fournit une interface pour créer des familles d’objets reliés ou dépendants
sans spécifier leurs classes concrètes.
Motivation :
Considérons une boite à outils d’interfaces utilisateur supportant plusieurs standards « look-andfeel » tels que Motif et Presentation Manager (PM). Ces derniers définissent différentes
apparences et comportements des « widgets » de l’interface utilisateur. Ces widgets peuvent être
des fenêtres « windows », « scroll bars », etc.. Pour que l’application soit portable à travers les
standards look-and-feel, il ne faut pas que les widgets soient codés « en dur » pour un standard
particulier. En effet, l’instanciation des widgets spécifiés dans un standard donné rendra difficile
le changement ultérieur du standard.
Ce problème peut être résolu par la définition d’une classe abstraite WidgetFactory définissant
une interface pour la création de chaque type de widget. Il faut aussi créer une classe abstraite
pour chaque type de widget et des sous-classes concrètes qui implémentent les widgets pour des
standards spécifiques look-and-feel. L’interface de WidgetFactory fournit, pour chaque classe
abstraite widget, une opération qui retourne un nouvel objet widget. Les clients utiliseront ces
opérations afin d’obtenir des instances de widgets, mais sans qu’ils sachent quelles classes
concrètes ils utilisent. Ce qui permet l’indépendance des clients du standard look-and-feel en
vigueur.
WidgetFactoty
Client
CreateScrollBar()
CreateWindow()
Window
PMWindow
MotifWidgetFactory
PMWidgetFactory
CreateScrollBar()
CreateWindow()
CreateSc rollBar()
CreateWindow()
MotifWindow
ScrollBar
PMScrollBar
MotifScrollBar
fig.1 Application du patron Abstract Factory
LATECE Technical Report 2004
3
Il y a une sous-classe concrète de WidgetFactory pour chaque standard look-and-feel. Chacune de
ces classes, selon le standard qu’elle représente, implémente les opérations de création des
widgets. Par exemple, l’opération CreateScrollBar de la classe MotifWidgetFactory crée et
retourne une instance de la classe MotifScrollBar, alors que l’opération correspondante de la
classe PMWidgetFactory retourne une instance de la classe PMScrollBar. Les clients créent des
widgets seulement à travers l’interface WidgetFactory et n’ont aucune connaissance des classes
qui implémentent les widgets dans différents standards. Finalement, une WidgetFactory permet
aussi de renforcer les dépendances entre classes concrètes de widgets du même standard lookand-feel.
Indications d’utilisation :
Le patron Abstract Factory peut être utilisé lorsque :
Un système doit être indépendant de la manière dont ses produits sont créés, composés et
représentés.
Un système doit être configuré avec un famille de produits parmi plusieurs.
On veut renforcer l’interdépendance d’une famille d’objets produits conçus pour être utilisés
ensemble.
On veut fournir une librairie de classes de produits en ne révélant que leurs interfaces et non
leurs implémentations.
Structure :
AbstractFactoty
Client
CreateProductA()
CreateProductB()
AbstractProductA
ProductA2
ConcreteFactory1
ConcreteFactory2
CreateProductA()
CreateProductB()
CreateProductA()
CreateProductB()
ProductA1
Abst ractProductB
ProductB2
ProductB1
fig.2 Structure du patron Abstract Factory
Participants :
AbstractFactory (WidgetFactory) : définit une interface pour les opérations qui créent les
objets produits abstraits.
ConcreteFactory (MotifWidgetFactory, PMWidgetFactory) : implante les opérations pour
créer les objets produits concrets.
AbstractProduct (Window, ScrollBar) : définit une interface pour un type d’objet produit.
LATECE Technical Report 2004
4
ConcreteProduct (MotifWindow, MotifScrollBar) :
o définit un objet produit à créer par la classe de fabrication concerte
correspondante.
o implante l’interface de AbstractProduct.
Client : utilise les interfaces déclarées par AbstractFactory et AbstractProduct.
Collaborations :
Une instance unique de la classe ConcreteFactory est créée à l’exécution. Cette fabrique
concrète crée des objets produits ayant une implémentation particulière. Pour créer des
objets produits différents, les clients doivent utiliser une fabrique concrète différente.
Une AbstractFactory délègue la création d’objets produits à ses sous-classes.
Conséquences :
Isoler les classes concrètes : la fabrique encapsule le processus de création des objets
produits. Elle permet, donc d’isoler les clients des classes d’implémentation.
Faciliter la substitution de familles de produits : la fabrique concrète est instanciée une
seule fois dans une application. Il est, alors, facile de changer la classe de fabrication
concrète et donc toute la famille de produits en un seul coup.
Renforcer le maintien de la cohérence entre produits : la fabrique abstraite consolide
l’interdépendance d’une famille d’objets produits conçus pour être utilisés ensemble.
L’ajout de nouveaux types de produits est difficile : l’ajout de nouveaux produits
nécessite la modification de l’interface de la fabrique abstraite et de toutes ses sousclasses.
Pour les autres rubriques que nous n’avons pas citées, nous invitons le lecteur à consulter le livre
de [Gamma et al. 1995].
2.2 Les problèmes d’utilisation et d’application des patrons
Les patrons de conception ne sont pas tous au même niveau de complexité. En effet,
l’application, de certains d’entre eux, n’est pas un processus évident. Il faut cerner le problème
pour pouvoir identifier la solution adéquate et donc le patron adéquat. Une fois que le patron à
utiliser est identifié, il faut l’appliquer au modèle concerné. Pour cela, le concepteur doit pouvoir
définir le rôle de chaque élément du modèle pour établir une correspondance avec les éléments du
patron.
Une fois le patron appliqué, il faudra vérifier si la sémantique du modèle est toujours respectée,
comme il faudra s’assurer que de futures modifications ne violent pas les contraintes sémantiques
et structurelles imposées par le patron.
L’implémentation des patrons dans un langage de programmation nécessite une mise en
correspondance entre les éléments de conception du patron et les constructions du langage de
programmation. Cela n’est pas toujours aussi évident, dans le cas du langage Java, par exemple,
on ne peut pas implémenter l’héritage multiple.
LATECE Technical Report 2004
5
3. Cadre de comparaison des approches de mise en œuvre des patrons
Plusieurs travaux se sont intéressés à la description formelle des patrons, à leur classification, à
leur application et à leur intégration dans des environnements de développement. Des approches
ont proposé des outils ou modifié des outils existants pour permettre la représentation et/ou la
mise en œuvre automatique des patrons de conception. Cependant, les représentations adoptées
pour les patrons sont diverses et dépendantes des objectifs de chaque approche et des niveaux
d'abstraction concernés.
3.1 Cadre de comparaison
Pour pouvoir comprendre, classifier et évaluer les approches, nous proposons un cadre de
comparaison. La formulation de ce cadre a été guidée par les objectifs de notre travail. Notre
cadre de comparaison est décrit comme suit :
Représentation de l’aspect structurel du patron : Un patron a une structure composée
d’un ensemble d’éléments qui coopèrent pour résoudre un problème de conception. Il est
très important de représenter explicitement ces éléments et les relations entre eux.
Représentation de l’aspect collaboration dans un patron : Les entités composant un
patron interagissent entre elles. Cette collaboration doit être représentée.
Représentation de la transformation : L’application du patron à un fragment d’un
modèle implique, en fait, la transformation de ce fragment de modèle. Cette
transformation consiste à reproduire la structure générique du patron en l’appliquant à un
ensemble d’éléments. Cette transformation doit être spécifiée d’une façon explicite et
paramétrable.
Mise en œuvre de la transformation : La représentation de la transformation est
dépendante de la façon dont les patrons sont spécifiés. Le processus de mise en œuvre de
cette transformation doit être bien défini.
Support des règles et contraintes : Plusieurs propriétés sémantiques et contraintes sont
reliées aux patrons. Il est important de pouvoir les exprimer et les associer au patron et
aussi de les appliquer lors du processus d’instanciation.
3.2 Classification des approches
Durant notre étude et évaluation des travaux décrits dans les sections suivantes, nous avons
identifié plusieurs différences entre les approches proposées. Certaines approches représentent les
patrons d’une façon explicite et visuelle. Cela permet une manipulation plus aisée par le
concepteur (modification de patron, ajout, etc.). D’autres approches intègrent la représentation
d’un patron dans le processus de transformation appliqué à un modèle lorsque le patron est
utilisé. La représentation d’un patron est, dans ce cas là, implicite et indissociable de la
transformation exécutée lors de son application.
Dans la famille des travaux qui proposent une représentation explicite du patron, certains
proposent un méta-modèle pour représenter les patrons, alors que d’autres proposent un ensemble
de modèles ou un reposoir de patrons. Pour ce qui est de l’application du patron, les approches
adoptées diffèrent selon l’objectif de l’étude et la représentation choisie pour les patrons.
L’objectif de l’étude [Borne et Revault 1999] peut être de fournir un support d’aide à la
conception basée sur les patrons, un support pour générer du code à partir de modèles conformes
à des patrons, un outil de validation des modèles conformes à des patrons, ou un support de
rétro-conception pour appliquer des patrons à des modèles existants.
LATECE Technical Report 2004
6
L’application des patrons peut se faire selon différentes approches. Flofijin et al. [Florijin et al.
1997] en distinguent trois :
Approche descendante : l’utilisateur choisit un patron, l’outil utilisé génère un ensemble
d’éléments de conception (classes, méthodes, associations, etc.) composant le patron.
Approche ascendante : contrairement à l’approche précédente où de nouveaux éléments
sont créés, dans cette approche, un ensemble d’éléments, reflétant la structure d’un patron
particulier, est associé à une instance de ce patron.
Approche mixte : dans ce cas, on complète un ensemble d’éléments reflétant partiellement
la structure d’un patron avec d’autres éléments et associations de façon à ce que le nouvel
ensemble reflète toute la structure du patron.
Nous avons regroupé les travaux que nous avons étudiés en trois catégories de famille :
(1) La première famille d’approches représente le patron d’une façon implicite et ne le
dissocie pas de son application.
(2) La deuxième famille donne une représentation explicite d’un patron, mais ne sépare pas le
mécanisme de son application de cette représentation. Ce sont souvent des approches qui
raisonnent dans un niveau unique de modélisation (abstraction).
(3) La dernière famille donne une représentation explicite d’un patron et le mécanisme
d’application du patron est indépendant du patron lui-même.
4. Revue des approches avec représentation implicite des patrons
4.1 Approche formelle transformationnelle
Alencar et al. [Alencar et al. 1997] décrivent le processus de conception comme étant la
transformation de modèles de conception orientée objet. Ils modélisent un patron de conception
comme une transformation appliquée à un modèle et cela en utilisant un langage de processus.
Les processus de transformation sont appliqués aux spécifications exprimées sous forme de
schémas. Des outils peuvent traduire les descriptions faites dans le langage de processus aux
langages de programmation orientés objet.
La structure du langage de processus a cinq éléments (fig.3). (1) Le nom qui introduit le
problème et le contexte du patron, et qui est suivi des paramètres (les parties participantes dans le
patron). (2) Une partie « Stable » qui spécifie les parties (classes ou ensemble de classes) qui ne
changent pas. (3) Une partie « Structure » qui décrit toutes les parties du patron, leurs relations et
collaborations. (4) Une partie « Instable » qui spécifie les parties (classes ou ensemble de classes)
qui changent pour s’adapter aux nouvelles exigences. Finalement, (5) une partie « Extension »
qui décrit l’évolution de l’application du patron.
LATECE Technical Report 2004
7
fig.3 Exemple du patron pont (Bridge), figure extraite de [Alencar et al. 1997]
Les auteurs de cette approche se sont concentrés sur l’aspect syntaxique des transformations,
l’aspect sémantique n’a pas été approfondi. Par ailleurs, les patrons sont pris en charge d’une
façon implicite et leur représentation n’est pas dissociée de leur application.
4.2 Génération automatique de code à partir des patrons
Budinsky et al. [Budinsky et al. 1996] présentent un outil qui permet de générer automatiquement
le code d’un patron à partir de quelques informations fournies par l’utilisateur. Les patrons sont
présentés comme un système hypertexte formé de pages reliées. En fait, en se basant sur le
formalisme de [Gamma et al. 1995], chaque section (intention, motivation, etc.) est affichée dans
une page séparée. En plus de ces pages, une page de génération de code est associé à chaque
patron. Elle permet à l’utilisateur d’entrer les informations qui permettront une implémentation
personnalisée du patron. L’utilisateur peut aussi contrôler les paramètres globaux qui
s’appliquent à tous les patrons.
L’architecture de l’outil (fig.4) est composée de trois parties. Il y a le présentateur (PRESENTER)
qui implémente l’interface utilisateur, c’est une sorte de navigateur qui affiche et interprète les
pages de description des patrons écrites en HTML (HyperText Markup Language). Ensuite, il y a
le Mapper qui spécifie comment l’interface utilisateur et le générateur de code coopèrent. Le
Mapper est un interpréteur Perl et les descriptions du mapping sont donc des scripts Perl. Quand
LATECE Technical Report 2004
8
un utilisateur entre des informations dans la page de génération de code, le Présentateur transmet
ces informations au Mapper à travers des scripts CGI (Common Gateway Interface). La dernière
partie appelée générateur de code interprète la page de génération de code pour implémenter un
patron. L’interpréteur est appelé COGENT (COde GENeration Template), il est invoqué par les
scripts Perl.
fig.4 Architecture de l’outil, figure extraite de [Budinsky et al. 1996]
L’avantage de cette architecture est qu’elle permet le découplage de l’interface utilisateur de la
génération de code. Ce qui permet de les modifier indépendamment l’un de l’autre. Cela facilite
aussi la distribution des composants. Toutefois, l’approche ne prend pas en charge la
représentation explicite des patrons. Certes, elle permet de les représenter d’une façon textuelle
sous forme de page HTML en vue de les présenter à l’utilisateur, mais il ne propose pas de
modèle explicite manipulable pour les patrons. Le patron est représentée d’une façon implicite
dans son application. Finalement, l’intégration du code généré au code existant pose certains
problèmes.
4.3 Framework de transformation « UMLAUT »
Sunyé et al. [Sunyé et al. 2000] ont fixé pour but d’intégrer les patrons de conception dans un
outil UML. Cet outil doit, d’une part, fournir des transformations de haut niveau permettant à un
concepteur d’appliquer un patron et, d’autre part, s’assurer que les solutions appliquées restent
consistantes durant le processus de conception.
Sunyé et al. proposent un framework UMLAUT [UMLAUT], Unified Modeling Language All
pUrposes Transformer, permettant l’application des transformations sur des modèles UML. Ils
utilisent une combinaison du paradigme orienté objet et du paradigme fonctionnel. Le processus
de transformation est décomposé en trois phases : traverser le modèle pour sélectionner d’une
façon séquentielle les éléments, associer des opérateurs fonctionnels à chacun des éléments, puis
valider l’intégrité du modèle obtenu.
UMLAUT implémente le méta-modèle UML avec le langage Eiffel. Une transformation est
spécifiée d’une façon formelle dans un langage proche d’OCL. L’utilisation d’OCL permet
l’intégration des pré- et post-conditions aux transformations. L’application d’un patron se fait en
des étapes de transformations successives. La figure (fig.5), par exemple, représente une
hiérarchie de classes avec plusieurs méthodes définies par chaque classe. Dans une situation
LATECE Technical Report 2004
9
pareille, on peut appliquer le patron Visitor. Le modèle final après application du patron Visitor
est présenté à la figure 6.
fig.5 Modèle initial, figure extraite de [Sunyé et al. 2000]
Fig.6 Modèle final après application du patron Visitor, figure extraite de [Sunyé et al. 2000]
Class::addVisitor()
actions :
let abstractVisitor :=
self . package . addClass ( self.name+' Visitor ', nil , nil ).
self . allOperations() ->forAll(operation |
let concreteVisitor := self .package . addClass(
operation .name+' Visitor ', abstractVisitor , nil ).
self .allSubTypes() ->forAll(subclass |
subclass . allOperations() -> select(subop |
subop . hasSameSignature( operation) ->forAll( op |
op . move( concreteVisitor ,'acceptFrom'+subclass .name ) .
op. rename ( ' acceptVisitor ').
op. pullUp ( ) ) ) ) ) .
Fig.7 Transformation associée au patron Visitor, figure extraite de [Sunyé et al. 2000]
La transformation de la figure 7 spécifie l’application du patron Visitor. Dans l’exemple
précédent, elle s’appliquera à la classe ParseNode. Cette transformation doit être complétée par la
spécification de la collaboration entre les entités participantes dans l’instance du patron concerné.
LATECE Technical Report 2004
10
L’approche de Sunyé et al. ne supporte pas la représentation explicite d’un patron. Comme dans
[Alencar et al. 1997], un patron est représenté d’une façon implicite dans les transformations
appliquées à un modèle lors de son utilisation. En plus, l’approche ne traite pas l’aspect
sémantique du patron.
5. Revue des approches avec représentation explicite des patrons
5.1 Extension d’UML pour représenter et instancier les patrons
Partant du fait que l’étape d’instanciation du patron est essentielle pour son application, Fontoura
et Lucena [Fontoura et Lucena 2001] proposent une représentation explicite de l’instanciation des
patrons en utilisant les mécanismes d’extension d’UML (stéréotype, tag et contrainte). Pour cela,
ils proposent de modifier les diagrammes de classes de façon à ce qu’ils puissent représenter
explicitement les points de variation et les classes d’application, et de définir des diagrammes
d’activité exposant les étapes à exécuter durant l’instanciation d’un patron.
fig.8 Représentation explicite des points de variation dans le patron Strategy
figure extraite de [Fontoura et Lucena 2001]
Plusieurs patrons ont été utilisés pour montrer comment on peut améliorer leurs représentations
en ajoutant de nouveaux éléments à la notation UML. Un de ces patrons est le patron Strategy. La
figure (fig.8) montre une version étendue du digramme de classe UML où les points de variation
(hot-spots) sont représentés. Dans ce cas, la méthode algorithm() est un hot-spot comme indiqué
par le tag variable. La classe ConcreteStrategy est en sur-brillance pour indiquer que c’est une
classe d’application (Application class) ce qui signifie qu’elle existe seulement après
l’instanciation du patron. La contrainte incomplete indique que plusieurs sous-classes de Strategy
peuvent être créées.
LATECE Technical Report 2004
11
Ce diagramme de classes est complétée par un diagramme d’instanciation (fig.9). Ce dernier
définit les étapes à exécuter durant l’application d’un patron dans un langage visuel de processus
ici les diagrammes d’activité d’UML.
fig.9 Diagramme d’instanciation pour le patron Strategy
figure extraite de [Fontoura et Lucena 2001]
Chaque action, dans le diagramme de transformation, est une transformation exprimée dans un
langage transformationnel qui ressemble à PROLOG et qui a une sémantique assez intuitive. La
transformation Subclass(Superclass, NewClass), par exemple, crée une nouvelle classe NewClass
et l’ajoute au système comme étant une sous-classe de Superclass. L’utilisateur doit spécifier le
nom de NewClass.
Fontoura et Lucena montrent que cette approche est valable aussi bien pour les simples patrons
que pour les frameworks. La notation, qu’ils proposent, permet de mieux documenter et
représenter en UML les patrons et leur instanciation. Cependant, l’approche ne donne pas une
démarche pour une mise en correspondance (mapping) du modèle proposé pour représenter un
patron et un modèle déjà existant.
5.2 Un « UML Profile » pour les patrons
Sanada et Adams [Sanada et Adams 2002] présentent une approche basée sur les mécanismes
standards d’extension d’UML. Ils séparent les diagrammes de classes en trois catégories : les
diagrammes classiques de classes, les diagrammes détaillés de classes qui sont des diagrammes
qui ne peuvent plus être raffinés et où l’implémentation des points de variation est résolue, et les
diagrammes de classes décrivant la structure statique des patrons de conception.
L’approche a été illustrée par l’exemple d’un système pour l’enregistrement des notes dans une
école ou université. Dans ce système (fig.10), il existe des classes pour représenter les élèves, les
enseignants, les lectures, les tests, etc. Les enseignants peuvent offrir plusieurs types de tests.
LATECE Technical Report 2004
12
fig.10 Diagramme classique de classes, figure extraite de [Sanada et Adams 2002]
Ce diagramme peut être raffiné. En effet, les fonctions de pondération utilisées par les
enseignants sont souvent différentes et dépendantes des lectures. Pour résoudre ce point de
variation, la responsabilité d’implémentation de la fonction de pondération doit être affectée à la
classe Lecture en utilisant le patron Strategy pour implémenter la méthode compute. Il en résulte
un diagramme détaillé de classes (fig.11) qui ne peut plus être raffiné.
fig.11 Diagramme détaillé de classes, figure extraite de [Sanada et Adams 2002]
Ces diagrammes de classes (classique et détaillé) peuvent être étendus avec des mécanismes
d’extension d’UML comme les stéréotypes, les contraintes et les valeurs marquées
(tagged values).
fig.12 Diagramme classique de classes avec des extensions, figure extraite de [Sanada et Adams 2002]
LATECE Technical Report 2004
13
fig.13 Diagramme détaillé de classes avec des extensions, figure extraite de [Sanada et Adams 2002]
Les extensions utilisées dans ces diagrammes (fig.12 et fig.13) sont :
• variation, binding=dynamic : cette valeur marquée montre que la méthode compute est un
point de variation dans la conception et que son instanciation est dynamique.
• Covariant : cette contrainte montre que les classes Test et Lecture travaillent d’une façon
coopérative, et ajouter une sous-classe à Lecture peut impliquer l’ajout d’une sous-classe
à Test et vice versa.
• Application Class : cette classe ne fait pas partie du framework mais de son instanciation.
• extensible=false : l’interface ne doit pas être étendue. On ne peut plus, lors de
l’instanciation définir de nouveaux attributs ou de nouvelles méthodes.
• Hook : la méthode computeGrade doit être re-écrite si on ajoute une sous-classe.
• Template : la méthode compute est une méthode template qui utilise la méthode hook
computeGrade pour implémenter l’algorithme de calcul du grade.
• Incomplete : le nombre de sous-classes de la classe Lecture n’est pas fixé.
Sanada et Adams ont classifié toutes les extensions par type de diagramme et ils les ont
regroupées dans deux UML profiles. Un profile pour les patrons et un pour les frameworks. Un
outil de modélisation (Argo/UML) a été étendu pour supporter, en partie, la distinction entre les
trois types de diagrammes et permettre de passer d’un type de diagramme à un autre.
Cette approche représente explicitement un patron. Elle permet aussi de marquer les éléments
participant à une structure reflétant un patron et donc la traçabilité de l’instance du patron.
Toutefois, la représentation du patron, lui même, est fournie comme documentation pour un
utilisateur. Elle n’est pas utilisée pour une instanciation automatique du patron.
5.3 Un langage formel pour les patrons : LePUS
Eden et al. [Eden et al. 1999] proposent un langage formel LePUS (LanguagE for Patterns
Uniform Specification) pour exprimer les patrons. C’est un fragment de la logique monadique de
haut niveau. Il utilise un vocabulaire limité d’entités et de relations. Il définit un patron d’une
façon précise et complète sous forme de formule accompagnée d’une représentation graphique.
Une instruction dans LePUS est formée d’une liste de participants (classes, fonctions ou
hiérarchies) et d’une liste de relations entre ces participants. Un programme est représenté par un
modèle. Un modèle M est une paire <P,R> où P est l’univers des entités basiques (classes et
LATECE Technical Report 2004
14
fonctions) et R=R1,…Rn est l’ensemble des relations entre ces entités. Les relations considérées
dans LePUS sont des primitives de tous les langages de programmation orientée objet. Elles sont
déduites par généralisation de toutes les relations basiques existantes entre les entités
participantes dans les patrons de [Gamma et al. 1995].
Ces relations peuvent être de type unaire (porte sur un seul opérande) ou de type binaire. Par
exemple, la relation unaire Abstract(C) est une relation basique et elle est satisfaite par une classe
C si cette dernière est abstraite. La relation d’héritage (possiblement indirect) entre deux classes
« concrete-class » et « abstract-class » est transitive et elle est exprimée par le prédicat :
Inheritance+( concrete-class, abstract-class).
Les entités basiques de P sont appelées entités de dimension 0. on considère un ensemble de
classes (fonctions) comme une classe (fonction) de dimension 1, etc… La dimension d’une entité
est définie d’une façon inductive : les entités basiques ont la dimension 0, un ensemble d’entités
de dimension d et de type uniforme est une entité de dimension d+1. Le domaine des classes
(fonctions) de dimension 1 est noté 2C (2F), de dimension 2 : 22c (22F) etc…
Toutes les relations dans LePUS dérivent des relations basiques. Soit α une relation basique
unaire et β une relation basique binaire. Soient w,v,v1,…,vn des variables basiques et V,W des
variables de dimension 1. Les relations généralisées suivantes sont admises :
def
(unaire)
α(V) = ∀v∈V : α(v)
(total)
(regular)
β→(V,W) = ∀v∈V ∃w∈W : β(v,w)
β↔ (V,W) indique que β est une fonction réversible de V vers W.
def
Les relations de type « total » s’appliquent à des variables de différentes dimensions.
Le patron FACTORY METHOD [Gamma et al.1995], par exemple, exige que chaque fonction de
l’ensemble Factory-Methods crée exactement une classe de l’ensemble des produits Products et
que chaque classe de Products soit créée par une seule fonction. On spécifie cette relation
« Creation » de type regular comme suit :
∃ Factory-Methods∈2F, Products∈2C : < Creation↔ (Factory-Methods, Products) >
En continuant toujours avec l’exemple du patron FACTORY METHOD, on peut spécifier que le
type retourné de chaque Factory-method est égal à une classe product par le prédicat suivant :
Return-Type↔(Factory-methods,Products).
Ni ce dernier prédicat, ni le prédicat définissant la relation de création ne forcent le type retourné
de chaque Factory-method à être égal au type de l’objet créé. Cette propriété est garantie en
exigeant que les relations Return-Type et Creation commutent (chevauchent) dans les ensembles
Factory-methods et Products. Cela est exprimé par le prédicat :
CommuteReturn-Type,Creation (Factory-methods,Products).
Des abstractions auxiliaires ont été introduites pour exprimer quelques abstractions intéressantes
dans la programmation orientée objet. Un ensemble de fonctions avec une signature identique est
LATECE Technical Report 2004
15
appelé « clan » en tenant compte des classes où elles sont définies. Fd est un clan dans Cd ssi Fd
contient des fonctions avec une signature identique, chacune étant définie dans une classe
différente appartenant à Cd. De façon formelle :
Def
Clan(Fd,Cd) = Defined-In↔(Fd,Cd) ∧ [∀F1d-1,F2d-1∈Fd: Same-Signature→(F1d-1,F2d-1)]
d+1
d
d
d+1
d
F est une tribu (tribe) dans C ssi chaque fonction F ∈F est un clan dans C .
Eden et al. ont aussi défini la notion de hiérarchie de classes comme un ensemble de classes
contenant une classe racine (root) abstraite et un ensemble de classes qui constitue le reste de la
hiérarchie (Nodes), chacune doit hériter (possiblement d’une façon indirecte) de root.
une hiérarchie (hierarchy) est un ensemble de classes basiques qui contient une
classe basique hr0 et un ensemble d’éléments restants hN1, tels que :
Inheritance+→( hN1 ,hr0)
Abstract(hr0)
Eden et al. étendent alors le modèle défini précédemment pour prendre en compte les entités
hiérarchiques : M=<P,R,H> où H⊂2C et définit les variables basiques d’hiérarchie.
Similairement aux autres domaines, Hd contient les hiérarchies de dimension d. La hiérarchie
présente dans le patron FACTORY METHOD est transcrite comme suit :
∃ factory-method ∈ 2F, Creators, Products ∈ Η :
clan(factory-method, Creators) ∧
Production ↔ (factory-method, Products) ∧
Return-Type ↔ (factory-method, Products) ∧
Commute Return-Type,Creation (factory-method, Products)
Les formules LePUS sont accompagnées d’une représentation graphique (fig.14, fig15 et fig.16).
Chaque formule bien formée correspond à un diagramme bien formé.
fig.14 Symboles graphiques de base de LePUS, figure extraite de [Eden et al. 1999]
LATECE Technical Report 2004
16
fig.15 Symboles graphiques pour les relations prédominantes, Figure extraite de [Eden et al. 1999]
fig.16 Notation des clans et tribus dans LePUS, Figure extraite de [Eden et al. 1999]
Un diagramme dans LePUS est un graphe dont les nœuds correspondent à des variables (peuvent
être décorées par des relations unaires) et dont les arcs sont libellés avec des relations binaires
(possiblement généralisées). Le patron FACTORY METHOD est représenté par le diagramme
LePUS de la fig.17.
fig.17 Diagramme LePUS pour le patron FACTORY
LATECE Technical Report 2004
METHOD, Figure extraite de [Eden et al. 1999]
17
Un prototype d’outil qui permet l’identification et l’application des patrons, a été implémenté.
Cependant, LePUS n’est pas facile à utiliser par un concepteur débutant ou même avec une
expérience moyenne. La représentation graphique qui accompagne LePUS est compacte mais pas
facile à interpréter. Finalement, il intervient au niveau implémentation et l’intégration du code
généré au code existant n’est pas abordée.
5.4 Un langage visuel pour la modélisation des patrons
Maplesden et al. [Maplesden et al. 2001] [Maplesden et al. 2002] proposent un langage visuel
pour la modélisation et l'instanciation des patrons (DPML : Design patterns modelling language).
Ce langage permet l’incorporation des patrons dans des modèles de classes UML. Pour cela,
DPML propose deux diagrammes : un diagramme de spécification et un diagramme
d’instanciation du patron.
Fig.18 Notation de DPML, figure extraite de [Maplesden et al. 2001]
Dans le diagramme de spécification, un patron est représenté par une collection de participants
(ex : classe, méthode), de dimensions associées aux participants (ensemble d’objets jouant un
rôle) et de contraintes sur les participants. Une même dimension peut être associée à différents
participants dans un diagramme de spécification ce qui signifie que ces participants peuvent avoir
des objets multiples qui leur sont associés et qu’en plus le nombre de ces objets est le même pour
chacun des participants.
(a)
(b)
Fig.19 Diagramme de spécification et diagramme d’instanciation du patron Abstract Factory
figure extraite de [Maplesden et al. 2001]
LATECE Technical Report 2004
18
L’approche est illustrée avec le patron Abstract Factory (fig.2) qui contient 6 participants
(fig.19(a)). (1) L’interface AbstractFactory déclare un ensemble d’opérations abstraites de
création createOps que les concreteFactories vont implémenter. (2) L’opération createOps
représente une ensemble d’opérations et a donc une dimension (productsDimension). La relation
Declared_In entre createOps et AbstractFactory implique que toutes les méthodes liées à
l’opération createOps dans une instanciation du patron, doivent être déclarées dans l’objet qui est
lié à l’interface AbstractFactory. (3) L’implémentation concreteFactories a une dimension
(factoriesDimension) pour indiquer qu’elle représente un nombre de classes concrètes. (4) La
méthode concreteCreateOps représente toutes les méthodes de l’ensemble des concreteFactories
qui implémentent une opération de l’ensemble des createOps, et donc est associée avec les
dimensions factoriesDimension et productsDimension. (5) L’interface Products est associée à
productsDimension pour signifier qu’il y a le même nombre d’interfaces de produit abstrait qu’il
y a d’opérations abstraites createOps. La relation Return_Type implique que chacune des
opérations createOps a exactement un des Products comme type de retour. (6) L’implémentation
concreteProducts est associée à chacune des dimensions productsDimension et
factoriesDimension, comme il y a exactement un concreteProduct pour chaque produit abstrait et
fabrication concrète.
Le diagramme d’instanciation (fig.19(b)), quant à lui, spécifie les instances de patron de
conception et leurs réalisations à l’intérieur des modèles objet. Il relie un élément abstrait du
patron à des objets du modèle concerné. Un prototype d’un outil CASE supportant DPML a été
implémenté avec succès.
L’approche proposée par Maplesden et al. permet la représentation explicite des patrons de
conception. Le processus d’instanciation est aussi pris en charge mais il faut spécifier un
diagramme d’instanciation pour chaque modèle ou partie de modèle auquel on veut appliquer un
patron. La démarche d’application du patron est mixte dans la mesure où l’outil proposé permet
de compléter un modèle avec de nouveaux éléments ou nouvelles associations de façon à ce que
le nouvel ensemble soit conforme à la structure entière du patron.
5.5 FACE : Framework Adaptive Composition Environment
Meijler et al. [Meijler et al. 1997] proposent un environnement appelé FACE (Framework
Adaptive Composition Environment) avec une approche modélisation = programmation où le
niveau d’abstraction des patrons est celui du niveau de conception. La modélisation consiste alors
à définir les rôles des classes et les relations entre elles en des termes spécifiques aux patrons.
Meijler et al. illustrent leur approche par plusieurs exemples de patrons. Considérons l’exemple
du patron Abstract Factory (fig.1). Le développeur d’une application compose un modèle de
patron appelé schéma. Ce dernier est composé de classes et leurs rôles, d’opérations et leurs
rôles, de relations entre classes et/ou opérations et des paramètres. Les relations peuvent être
spécifiques au patron. La création de ce schéma est appelée l’instanciation du patron.
LATECE Technical Report 2004
19
fig.20 Schéma d’instanciation du patron Abstract Factory, figure extraite de [Meijler et al. 1997]
Les diagrammes représentant les schémas utilisent la notation OMT mais en ajoutant des
notations propres pour les relations spécifiques aux patrons. Le schéma d’instanciation pour
l’exemple du patron Abstract Factory est représenté à la fig.20.
Ce schéma rend explicite uniquement les aspects importants relatifs au patron. Dans ce cas là, par
exemple, les opérations de création, qui forment le cœur du patron, sont représentées
explicitement par des composants du schéma. Ce schéma est appelé schéma primaire car il
regroupe un ensemble basique de classes abstraites (capturant l’essence du patron) et de leurs
relations. Cependant, pour que ce schéma soit bien formé, il faut qu’il vérifie certaines règles
comme les règles de combinaison des éléments qui le composent. Meijler et al. ont introduit alors
le méta-schéma (fig.21) qui exprime la syntaxe et la sémantique du schéma.
LATECE Technical Report 2004
20
fig.21 Méta-schéma et schéma primaire du patron Abstract Factory
Figure extraite de [Meijler et al. 1997]
Le schéma primaire est dupliqué pour former le noyau. Le développeur commence par ce noyau
qu’il étend par les classes concrètes avec leurs rôles et leurs relations avec le noyau, les
opérations et les paramètres nécessaires. Ces extensions doivent se faire en conformité avec le
méta-schéma.
Dans cette approche, un patron et son instanciation sont représentés explicitement. Cependant, le
schéma d’instanciation inclut des informations spécifiques au cas concret pris comme exemple.
L’approche ne traite pas l’aspect transformation de modèle par application d’un patron.
5.6 Outil pour le support des patrons
Florijin et al. [Florijin et al. 1997] décrivent un environnement de développement orienté objet
permettant l’utilisation des patrons de conception pendant le développement ou la maintenance
de modèles ou programmes orientés objet. Ils se basent sur l’idée qu’à granularité grossière, un
patron de conception est un bloc de construction composé de différents éléments de conception et
que l’environnement doit être ouvert en considérant ces éléments qu’il doit exprimer.
L’environnement que Florijin et al. ont construit est composé de plusieurs parties (fig.22). Il a été
implémenté en Visualworks Smalltalk. L’élément noyau de l’architecture de cet environnement
est le modèle de fragment et la base de données de fragment correspondante. Tout élément du
programme (classe, méthode, relation entre classes, patron) est considéré comme un fragment (ou
graphe de fragments) d’un type particulier. Un fragment peut avoir des rôles qui peuvent
référencer d’autres fragments (ex : une classe et ses méthodes). Il peut aussi être référencé par un
rôle d’un autre fragment et dans ce cas il est appelé acteur dans ce rôle et il a un numéro
d’identification qui le distingue des autres acteurs de ce rôle. Pour contraindre les acteurs et leur
LATECE Technical Report 2004
21
nombre, un rôle a un type et peut avoir une cardinalité qui définit le nombre d’acteurs qui
peuvent lui être associés.
fig.22 Les composantes clés de l’environnement, Figure extraite de [Florijin et al. 1997]
Un patron est donc représenté par une structure de fragments où les fragments sont reliés par des
rôles. Cette structure a une racine (fragment) qui correspond à une instance de patron et qui a un
lien avec tous les fragments composants le patron. Ce lien représente le rôle que chacun des
fragments joue dans l’instance du patron. Le modèle de fragment pour l’exemple du patron
Abstract Factory est présentée à la fig.23.
fig.23 La structure du fragment correspondant à l’instance du patron Abstarct Factory
Figure extraite de [Florijin et al. 1997]
Le système entier des fragments (fragment database) est représenté comme un patron (fig.24). Il a
une racine à laquelle tous les fragments du système sont reliés par des rôles. Les rôles varient
LATECE Technical Report 2004
22
selon la nature du fragment ( le fragment peut être une racine d’un prototype de patron, un
comportement de fragments particuliers, un élément de conception ou une exception).
fig.24 Structure du fragment système, figure extraite de [Florijin et al. 1997]
L’outil offre aussi un modèle imbriqué de transactions. Ce modèle permet de traiter des
opérations spécifiques à un patron comme une seule entité. Il est aussi possible d’exprimer des
contraintes sur un patron par le moyen des prédicats qui sont écrits en Smalltalk. Chaque fois
qu’un patron est modifié, le contrôle de validation se fait. Des exceptions sont générées
lorsqu’une contrainte est violée.
L’environnement de développement proposé contient plusieurs outils qui facilitent l’ajout de
nouveaux éléments dans le système et aussi leur incorporation dans des patrons. Un explorateur
de fragment permet de visualiser la structure d’un fragment et de le manipuler. Un inspecteur de
fragment affiche les détails d’un fragment particulier. Un dernier outil « OMT-tool » permet au
concepteur de travailler à différents niveaux d’abstraction (conception, code).
L’approche de Florijin et al. s’est plus concentrée sur la représentation explicite d’un patron en
vue de le manipuler comme une construction. L’instanciation du patron se fait selon une
approche descendante, cela ne permet donc pas de transformer des modèles déjà existants par
application d’un patron.
6. Revue des approches déclaratives
6.1 Un méta-modèle pour les patrons
Pagel et Winter [Pagel et Winter 1996] partent de l’idée que pour supporter l’application des
patrons, un outil doit traiter les patrons comme les autres primitives de conception (classes,
attributs, etc.). En se basant sur [Pree 1994], ils proposent une description unifiée de tous les
patrons sous forme d’un méta-patron appelé « Template & Hook ». En plus de généraliser
l’approche méta-patron de Pree, ce méta-patron a des similarités avec le patron « Template
Method » de [Gamma et al. 1995] et le patron « Objectifier » de [Zimmer 1994].
LATECE Technical Report 2004
23
fig.25 Méta-patron « Template & Hook », figure extraite de [Pagel et Winter 1996].
Dans ce méta-patron (fig.25), une classe template est une classe d’un patron qui est couplée à au
moins une autre classe de ce patron. Ce couplage consiste souvent en un appel de méthode. Les
méthodes contenant ces appels sont appelées template methods. Les méthodes Hook sont des
méthodes abstraites appelées par au moins une méthode template. Elles sont définies dans des
classes abstraites « hook classes » qui sont couplées à au moins une classe template. Les classes
et méthodes template sont appelées des points stables « frozen spots », tandis que les classes et
méthodes hook sont appelées des points de variation « hot spots ».
À partir de ce méta-patron, Pagel et Winter dérivent un méta-modèle pour les patrons (fig.26).
Chaque élément du méta-patron est associé à une classe du méta-modèle. Des contraintes peuvent
être associées à une ou plusieurs classes. Ce méta-modèle va être utilisé pour compléter des outils
de conception.
Pagel et Winter définissent aussi le processus d’instanciation d’un patron comme un ensemble de
relations entre les différentes classes, méthodes et structures du patron abstrait et du patron
appliqué dans un contexte particulier. Ces relations sont : Classes, Features, Inheritance et
Associations. La relation Classes, par exemple, relie les classes de conception aux classes du
patron abstrait dont elles sont des instances. La relation Features relie les propriétés (attributs,
méthodes et leurs signatures complètes) d’une classe du patron abstrait à leurs instances qui sont
des propriétés d’une classe de conception. La relation Inheritance relie un couple de classes (une
classe et sa super-classe) du patron abstrait à leur instance qui correspond à un couple de classes
(une classe et sa super-classe) de conception. Finalement, la relation Associations relie une
association entre deux classes du patron abstrait à une association entre deux classes de
conception. Ces relations peuvent être utilisées pour valider le modèle de conception par rapport
à l’architecture abstraite du patron.
LATECE Technical Report 2004
24
fig.26 Méta-modèle pour les patrons, figure extraite de [Pagel et Winter 1996].
Un prototype d’outil, basé sur un méta-modèle étendu, est en cours de développement. Il est
accompagné d’un reposoir de patrons avec des facilités de navigation pour permettre au
concepteur de trouver le patron adéquat.
LATECE Technical Report 2004
25
Cette approche prend en charge la représentation explicite des patrons. De plus, le processus
d’instanciation est spécifié de telle façon que les éléments abstraits d’un patron sont associés aux
éléments d’une instance de ce patron. Toutefois, l’instanciation du patron ne s’applique pas d’une
façon automatique à un fragment de modèle existant. La transformation de modèles n’est pas
abordée.
6.2 Méta-programmation déclarative
Mens et Tourwé [Mens et Tourwé 2001] utilisent la technique de méta-programmation
déclarative pour spécifier les patrons, les instancier, générer du code et supporter l’évolution des
instances. Cette technique s’intéresse à la manipulation de code à un méta-niveau et cela dans le
but d’automatiser certains aspects du processus de développement logiciel.
Mens et Tourwé se basent sur l’association étroite d’un méta-langage déclaratif et un langage
orienté objet. Comme méta-langage, ils utilisent un langage de programmation logique appelé
SOUL qui est une variante de PROLOG avec quelques légères différences syntaxiques. Toutes
les constructions du langage orienté objet sont représentées par des faits dans le méta-langage
moyennant des prédicats de mise en correspondance (mapping) (table 1). Pour chacun des
prédicats, un prédicat generatecode permet de générer l’implémentation (code) adéquate au métaniveau.
Prédicat de mapping
Description
class(?C)
C doit être une classe
subclass( ?P, ?C)
La classe C doit être une sous-classe directe de la classe P
Table 1 : Exemples de prédicats de mapping
Un patron est spécifié sous forme d’un prédicat pattern contenant son type (ex : composite,
abstractFactory) et un ensemble de rôles correspondants aux participants du patron ( pattern(nom,
[liste des rôles]) ). Une instance du patron a un identificateur unique, un type de patron et un
ensemble de participants concrets associés aux rôles définis dans le prédicat pattern. Le prédicat
représentant le patron Abstract Factory, par exemple, est comme suit :
pattern(abstractFactory,
[abstractFactory, concreteFactory, genericProduct, abstractProduct, concreteProduct,
abstractRelation, concreteRelation, abstractFactoryMethod, concreteFactoryMethod]).
Considérons l’exemple de l’instance du patron Abstract Factory représentée à la fig.27. La
spécification déclarative de cette instance, dont l’identificateur est AF1, est représentée à la
fig.28.
LATECE Technical Report 2004
26
fig.27 Instance du patron Abstract Factory
patternInstance(AF1, abstractFactory).
role(AF1, abstractFactory, Look).
role(AF1, concreteFactory, MSLook).
role(AF1, concreteFactory, MacLook).
role(AF1, genericProduct, Widget).
role(AF1, abstractProduct, Window).
role(AF1, abstractProduct, Button).
role(AF1, concreteProduct, [MSWindow, Window]).
role(AF1, concreteProduct, [MSButton, Button]).
role(AF1, concreteProduct, [MacWindow, Window]).
role(AF1, concreteProduct, [MacButton, Button]).
role(AF1, abstractRelation, [Look, Window]).
role(AF1, abstractRelation, [Look, Button]).
role(AF1, concreteRelation, [MSLook, MSWindow]).
role(AF1, concreteRelation, [MacLook, MacWindow]).
role(AF1, concreteRelation, [MSLook, MSButton]).
role(AF1, concreteRelation, [MacLook, MacButton]).
role(AF1, abstractFactoryMethod, [newWindow, Look, Window]).
role(AF1, abstractFactoryMethod, [newButton, Look, Button]).
role(AF1, concreteFactoryMethod, [newWindow, MSLook]).
role(AF1, concreteFactoryMethod, [newWindow, MacLook]).
role(AF1, concreteFactoryMethod, [newButton, MSLook]).
role(AF1, concreteFactoryMethod, [newButton, MacLook]).
fig.28 Spécification déclarative d’une instance du patron Abstract Factory
Les contraintes sur le patron sont spécifiées par un prédicat patternConstraint. Par exemple, le
patron Abstract Factory spécifie que toutes les fabriques concrètes (concreteFactory) doivent
être descendantes de la classe de fabrication abstraite (abstractFactory) et que toutes les sousclasses de la classe fabrication abstraite (abstractFactory) doivent être des fabriques concrètes
(concreteFactory). Cette contrainte est exprimée par le prédicat suivant :
patternConstraint(?I, abstractFactory) :∃?AF such that role(?I, abstractFactory, ?AF) :
∀?CF such that role(?I, concreteFactory, ?CF) :
hierarchy(?AF, ?CF)
∀?C such that concreteSubclass(?AF, ?C) :
role(?I, concreteFactory, ?C).
LATECE Technical Report 2004
27
L’instanciation du patron se fait par le biais d’une requête createPattern avec les arguments
adéquats.
createPattern(AF1, abstractFactory,
[abstractFactory([Look]),
concreteFactory([MSLook, MacLook]),
genericProduct([Widget]),
abstractProduct([Window, Button]), ...])
Cette requête ajoute alors des faits dans la base de données en appelant la clause addRole pour
chaque rôle dans le patron à instancier. La clause addRole, quant à elle, appelle le prédicat
generate qui permet de générer le squelette du code.
createPattern(?Instance, ?PatternKind, ?RoleSet) :assert( patternInstance(?Instance, ?PatternKind)),
∀ ?Role(?Participants) ∈ ?RoleSet :
∀ ?P ∈ ?Participants : addRole(?Instance, ?Role, ?P).
addRole(?Instance, ?Role, ?Participant) :assert(role(?Instance, ?Role, ?Participant)),
generate(?Instance, ?Role, ?Participant).
Mens et Tourwé définissent les transformations de haut niveau comme une combinaison de
transformations primitives. Elles sont spécifiées sous forme d’un ensemble de règles logiques.
L’application d’une règle se fait par un prédicat transform qui invoque la transformation après
avoir vérifié ses pré-conditions. Par exemple, la transformation composite extractSuperclass
génère une nouvelle classe et redirige tous les parents de toutes les classes vers cette nouvelle
super-classe :
extractSuperclass(?Classes, ?Superclass):generateCode(class(?Superclass)),
∀?C ∈ ?Classes :
transform(changeSuperclass(?C, ?Superclass)).
transform(?Transformation):checkPrecondition(?Transformation),
call(?Transformation).
Dans le cas d’une transformation faite sur l’instance d’un patron, l’ajout d’un élément à l’instance
appelle directement le prédicat addRole qui modifie la spécification de l’instance et génère le
fragment de code correspondant. Dans le cas d’une suppression, l’opération est plus dangereuse
dans la mesure où elle peut avoir un impact sur d’autres instances de patrons.
Selon Mens et Tourwé, les conflits, pouvant résulter de la modification d’une instance par un
utilisateur, peuvent être résolus en utilisant uniquement les transformations fournies pour chaque
patron. Cependant, certaines inconsistances structurelles ou comportementales peuvent résulter
des transformations indépendantes (deux entités reliées d’une certaine façon sont modifiées
simultanément). Ces inconsistances ne peuvent pas être détectées par la vérification des
LATECE Technical Report 2004
28
contraintes du patron ou des pré-conditions des transformations, mais plutôt en utilisant des
tables de conflits contenant les transformations qui aboutissent à des conflits quand elles sont
appliquées en parallèle dans certaines conditions.
Cette approche représente d’une façon explicite un patron et son instanciation. Mens et Tourwé
se sont aussi intéressés aux transformations valides qui peuvent être faites sur du code déjà
existant (refactoring) et sur des instances de patrons. Cependant, les transformations sont faites
sur du code et l’instanciation du patron a pour but aussi la génération de code.
6.3 UML et les diagrammes de contraintes
Ayant pour objectif de représenter un patron dans sa généralité, Lauder et Kent [Lauder et Kent
1998] utilisent en conjonction la notation des diagrammes de contraintes [Kent 1997] et la
notation UML. Ils entendent par généralité le fait d’exprimer un patron avec des collections
d’éléments sans pour autant donner une cardinalité fixe à ces collections ni des noms aux
membres de ces collections. Pour cela, ils utilisent les diagrammes de contraintes qui sont
similaires aux diagrammes de Venn. Ils permettent la spécification d’ensembles « anonymes »
contraints.
Dans les diagrammes de contraintes (fig.29), un élément arbitraire d’un ensemble est représenté
par un point. Les points, reliés par un trait, représentent le même élément à différentes positions,
l’élément ne peut être qu’à une position à la fois. Les points, reliés par un trait courbé, ne
représentent pas nécessairement des éléments distincts, par contre les points non connectés
représentent des éléments assurément distincts. Un arc orienté représente une relation de
navigation entre différents ensembles correspondant à une relation entre leurs membres.
Fig.29 Diagrammes de contraintes, figure extraite de [Lauder et Kent 1998]
Lauder et kent proposent d’utiliser ces diagrammes en conjonction avec la notation UML. Pour
spécifier les instances d’une classe d’une façon abstraire, ils ont ajouté à une classe un
compartiment (fig.30) où les instances de cette classe sont spécifiées avec un diagramme de
contraintes.
LATECE Technical Report 2004
29
fig.30 Diagramme de classe UML avec des instances abstraites,
Figure extraite de [Lauder et Kent 1998]
Pour exprimer les patrons d’une façon plus générale et plus abstraite, Lauder et Kent présentent
une modélisation à trois couches des patrons. Le premier modèle est le modèle de rôles (fig.31).
Il est le plus abstrait et il est exprimé par un ensemble contraint qui capture l’esprit pur du patron.
Il spécifie un état et une sémantique hautement abstraits.
fig.31 Modèle de rôles pour le patron Abstract Factory, figure extraite de [Lauder et Kent 1998]
Ce modèle peut être instancié par un modèle de la couche intermédiaire appelé le modèle de type
(fig.32) spécifique à un domaine. Le type, comme dans UML, est défini comme une spécification
d’un état abstrait et des interfaces d’opérations. Le modèle de type représente la structure
abstraite du patron mais il introduit une syntaxe concrète pour les opérations décrites dans la
sémantique du modèle de rôle. Le dernier modèle est un modèle de classe (comme présenté dans
[Gamma et al. 1995]) qui réalise le modèle de type. Il contient les détails de l’implémentation
concrète du patron.
LATECE Technical Report 2004
30
fig.32 Modèle de type pour le patron Abstract Factory, figure extraite de [Lauder et Kent 1998]
fig.33 Relation entre le modèle de type et le modèle de rôle, figure extraite de [Lauder et Kent 1998]
Pour ce qui est de l’aspect collaboration, Lauder et Kent se conforment à la tradition de [Gamma
et al. 1995] et utilisent pour la spécification de cet aspect des diagrammes de séquence. Toutefois,
ils associent à ces diagrammes de séquence des pré- et post-conditions sous forme de diagrammes
de contraintes.
L’approche permet de décrire les patrons d’une façon très abstraite, générale mais aussi très
précise et visuelle. Elle est très intéressante dans la mesure où elle se base sur l’idée de
raffinement de modèles pour aboutir à l’instanciation d’un patron. Cependant, l’utilisation des
diagrammes de contrainte ne fait pas partie du standard UML et donc les outils UML ne pourront
LATECE Technical Report 2004
31
pas être utilisés pour appliquer cette approche à moins qu’ils soient modifiés ou étendus par
d’autres outils.
6.4 Un méta-modèle dédié aux patrons
Dans [Albin-Amiot et Guéhéneuc 2001] , les patrons sont modélisés par un ensemble d’entités et
éléments définis dans un méta-modèle dédié à la représentation des patrons (fig.34). Ce métamodèle est utilisé pour décrire un patron, l’instancier et de générer le code associé. Il est aussi
utilisé pour la détection des patrons dans du code. Il englobe toutes les entités nécessaires pour
décrire la structure et le comportement des patrons. La structure du méta-modèle proposé est
similaire à celle proposée par [Pagel et Winter 1996].
fig.34 Méta-modèle pour les patrons, figure extraite de [Albin-Amiot et Guéhéneuc 2001]
Dans ce méta-modèle, un patron est représenté par une instance d’une sous-classe de la classe
Pattern. Cette dernière est une collection d’instances de la classe PEntity correspondant à un
participant (classe ou interface) dans le patron. Chaque instance de PEntity contient un ensemble
d’éléments instances de PElement représentant ses champs, ses méthodes et les relations
d’association et de délégation qu’elle a avec d’autres instances de PEntity.
L’instanciation d’un patron se fait en quatre étapes (fig.35). La première consiste à spécialiser le
méta-modèle en un méta-modèle spécifique au patron en question. Dans le cas du patron
Composite, par exemple, le méta-modèle présenté précédemment est suffisant. Le méta-modèle
spécifique au patron sera instancié, dans la seconde étape, en un modèle abstrait du patron. Ces
modèles abstraits sont stockés dans un reposoir représenté par la classe PatternsRepository du
méta-modèle. La troisième étape consiste à instancier le modèle abstrait obtenu en un modèle
concret spécifique à une application. La dernière étape est la génération de code qui est
déclenchée par l’appel de la méthode « build() » de la classe Pattern.
LATECE Technical Report 2004
32
fig.35 Le processus d’instanciation du patron Composite
Figure extraite de [Albin-Amiot et Guéhéneuc 2001]
La fig.36 représente le patron Composite comme défini dans [Gamma et al.1995]. Le modèle
abstrait du patron Composite est représenté à la fig.37.
fig.36 Le patron Composite dans [Gamma et al. 1995]
fig.37 Le modèle abstrait du patron Composite
Le modèle abstrait est exprimé d’une façon déclarative dans une classe Java appelée Composite
qui est une sous-classe de la classe Pattern dans le méta-modèle. Un fragment de cette
déclaration est visualisé à la fig.38.
LATECE Technical Report 2004
33
fig.38 Représentation déclarative en Java du patron Composite
L’instanciation du modèle abstrait du Composite donne un modèle concret dépendant d’un
contexte donné. Pour illustrer la procédure d’instanciation, Albin-Amiot et Guéhéneuc utilisent
un modèle concret introduit par [Gamma et al. 1995]. Ce modèle représente une hiérarchie de
composants graphiques (fig.39).
LATECE Technical Report 2004
34
fig.39 Un modèle concret du patron Composite
On peut obtenir le modèle concret de la fig.39, en créant une instance de la classe Composite
définie à la fig.38. Tous les paramètres de l’instance doivent être nommés conformément au
contexte qui est défini par le modèle concret ciblé (fig.40). L’étape finale consiste à générer le
code correspondant au modèle concret par appel de la méthode « build() » de la classe Pattern. Le
code généré est présenté à le fig.41.
fig.40 Instanciation du Composite en un modèle concret
Cette approche est plutôt descendante, elle ne permet pas le rétro-conception dans la mesure où
elle ne s’applique pas à un modèle existant déjà. Aussi, le code généré n’est pas intégré dans le
code d’un utilisateur.
LATECE Technical Report 2004
35
/* Graphic.java */
public interface Graphic {
public abstract void draw();
}
/* Picture.java */
public class Picture implements Graphic {
// Association: children
private Vector children = new Vector();
public void addGraphic(Graphic aGraphic)
{children.addElement(aGraphic);}
public void removeGraphic(Graphic aGraphic)
{children.removeElement(aGraphic);}
// Method linked to:children
public void draw()
{for(Enumeration enum = children.elements();
enum.hasMoreElements();
((Graphic)enum.nextElement()).draw());
}
}
/* Text.java */
public class Text implements Graphic {
public void draw(){}
}
/* Line.java */
public class Line implements Graphic {
public void draw(){}
}
/* Rectangle.java */
public class Rectangle implements Graphic {
public void draw(){}
}
Fig.41 Code généré à partir du modèle concret
6.5 Méta-modèle basé sur les rôles
France et al. [France et al. 2004] [France et al. 2003] proposent de spécifier les patrons au niveau
méta. Un méta-modèle UML peut être spécialisé pour définir un méta-modèle pour les patrons.
La spécialisation se fait, d’une part, par le sous-typage des classes du méta-modèle et d’autre
part, par la définition de règles plus restrictives et de contraintes OCL correspondant à la
sémantique du patron. France et al. distinguent l’aspect structurel et l’aspect interaction qui
définissent un patron.
Pour ce qui est de l’aspect structurel, ils définissent une structure de rôles appelée la spécification
structurelle du patron (SPS : Structural Pattern Specification). Cette dernière définit des soustypes des classes du méta-modèle UML et des contraintes pour décrire les éléments du modèle de
classes du patron et leur sémantique. Le sous-type d’une classe du méta-modèle UML, est appelé
rôle (classifier role). Le rôle spécifie les propriétés qu’un élément du modèle UML doit avoir
pour faire partie d’un modèle de patron. La classe concernée du méta-modèle est appelée la base
du rôle, elle peut être une classe ou une relation entre classes (association, héritage, etc…).
Certaines règles et contraintes additionnelles sur les éléments du modèle du patron (les éléments
qui jouent des rôles) sont exprimées sous forme de contraintes OCL au niveau du méta-modèle.
Les propriétés sémantiques du patron sont décrites avec des « templates » de contrainte OCL.
LATECE Technical Report 2004
36
fig.42 Structure du classifier role, figure extraite de [France et al. 2004]
Un classifier role est représenté à la fig.42. La première partie indique le nom de la classe de
base, le nom du rôle et une multiplicité qui représente le nombre de classes pouvant jouer ce rôle
dans un diagramme de classe conforme au patron. Une spécification structurelle (SPS) contient
au minimum un rôle obligatoire à instancier. La deuxième partie correspond aux propriétés
structurelles du rôle (ex : attribut). La troisième partie spécifie les propriétés comportementales
associées au rôle (ex : opération).
(a)
(b)
fig.43 Vue partielle du SPS pour le patron Observer et de son méta-modèle UML spécialisé
figure extraite de [France et al. 2004]
Un exemple qui spécifie une variante du patron Observer est montré à la fig.43. Cette variante
stipule qu’il peut y avoir une ou plusieurs classes Observer et une ou plusieurs classes Subject et
qu’une classe Observer doit avoir une seule association Observes avec une classe Subject et vice
versa. La fig.43 est une vue partielle de la spécification du patron car elle ne montre pas les
contraintes et les propriétés des rôles. La spécification structurelle de la fig.43(a) montre deux
rôles de classes Subject et Observer et une association entre ces rôles appelée Observes. Ces rôles
LATECE Technical Report 2004
37
définissent des sous-types des classes du méta-modèle UML comme montré à la fig.43(b). Par
exemple, les rôles Subject et Observer sont des sous classes de la classe Class et le rôle Observes
est une spécialisation de la classe Association.
La spécification de la fig.43 indique qu’un diagramme de classes conforme à cette variante du
patron Observer doit avoir au moins une classe conforme au rôle Subject et une autre au rôle
Observer, cela est indiqué par la multiplicité (1..*) spécifiée dans le rôle. En plus, une classe
conforme au rôle Subject doit avoir exactement une propriété structurelle conforme au rôle
SubjectState et une opération conforme au rôle Attach. D’un autre côté, une classe conforme au
rôle Observer doit aussi avoir exactement une propriété structurelle conforme au rôle
ObserverState et une opération conforme au rôle de la propriété comportementale Update.
Une association conforme au rôle Observes doit avoir un côté « association-end » connecté à une
classe Subject et l’autre connecté à une classe Observer. Le côté connecté à Subject doit être
conforme au rôle Sub et l’autre côté doit être conforme au rôle Obs. la multiplicité du rôle Sub
(respectivement Obs) impose qu’une classe Subject (respectivement Observer) doit participer à
une seule association Observes. D’autres contraintes sur ces éléments sont spécifiées au niveau
du méta-modèle sous forme d’expressions OCL. Des templates sont utilisés pour exprimer les
propriétés sémantiques. France et al. distinguent, d’un côté, les «operation templates» qui
expriment les propriétés sémantiques associées aux propriétés comportementales d’un rôle et,
d’un autre côté, les «property templates» qui correspondent aux invariants du modèle. Un
diagramme de classes est dit conforme à une SPS s’il est conforme aux contraintes structurelles et
aux propriétés sémantiques du patron.
D’une façon analogue à Gamma et al., France et al. utilisent des diagrammes de séquence pour
spécifier l’aspect interaction dans un patron. Ils introduisent une spécification d’interaction du
patron (IPS : interaction pattern specification) qui est un diagramme de séquence décrivant les
interactions entre les rôles présents dans la spécification structurelle du patron. En fait, c’est un
méta-modèle qui spécifie les diagrammes d’interaction conformes au patron.
France et al. ont développé un outil prototype qui leur a permis de créer des SPSs, de les utiliser
et de générer des diagrammes de classes. Cependant, la prise en charge des contraintes a posé des
problèmes car leur outil se base sur Rational Rose dont la version actuelle ne permet pas la
manipulation des contraintes OCL. En outre, la démarche de France et al. est une démarche
descendante, elle ne permet pas de manipuler les modèles déjà existants. L’aspect transformation
d’un modèle existant déjà par application du patron n’est pas du tout pris en charge.
7. Discussion
Généralement parlant, il y a un consensus sur les éléments qui composent et définissent un
patron. Cependant, certaines approches se sont plus concentrées sur l’aspect structurel du patron,
négligeant l’aspect collaboration entre éléments du parton. L’aspect sémantique du patron n’est
pas toujours pris en charge. Les travaux qui proposent des langages formels basés sur des
notations mathématiques, permettent une spécification précise et générique des patrons et de leur
application mais ces approches nécessitent des connaissances en mathématique pour pouvoir les
assimiler.
LATECE Technical Report 2004
38
Une synthèse de tous les travaux passés en revue est présentée dans la table 2. Cette table est
basée sur notre cadre de comparaison énoncé à la section 3. Les trois familles d'approches sont
représentées avec différentes couleurs dans la table. La plupart des approches ont pour objectif de
fournir un support d’aide à la conception et non pas la rétro-conception. En effet, la majorité des
travaux adoptent une démarche descendante pour l’application d’un patron.
Quelques aspects dans les descriptions des patrons ne sont pas évidents à spécifier (ex : intention,
motivation, conséquence, indications d’utilisation, etc.). Le travail de [Budinsky et al. 1996] est
le seul qui s’est intéressé à l’ensemble des rubriques employées par [Gamma et al. 1995] pour
décrire un patron. Toutefois, l’approche s’est limitée à fournir une description textuelle de ces
rubriques. La question qui se pose alors : est-ce qu’on doit laisser appliquer le patron sans qu’il y
ait la motivation ? Il faudra penser à spécifier des pré-conditions pour l’application d’un patron.
Les travaux de [Mens et Tourwé 2001] et [Sunyé et al. 2000] sont les seuls qui proposent
d’appliquer des transformations avec des pré-conditions.
Niveau d’abstraction
Structure
Interaction Contraintes
Sémantique
Transformation
[Budinsky et al. 1996]
[Sunyé et al. 2000]
[Maplesden et al. 2001]
[Meijler et al. 1997]
[Florijin et al. 1997]
[Pagel et Winter 1996]
[Mens et Tourwé 2001]
[Lauder et Kent 1998]
[Albin-Amiot et
Guéhéneuc 2001]
[France et al. 2004]
Modèle
abstrait
X
X
X
[Alencar et al. 1997]
[Sanada et Adams 2002]
[Fontoura et Lucena
2001]
[Eden et al. 1999]
Métamodèle
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
Rétroconception
X
X
X
X
X
X
X
X
Gris : Représentation implicite
Vert : Représentation explicite
Blanc : Représentation déclarative
Table 2 : table de synthèse
Parmi les quelques approches qui se sont intéressées à la représentation des contraintes sur les
éléments du patron, Florijin et al. ont aussi investigué les méthodes de validation et de
vérification d’un modèle après application du patron. En fait, lors des modifications manuelles ou
automatiques d’un modèle, la structure d’une instance de patron peut être rompue soit par une
suppression d’un élément ou par l’ajout incomplet d’éléments. Cela peut être pris en charge par
l’ajout de contraintes dont il faudra tenir compte lors de l’application du patron et aussi lors des
modifications ultérieures. Mens et Tourwé [Mens et Tourwé 2001] suggèrent d’énumérer toutes
les transformations possibles pour chaque patron.
LATECE Technical Report 2004
39
D’autres travaux [Noble 1998a] [Noble 1998b] [Zimmer 1994] se sont intéressés aux relations
entre différents patrons. Selon Noble [Noble 1998b], certains patrons peuvent être en conflit et ne
peuvent être utilisés ensemble dans un même contexte. Seul l’approche de [Eden et al. 1999] a
abordé cet aspect lors de l’utilisation des patrons. Toutefois, Eden et al. se sont limités à la
spécification de la relation de raffinement entre deux patrons. Finalement, en dehors des
approches utilisant des valeurs marquées (étiquettes), la traçabilité des éléments composant une
instance de patron n’est pas toujours possible. Ce qui rend difficile la modification ultérieure de
cette instance.
8. Conclusion
Dans ce rapport nous avons passé en revue certains des travaux qui ont essayé de spécifier les
patrons de façon plus formelle ou de les intégrer dans des environnements de développement.
Selon les objectifs de notre travail, nous constatons qu'il y a de nombreux travaux qui proposent
des représentations explicites des patrons, cependant peu d'entre eux représentent explicitement
l'aspect dynamique et sémantique du patron. Les transformations appliquées à un modèle lors de
l'utilisation d'un patron sont rarement représentées explicitement. Autrement dit, peu d'outils et
environnements proposés sont orientés vers la rétro-conception.
LATECE Technical Report 2004
40
Références bibliographiques
[Albin-Amiot et Guéhéneuc 2001] H. Albin-Amiot et Y.G. Guéhéneuc, « Meta-modeling Design
Patterns: application to pattern detection and code synthesis », in Proceedings of ECOOP
Workshop on Automating Object-Oriented Software Development Methods, Juin 2001.
[Alencar et al. 1996] P.S.C Alencar, D.D. Cowan et C.J.P. Lucena, « A formal approach to
architectural design patterns », Proceedings of the 3rd iternational symposium of FME, pages
576-594, 1996.
[Alencar et al. 1997] P.S.C Alencar, D.D. Cowan, J. Dong et C.J.P. Lucena, « A transformational
Process-Based Formal Approach to Object-Oriented Design », Formal Methods Europe
(FME’97), 1997.
[Borne et Revault 1999] I. Borne et N. Revault « Comparaison d'outils de mise en oeuvre de
Design Patterns », in Revue L'Objet, Vol.5, No.2 - numéro spécial sur les Patrons de Conception,
pp. 243-266, 1999.
[Budinsky et al. 1996] F.J. Budinsky, M.A. Finnie, J.M. Vlissides et P.S. Yu, « Automatic Code
Generation from Design Patterns », dans IBM Systems Journal, vol.35, No.2, pp.151-171, 1996.
[Buschman et al. 1996] F. Buschmann, R. Meunier, H. Rohnert, P. Sommerlad et M. Stal,
« Pattern-Oriented Software Architecture » John Wiley and sons, 1996.
[Coad 1992] P. Coad, « Object-oriented patterns », communications of the ACM, vol.35, No.9,
pp.152-159, septembre 1992.
[Eden et al. 1997] A. Eden, J. Gil et A. Yehudai, « Automating the Application of Design
Patterns », Journal of Object-Oriented Programming, vol.10, No.2, pp 44-46, 1997.
[Eden et al. 1999] A.H. Eden, J. Gil, Y. Hirshfeld et A. Yehudai, « Towards a mathematical
foundation for design patterns », Technical report, dept.of information technology, U.Uppsala,
1999.
[Eide et al. 2002] E. Eide, A. Reid, J. Regehr et J. Lepreau, « Static and Dynamic Structure in
Design Patterns », in Proceedings of the 24th International Conference on Software Engineering
(ICSE 2002), Orlando, FL, Mai 2002.
[Florijin et al. 1997] G. Florijn, M. Meijers et P. van Winsen, « Tool support for object-oriented
patterns » in Lecture Notes in Computer Science, vol. 1241, pp. 472-495, 1997. (ECOOP97,
Finland).
[Fontoura et Lucena 2001] M. Fontoura et C. Lucena, « Extending UML to Improve the
Representation of Design Patterns », Journal of OO Programming, vol.13, No11, mars 2001.
LATECE Technical Report 2004
41
[Fowler 1997] M. Fowler, « Analysis patterns, reusable object models », Addisson Wesley, 1997.
[France et al. 2003] R.B. France, S. Ghosh, E. Song et D-K. Kim, « A Metamodeling Approach
to Pattern-based Model Refactoring », IEEE Software, Special Issue on Model Driven
Development, Vol.20, No.5, Septembre/Octobre 2003.
[France et al. 2004] R.B. France, D-K. Kim, S. Ghosh et E. Song, « A UML-Based Pattern
Specification Technique », IEEE Transactions on Software Engineering, vol.30, No3, pp. 193206, mars 2004.
[Gamma et al. 1995] E. Gamma, R. Helm, R. Johnson and J. Vlissides, « Design Patterns:
Elements of Reusable Object-Oriented Software », Addison-Wesley, 1995.
[Johnson 1997] R.E. Johnson, « Frameworks = (components + patterns) », Communications of
the ACM, vol.40 , No.10, pp. 39-42, Octobre 1997.
[Lauder et Kent 1998] A. Lauder et S. Kent, « Precise Visual Specification of Design Patterns »,
Lecture Notes in Computer Science, vol. 1445, pp. 114-134, 1998.
[Maplesden et al. 2001] D. Maplesden, J. Hosking et J. Grundy, « A Visual Language for Design
Pattern Modelling and Instantiation », Proceedings of the IEEE Symposia on Human-Centric
Computing Languages and Environments, 2001.
[Maplesden et al. 2002] D. Maplesden, J. Hosking et J. Grundy, « Design Pattern Modelling and
Instantiation using DPML », Proceedings of 14th International Conference on Technology of
Object-Oriented Languages and Systems (TOOLS Pacific 2002), Sydney, Australia.
[Meijler et al. 1997] T.D. Meijler, S. Demeyer et R. Engel, « Making Design Patterns Explicit in
FACE, A Framework Adaptive Composition Environment », in Proceedings of the Sixth
European Software Engineering Conference (ESEC/FSE’97), pp.94-110, 1997.
[Mens et Tourwé 2001] T. Mens et T. Tourwé, « A Declarative Evolution Framework for ObjectOriented Design Patterns », Proceedings IEEE International Conference on Software
Maintenance (ICSM 2001), pp. 570-579, Florence, Italy, 6-10 Novembre, 2001.
[Noble 1998a] J. Noble, «Towards a Pattern Language for Object Oriented Design », In 28th
International Conference on Technology of Object-Oriented Languages and Systems - Pacific
(TOOLS 28), Melbourne, Australia, 23-26 Novembre, 1998.
[Noble 1998b] J. Noble, « Classifying relationships between object-oriented design patterns », In
Australian Software Engineering Conference (ASWEC), 1998.
[Rumbaugh et al. 1996] J. Rumbaugh, M. Blaha, W. Premerlani, F. Eddy et W. Lorensen, « OMT
: modélisation et conception orientées objet », Prentice-Hall, 1996.
[OMG] http://www.omg.org/
LATECE Technical Report 2004
42
[Pagel et Winter 1996] B-U. Pagel, M. Winter, « Towards Pattern-Based Tools », In Proceedings
of EuropLop, Munchen, 1996.
[Pree 1994] W. Pree, « Design Patterns for Object-Oriented Software Development », AddisonWesley, 1994.
[Pree 1998] W. Pree, « Design patterns et architectures logicielles », traduction de Olivier
Lhomme, Vuibert , 1998.
[Sanada et Adams 2002] Y. Sanada et R. Adams « Representing Design Patterns and
Frameworks in UML, Towards a Comprehensive Approach », Journal of Object Technology Vol.
1, No. 2, pp 143-154, Juillet-Août 2002.
[Sunyé et al. 2000] G. Sunyé, A. Le Guennec, and J.M. Jézéquel, «Design pattern application in
UML » In E. Bertino, editor, ECOOP'2000 proceedings, number 1850, pp. 44-62, Lecture Notes
in Computer Science, Springer Verlag, Juin 2000.
[UMLAUT] UMLAUT: Unified Modeling
http://www.irisa.fr/UMLAUT/Welcome.html
Language
All
pUrposes
Transformer,
[Zimmer 1994] W. Zimmer, « Relationships Between Design Patterns », In Pattern Languages of
Program Design, Addison-Wesley, 1994.
LATECE Technical Report 2004
43