Tâche: Identifier les éléments de conception |
|
 |
Cette tâche explique comment identifier les sous-systèmes, les classes, les interfaces, les événements et les signaux. |
|
Objet
-
Analyser les
interactions entre les classes d'analyse pour identifier les éléments de modèle de conception
|
Relations
Rôles | Principal:
| Complémentaire:
| Auxiliaire:
|
Entrées | Obligatoire:
| Facultatif:
| Externe:
|
Sorties |
|
Description principale
La Tâche : Analyse des cas d'utilisation produit des classes
d'analyse, qui représentent des éléments conceptuels pouvant adopter un comportement. En conception, les
classes d'analyse évoluent vers un certain nombre de types différents d'éléments de conception :
-
des classes, pour représenter un ensemble de responsabilités à granularité plutôt fine ;
-
des sous-systèmes, pour représenter un ensemble de responsabilités à granularité grossière (ils sont composés
éventuellement d'un autre ensemble de sous-systèmes, mais en dernier ressort d'un ensemble de classes) ;
-
des classes actives, qui représentent les fils de contrôle dans le système ;
-
des interfaces, pour représenter les déclarations abstraites de responsabilités fournies par une classe ou un
sous-système.
De plus, en conception, il faut également identifier :
-
les événements, à savoir les spécifications d'occurrences intéressantes dans le temps et dans l'espace qui exigent
habituellement (si elles sont remarquables) une réponse du système ; et
-
les signaux, qui représentent les mécanismes asynchrones utilisés pour communiquer certains types d'événements dans
le système.
Ces distinctions plus fines nous permettent d'examiner différents aspects de la conception :
-
Les événements, et les signaux utilisés pour les communiquer, nous permettent de décrire les déclencheurs
asynchrones de comportement auxquels le système doit répondre.
-
Les classes et les sous-systèmes nous permettent de regrouper les responsabilités associées en unités, lesquelles
peuvent être développées de manière relativement indépendante. Les classes remplissent un ensemble atomique de
responsabilités associées, tandis que les sous-systèmes sont des blocs de construction composites, formés à leur
tour de classes ou d'autres sous-systèmes. Les sous-systèmes permettent de représenter les produits d'une équipe de
développement en une seule unité intégrale de fonctionnalité. En tant que telles, elles sont utilisées à la fois
comme unités de contrôle et de gestion de la configuration et comme éléments de conception logique.
-
Les classes actives sont utilisées pour représenter les fils de contrôle dans le système, ce qui nous permet de
modéliser l'accès concurrent. Les classes actives sont souvent utilisées en combinaison avec d'autres classes qui
sont généralement passives (mais pas nécessairement). Une telle combinaison peut alors permettre, tout comme une
collaboration, de modéliser un comportement complexe.
Dans les systèmes en temps réel, les capsules sont utilisées à la place des classes actives, offrant une
sémantique plus forte pour simplifier la conception et accroître la fiabilité des applications concurrentes.
Les capsules partagent certains aspects des classes et des sous-systèmes : il s'agit en effet de collaborations
encapsulées de classes qui, ensemble, représentent un fil de contrôle dans le système. A la différence du
sous-système, qui est (généralement) pris en charge par une équipe de développeurs, une capsule est prise en
charge par un seul concepteur ; cependant, un sous-système peut contenir des capsules.
-
Les interfaces nous permettent d'examiner et d'enregistrer les "coutures" du système, pour définir précisément la
manière dont les parties constitutives du système vont interopérer.
-
Dans les systèmes en temps réel, nous devons utiliser les protocoles pour définir précisément les messages qui
peuvent être envoyés et reçus sur le port d'une capsule.
En procédant à des distinctions et en traitant séparément chaque problème représenté par ces concepts, nous simplifions
le processus de conception et clarifions notre solution.
Si la traçabilité doit être maintenue entre les modèles système, elle doit être documentée lors de cette
tâche. Pour plus d'informations sur la documentation de la traçabilité entre le modèle de conception et les autres
modèles système, voir Instructions : Modèle
de conception.
Représentation UML 1.x
Selon UML 1.5, un sous-système est un type particulier de package qui ne possède que des interfaces comme éléments
publics. Les interfaces constituent une couche d'encapsulation qui permet à la conception interne du sous-système de
rester invisible pour les autres éléments de modèle. Le concept de sous-système permet de distinguer ce dernier des
packages "ordinaires", qui sont des conteneurs d'éléments de modèle sans sémantique ; le sous-système représente une
utilisation particulière de packages possédant des propriétés de comportement semblables à celles des classes.
Dans le processus RUP, les capsules sont représentées à l'aide de la notation UML 1.5. Une grande partie peut être
représentée dans UML 2.0 en utilisant le Concept: classe
structurée.
Reportez-vous aux Différences entre UML 1.x et UML 2.0 pour plus d'informations.
|
Etapes
Identification des événements et des signaux
Objet
|
Identifier les événements internes et externes et les signaux auxquels doit répondre le système.
|
Les événements sont des occurrences internes et externes qui engendrent une action dans le système. Les événements
et leurs caractéristiques peuvent permettre de guider l'identification des éléments de conception clés, tels que
les classes actives.
Il est possible d'extraire une liste initiale d'événements externes à partir du modèle de cas d'utilisation et des
interactions des acteurs avec les cas d'utilisation. Les événements internes peuvent provenir du texte des flux de
cas d'utilisation, ou être identifiés au fil de l'évolution de la conception.
Les caractéristiques importantes des événements sont les suivantes :
-
Interne ou externe - L'événement est-il interne ou externe ?
-
Priorité - L'événement doit-il causer la suspension d'autres processus pour pouvoir être traité ?
-
Fréquence - A quelle fréquence se produit l'événement ?
-
Distribution de la fréquence - L'événement se produit-il à intervalles réguliers ou de manière sporadique ?
-
Exigences en termes de réponse - A quelle vitesse le système doit-il réagir à l'événement (il faudra
éventuellement faire la distinction entre la moyenne et le pire des cas) ?
-
Type - S'agit-il d'un événement d'appel, temporel, de signal ou de changement (voir Concept : Evénements et signaux pour en connaître les définitions) ?
Les caractéristiques des événements doivent être enregistrées selon les besoins pour guider l'identification des
éléments de conception qui les traitent. L'enregistrement de ces caractéristiques tend à être plus important dans
les systèmes réactifs (commandés par les événements), mais il peut s'avérer utile dans d'autres systèmes, comme
ceux qui utilisent des accès concurrents et/ou des messages asynchrones.
Les événements de communication asynchrones peuvent être modélisés sous forme de signaux pour exprimer les données
contenues ou les relations entre les signaux, comme la généralisation. Dans certains systèmes, en particulier dans
les systèmes réactifs, il est important d'associer les signaux reçus par des unités externes à des mécanismes
spécifiques, tels que des interruptions ou des messages d'interrogation spécifiques.
|
Identification des classes, des classes actives et des sous-systèmes
Objet
|
Affiner les classes d'analyse en éléments de modèle de conception appropriés
|
Identifiez les classes. Lorsque la classe d'analyse est simple et qu'elle représente déjà une seule abstraction
logique, elle peut être directement mappée un à un à une classe de conception. Habituellement, les classes
entité restent relativement intactes lors du passage à la conception. Ces classes étant aussi généralement
persistantes, déterminez si la classe de conception doit être persistante et faites-en la remarque dans la description
de classe.
Lors de leur identification, les classes doivent être regroupées dans des Produits
: Packages de conception, à des fins d'organisation et de gestion de la configuration. Voir Instructions relatives au produit : Package de conception pour plus d'informations
sur les décisions relatives au regroupement par packages.
Identifiez les classes actives. Abordez les exigences liées aux accès concurrents du système sous l'angle des
objets d'analyse identifiés : le système doit-il répondre à des événements générés de manière externe ? Si oui, quelles
classes d'analyse sont "actives" lorsque l'événement se produit ? Les événements externes du modèle de cas
d'utilisation sont représentés par des stimuli provenant d'acteurs qui interagissent avec un cas d'utilisation.
Examinez les réalisations de cas d'utilisation correspondantes pour voir quels sont les objets qui interagissent
lorsqu'un événement se produit. Commencez par regrouper les objets dans des ensembles autonomes d'objets collaborants ;
ces regroupements constituent une première division dans un groupe susceptible de former une classe active composite.
Si les événements possèdent des attributs importants qui doivent être enregistrés, envisagez de les modéliser en tant
que classes, <<signaux>> stéréotypés. Dans les systèmes en temps réel, ces ensembles d'objets identifiés
doivent être regroupés dans des capsules, qui ont une très forte sémantique d'encapsulation.
Les instances de classes actives représentent des unités d'exécution "logiques" indépendantes. Ces unités d'exécution
"logiques" ne doivent pas être confondues avec ou littéralement mappées aux unités d'exécution du système
d'exploitation (même si le moment viendra où nous les mapperons à ces unités). Elles représentent au contraire des
unités d'exécution conceptuelles indépendantes dans l'espace de solution. Leur identification à ce stade de la
conception a pour but de permettre le partitionnement de la solution en unités indépendantes selon les "coutures"
naturelles du système liées aux accès concurrents. La division du travail ainsi obtenue simplifie conceptuellement les
problèmes de gestion de l'accès concurrent, puisque les unités d'exécution indépendantes peuvent être traitées
séparément, à moins qu'elles ne partagent des classes passives sous-jacentes.
En général, une classe active doit être envisagée à chaque fois qu'il existe des accès concurrents ou des conflits
entre les accès concurrents dans le domaine concerné. Une classe active doit servir à représenter un objet concurrent
ou une activité concurrente externes dans l'ordinateur. Elle donne ainsi la possibilité de suivre et de contrôler les
activités concurrentes.
Un autre choix naturel consiste à utiliser les classes actives comme des représentants internes ou des unités
physiques externes connectés à un ordinateur, puisque ces entités physiques sont concurrentes par nature. Ces
classes de "pilote de périphérique" servent non seulement à suivre et à contrôler les unités physiques correspondantes,
mais également à isoler le reste du système des spécificités de ces unités. Ainsi, le reste du système peut ne pas être
affecté lorsque la technologie des unités évolue.
Communément, les classes actives servent également à représenter les activités concurrentes logiques. Une activité
logique désigne un "objet" concurrent conceptuel, tel que, par exemple, une transaction financière ou un appel
téléphonique. Bien que que ces activités ne se manifestent pas directement en tant qu'entités physiques (même si elles
ont lieu dans le monde physique), elles ont souvent des raisons d'être traitées comme telles. Par exemple, il peut être
nécessaire de suspendre momentanément une transaction financière particulière afin d'éviter un conflit d'accès
concurrents, ou de l'abandonner en raison de défaillances dans le système. Ces objets conceptuels devant être manipulés
en tant qu'unités, il convient de les représenter comme des objets qui possèdent leurs propres interfaces offrant les
capacités fonctionnelles appropriées.
Le contrôleur d'objets actifs est un exemple particulier de ce type d'objet conceptuel. Son but est de gérer en
permanence un ou plusieurs autres objets actifs. Il s'agit en principe de porter chaque objet à l'état opérationnel
souhaité, de le maintenir dans cet état malgré les différentes perturbations, telles qu'une défaillance partielle, et
de synchroniser son opération avec celle d'autres objets. Ces contrôleurs d'objets actifs évoluent souvent à partir des
objets de contrôle identifiés lors de la Tâche : Analyse
des cas d'utilisation.
En raison de leur capacité à résoudre les conflits d'accès concurrents de manière simple et élégante, les classes
actives sont également très utiles en tant que gardiennes des ressources partagées. Dans ce cas, une ou
plusieurs ressources requises par plusieurs activités concurrentes sont encapsulées dans une classe active. En vertu de
leur sémantique intégrée d'exclusion mutuelle, de telles gardiennes protègent automatiquement ces ressources des
conflits d'accès concurrents.
Pour les systèmes en temps réel, vous devez utiliser les capsules à la place des classes actives : partout où vous
avez identifié la nécessité d'une classe active, conformément à la méthode heuristique décrite ci-dessus, vous devez y
substituer une capsule.
Identifiez les sous-systèmes. Lorsque la classe d'analyse est complexe, incarnant un comportement qu'une classe
de conception unique ne peut gérer seule, elle doit être mappée à un sous-système de conception. Le sous-système de
conception sert à encapsuler ces collaborations de façon à ce que ses clients ignorent totalement la conception interne
du sous-système, même lorsqu'ils utilisent les services qu'il fournit.
Un sous-système est modélisé sous la forme d'un composant UML qui ne contient que des interfaces comme éléments
publics. Les interfaces constituent une couche d'encapsulation qui permet à la conception interne du sous-système de
rester invisible pour les autres éléments de modèle. Le concept de sous-système permet de distinguer ce dernier des
packages, qui sont des conteneurs d'éléments de modèle sans sémantique.
La décision de créer un sous-système à partir d'un ensemble de classes d'analyse collaborantes repose en grande partie
sur le fait de savoir si la collaboration pourra être ou sera développée séparément par une équipe de conception
indépendante. Si les collaborations peuvent être entièrement contenues dans un package avec les classes collaborantes,
un sous-système peut offrir une forme d'encapsulation plus solide que celle d'un simple package. Le contenu et les
collaborations à l'intérieur d'un sous-système sont totalement isolés derrière une ou plusieurs interfaces ; de cette
façon, le client du sous-système ne dépend que de l'interface. Le concepteur du sous-système est donc complètement
isolé des dépendances externes ; le concepteur (ou l'équipe de conception) doit définir la façon dont l'interface est
réalisée, mais il peut modifier la conception interne du sous-système sans affecter les dépendances externes. Dans les
grands systèmes avec des équipes très indépendantes, ce degré de découplage ainsi que l'exécution architecturale des
interfaces formelles sont de solides arguments pour choisir des sous-systèmes plutôt que de simples packages. Voir
aussi Instructions relatives au produit : Sous-système de conception pour plus
d'informations sur les facteurs qui motivent l'utilisation de sous-systèmes en tant qu'éléments de conception.
|
Identification des interfaces des sous-systèmes
Objet
|
Identifier les éléments de conception qui formalisent les coutures du système.
|
Les interfaces définissent un ensemble d'opérations réalisées par un discriminant. Dans le modèle de conception, elles
servent essentiellement à définir les interfaces pour des sous-systèmes. Certes, elles peuvent être utilisées pour des
classes également, mais il suffit généralement de définir les opérations publiques sur une classe pour en définir son
"interface". Les interfaces sont importantes pour les sous-systèmes, car elles permettent d'effectuer la distinction
entre la déclaration du comportement (l'interface) et la réalisation de ce comportement (les classes spécifiques du
sous-système qui réalisent l'interface). Ce découplage permet d'accroître l'indépendance des équipes de développement
qui travaillent sur différentes parties du système, tout en gardant des définitions précises des "contrats" qui lient
ces différentes parties.
Pour chaque sous-système, identifiez un ensemble d'interfaces candidates. A l'aide des collaborations regroupées
identifiées lors de l'étape précédente, identifiez la responsabilité qui est "activée" lorsque la collaboration est
initiée. Ensuite, pour préciser cette responsabilité, déterminez quelles sont les informations qui doivent être
fournies par le "client" et celles qui sont renvoyées lorsque la collaboration est achevée. Ces ensembles
d'informations deviennent les paramètres d'entrée et de sortie et la valeur de retour du prototype pour une opération
que le sous-système va réaliser. Spécifiez un nom pour cette opération, à l'aide des conventions de dénomination
définies dans le Produit : Instructions relatives au projet. Répétez cette étape
jusqu'à ce que soient définies toutes les opérations que le sous-système réalisera.
Ensuite, regroupez les opérations selon leurs responsabilités associées. Les plus petits groupes sont préférables aux
plus grands. En effet, dans un groupe, lorsque le nombre d'opérations est plus petit, la cohésion de l'ensemble de
responsabilités communes a plus de chance d'être forte. Ayez également toujours en vue les possibilités de
réutilisation ; recherchez des similitudes qui pourraient faciliter l'identification des fonctionnalités associées
réutilisables. Toutefois, ne passez pas trop de temps à chercher le regroupement idéal de responsabilités.
Souvenez-vous qu'il s'agit seulement d'un premier classement que vous améliorerez de manière itérative tout au long de
la phase d'élaboration.
Recherchez des similitudes entre les interfaces. A partir de l'ensemble d'interfaces candidates, recherchez des
noms, responsabilités et opérations semblables. Lorsque les mêmes opérations existent dans plusieurs interfaces,
refactorisez ces dernières en extrayant les opérations communes vers une nouvelle interface. Ne négligez pas non plus
les interfaces existantes, en les réutilisant dans la mesure du possible. Le but est de maintenir la cohésion des
interfaces tout en supprimant les opérations redondantes entre elles. Cette étape facilitera la compréhension des
interfaces et leur évolution dans le temps.
Définissez des dépendances d'interface. Les paramètres et la valeur de retour de chaque opération d'interface
ont chacun un type particulier : ils doivent réaliser une interface particulière ou doivent être des instances d'un
type de données simple. Lorsque les paramètres sont des objets qui réalisent une interface particulière, définissez des
relations entre cette interface et les interfaces dont elle dépend. Définissez des dépendances entre les interfaces qui
fournissent des informations de couplage utiles à l'architecte logiciel, car les dépendances d'interface définissent
les principales dépendances entre les éléments du modèle de conception.
Mappez les interfaces aux sous-systèmes. Après avoir identifié les interfaces, créez des associations de
réalisation entre le sous-système et les interfaces qu'il réalise. Une réalisation depuis le sous-système vers
une interface indique qu'un ou plusieurs éléments du sous-système réalisent les opérations de cette interface. Plus
tard, une fois le sous-système conçu, ces réalisations interface/sous-système seront précisées, lorsque le concepteur
du sous-système définira les éléments spécifiques qui réaliseront les opérations de l'interface. Ces réalisations
précisées ne sont visibles que pour le concepteur ; pour le client du sous-système, seule la réalisation
interface/sous-système est visible.
Définissez le comportement spécifié par les interfaces. Les interfaces définissent souvent une machine d'état
implicite pour les éléments qui réalisent l'interface. Si les opérations sur l'interface doivent être appelées dans un
ordre particulier (par exemple, il faut ouvrir une connexion à une base de données avant de pouvoir l'utiliser), vous
devez définir une machine d'état qui illustre les états visibles publiquement (ou induits) que doit prendre en charge
tout élément de conception qui réalise l'interface. Cette machine d'état aidera l'utilisateur de l'interface à mieux
comprendre cette interface, et le concepteur des éléments qui réalisent l'interface à leur donner le bon comportement.
Regroupez les interfaces en packages. Le propriétaire des interfaces est l'architecte logiciel ; les changements
apportés aux interfaces sont toujours importants pour l'architecture. Pour gérer cette situation, les interfaces
doivent être regroupées en un ou plusieurs packages dont l'architecte logiciel est le propriétaire. Si chaque interface
est réalisée par un seul sous-système, les interfaces peuvent être placées dans le même package avec le sous-système.
Si les interfaces sont réalisées par plus d'un sous-système, elles doivent être placées dans plusieurs packages en
possession de l'architecte logiciel. Ainsi, les interfaces peuvent être gérées et contrôlées indépendamment des
sous-systèmes.
Objet
|
Identifier les éléments de conception qui formalisent les coutures du système (conception en temps réel
uniquement).
|
Dans les systèmes commandés par les événements, les protocoles sont semblables aux interfaces : ils identifient le
"contrat" qui lie les capsules entre elles en définissant un ensemble de signaux correspondants, utilisés pour
communiquer entre les unité d'exécution de contrôle indépendantes. Tandis que les interfaces servent essentiellement à
définir la messagerie synchrone à l'aide d'une fonction d'appel, les protocoles, eux, servent essentiellement à définir
la communication asynchrone à l'aide d'une technique de messagerie par signaux. Les protocoles permettent d'effectuer
la distinction entre la déclaration du comportement (l'ensemble de signaux) et la réalisation de ce comportement (les
éléments du sous-système qui réalisent l'interface). Ce découplage permet d'accroître l'indépendance des équipes de
développement qui travaillent sur différentes parties du système, tout en gardant des définitions précises des
"contrats" qui lient ces différentes parties.
Pour chaque capsule, identifiez un ensemble de signaux d'entrée et de sortie. A l'aide des collaborations
regroupées identifiées au cours d'étapes antérieures, identifiez la responsabilité qui est "activée" lorsque la
collaboration est initiée. Ensuite, pour préciser cette responsabilité, déterminez quelles sont les informations qui
doivent être fournies par le "client" et celles qui sont renvoyées lorsque la collaboration est achevée. Ces ensembles
d'informations deviennent les paramètres d'entrée du prototype pour un signal que la capsule va réaliser par l'un de
ses ports. Spécifiez un nom pour ce signal, à l'aide des conventions de dénomination définies dans le Produit : Instructions relatives au projet. Répétez cette étape
jusqu'à ce que soient définis tous les signaux que la capsule réalisera.
Ensuite, regroupez les signaux selon leurs responsabilités associées. Les plus petits groupes sont préférables aux plus
grands. En effet, dans un groupe, lorsque le nombre de signaux est plus petit, la cohésion de l'ensemble de
responsabilités communes a plus de chance d'être forte. Ayez également toujours en vue les possibilités de
réutilisation ; recherchez des similitudes qui pourraient faciliter l'identification des fonctionnalités associées
réutilisables. Toutefois, ne passez pas trop de temps à chercher le regroupement idéal de responsabilités.
Souvenez-vous qu'il s'agit seulement d'un premier classement que vous améliorerez de manière itérative tout au long de
la phase d'élaboration. Donnez au protocole un nom significatif, décrivant le rôle qu'il joue dans les collaborations
de capsule.
Recherchez des similitudes entre les protocoles. A partir de l'ensemble de protocoles candidats, recherchez des
noms, responsabilités et signaux semblables. Lorsque les mêmes signaux existent dans plusieurs protocoles, refactorisez
ces derniers en extrayant les signaux communs vers un nouveau protocole. Ne négligez pas non plus les protocoles
existants, en les réutilisant dans la mesure du possible. Le but est de maintenir la cohésion des protocoles tout en
supprimant les signaux redondants entre eux. Cette étape facilitera la compréhension des protocoles et leur évolution
dans le temps.
Mappez les protocoles aux sous-systèmes. Après avoir identifié les protocoles, créez des ports sur les
capsules qui les réalisent. Les ports d'une capsule définissent ses "interfaces", c'est-à-dire le comportement qui peut
lui être demandé. Plus tard, une fois la capsule conçue, le comportement spécifié par les ports sera décrit par la
machine d'état pour cette capsule.
Définissez le comportement spécifié par les protocoles. Les protocoles définissent souvent une machine d'état
implicite pour les éléments qui réalisent l'interface. Si les signaux d'entrée sur l'interface doivent être reçus dans
un ordre particulier (par exemple, il faut recevoir un signal "système prêt" avant de pouvoir recevoir un signal
d'erreur particulier), vous devez définir une machine d'état qui illustre les états visibles publiquement (ou induits)
que doit prendre en charge tout élément de conception qui réalise le protocole. Cette machine d'état aidera
l'utilisateur des capsules à mieux les comprendre, et le concepteur de ces capsules à donner le bon comportement à
leurs éléments.
Regroupez les protocoles en packages. Le propriétaire des protocoles est l'architecte logiciel ; les changements
apportés aux protocoles sont toujours importants pour l'architecture. Pour gérer cette situation, les protocoles
doivent être regroupés en un ou plusieurs packages dont l'architecte logiciel est le propriétaire. Ainsi, les
protocoles peuvent être gérés et contrôlés indépendamment des capsules qui les réalisent.
|
|
Propriétés
Plusieurs occurrences |  |
Commandé par les événements |  |
En cours |  |
Facultatif |  |
Planifié |  |
Réitérable |  |
Plus d'informations
Listes de contrôle |
|
Concepts |
|
Instructions |
|
Guides d'utilisation de l'outil |
|
© Copyright IBM Corp. 1987, 2006. All Rights Reserved.
|
|