Vous êtes ici : Accueil UML L'analyse et la conception architecturale

L'analyse et la conception architecturale

 

Documents

Documents collectés :

La phase d'analyse peut commencer avec tout document équivalent à celui que nous venons de décrire de la capture des besoins fonctionnels et techniques.

Documents livrés :

A l'issue de la phase d'analyse nous serons en mesure de livrer un modèle complet de l'architecture du système.

Transition de la capture des besoins à l'analyse :

CaptureBesoinVersAnalyse.jpgPréparation de la phase de réalisation

La phase d'analyse ne consiste pas à réaliser le projet dans ces moindres détails mais afin d'être efficace et de vérifier que cette réalisation sera possible il est bon de prendre des précautions dès le début de la phase d'analyse.

Préparation de la chaine de production :

  • Environnement de modélisation.
  • Environnement de compilation et d'exécution.
  • Plateforme de test.
  • Règles de nommage des classes, des attributs, des messages et des versions de projet.
  • Procédures de stockage des versions
  • Test de la chaine de production sur un exemple basique « Hello World ».

Démarche d'analyse pour conception d'une architecture Objet.

L'analyse va être de plus en plus fine mais il faut une fois de plus éviter de plonger directement dans des solutions techniques connues tout en gardant à l'esprit les contraintes du contexte dans lequel l'application va être développée.

On pourrait traduire cette attitude par « Ne pas mettre la charrue avant les bœufs » tout en gardant à l'esprit les contraintes techniques que les chemins vont imposés à notre charrue et ses bœufs.

Identification des classes candidates

Nous allons maintenant utiliser les différents diagrammes de la phase de capture des besoins et proposer un ensemble de classes qui permettrons de matérialiser informatiquement chacune des entités identifiées durant la capture des besoins.

Notre fil conducteur sera l'ensemble des besoins exprimés durant la capture des besoins. Nous allons reprendre chaque cas d'utilisation avec son ou ses diagrammes de séquence, d'activité et d'état,  afin d'identifier tous les concepts informatique qu'ils révèlent.

Chaque cas d'utilisation contient un vocabulaire et des mécanismes que nous devons maintenant projeter à travers des entités informatiques.

Il faudra durant notre analyse distinguer les classes de représentation des données qui seront dans la base de donnée (qui ne comportent que des attributs) et les classes qui vont constituer la partie logiciel du projet (qui comportent des attributs et des méthodes).

Certains commencent par une représentation des données et passent ensuite à une représentation logicielle.

D'autres font une représentation globale sans distinguer les données et le logiciel et affinent ensuite progressivement leur modèle pour distinguer les données des programmes.

Il ne faut pas se tromper, les classes que nous allons identifier ne fournissent qu'une représentation statique du système. Cependant, nous devons garder à l'esprit que chaque classe va se composer d'un ensemble d'attributs et éventuellement d'opérations qui seront utilisés dans la descriptions dynamique du système.

Chaque classe pourra être affinée par un diagramme d'état et/ou un diagramme d'activité qui va décrire son fonctionnement dynamique. Les diagrammes dynamiques vont utiliser les opérations des classes et vont aussi générer des opérations dans le cas des diagrammes de séquence.

Nous pouvons donc garder tout ça à l'esprit bien que notre objectif dans cette phase soit simplement de vérifier pour chaque classe candidate les points suivants :

  • Quels sont ses attributs. Une classe sans attributs ressemble plus à une interface décrivant des traitements possibles.
  • Quel est son métier, sa responsabilité. Si cette classe présente de trop nombreuses responsabilités c'est peut-être parce qu'elle est trop compliquée. Il faudra alors peut-être la décomposer.

Durant la phase d'identification des classes il est aussi possible de détecter des redondances ou des similarités dans les attributs des classes. Il est alors intéressant d'étudier la possibilité de faire des héritages.

Enfin, durant la phase d'identification des classes il y a un certain nombre d'associations qui semblent nécessaires et il ne faut pas se priver de les créer.

En effet, à ce stade de l'analyse, il faut travailler avec l'esprit ouvert en restant conscient que certaines classes et associations identifiées dans cette phase vont disparaitre et d'autres vont apparaître plus tard.
Habituellement la technique du « brain storming » est assez efficace pour mener cette phase.

Dans l'exemple ci-dessous nous avons une première approche des classes et des associations utilisées pour la création d'un devis. On remarquera qu'à l'occasion de cette analyse nous avons ajouté une association entre « Article » et « CompteSociete » afin de matérialiser la relation fournisseur.

Cette proposition est peut-être un peu précoce dans le processus d'analyse car il faudra peut-être distinguer une classe « Client » d'une classe « Fournisseur » héritant chacune d'une classe mère « Societe » qui fournissent tous les attributs génériques d'une société.
Nous commencerons cependant par cette proposition que nous affinerons si besoin.
                             IdentificationClassesBis.jpg

Les différents entretiens avec le client nous portent à modéliser la gestion des produits comme représenté ci-dessous.

Ce diagramme modélise la notion de produit à la fois pour le service commercial, la production, les stocks, les approvisionnements et tout le reste de l'entreprise.

IdentificationClassesTer.jpg

 Afin de valider le diagramme nous l'avons confronté aux besoins de chaque service afin de nous assurer qu'il réponde à l'ensemble des besoins de l'entreprise.

Répartition des classes en packages

Une fois les différentes classes identifiées nous procédons à un regroupement en Packages.
Un Package est un contenant au même titre que les dossiers de votre ordinateur. Le Package définit un espace de nom et une unité organisationnelle.

L'organisation du modèle en package doit permettre une bonne modularité générale du système et ainsi une bonne répartition des développements.
L'organisation en package répond souvent au principe d'une architecture 3 tiers qui sépare clairement la partie « IHM » (Interface Homme Machine) de la partie « Métier » qui met en œuvre les mécanismes métier de l'entreprise et enfin la partie « Base de données » qui fournit les mécanismes d'accès et de stockage des données.

Ce type d'architecture permet de faire évoluer distinctement l'IHM et/ou le métier et/ou la base de donnée sans remettre en question les autres niveaux.
Nous retrouvons ce principe de décomposition en couches par exemple dans le modèle réseau OSI.

Ci-dessous dans une architecture 3 tiers on définit une dépendance bi-directionnelle entre « IHM » et « Metier » ce qui va nous donner des contraintes réciproques sur les 2 packages qui seront exprimées dans les interfaces d'accès aux packages.

Inversement le package « BDD » n'a aucune dépendance sur le package « Metier » donc les modifications que nous apporterons à « Metier » n'auront pas d'impact sur « BDD ». En revanche le package « BDD » devra répondre aux besoins de « Metier ».
                                       Architecture3Tiers.jpg

Pour notre projet nous avons défini que nous utiliserions une base de données MySQL et une interface graphique la plus générique possible.
Nous ne rentrons pas dans le détail de l'interface graphique ni dans celui de la base de donnée pour nous concentrer sur les besoins de la partie métier.
Nous avons ainsi regroupé ci-dessous quelques classes pour illustrer la répartition des classes dans une architecture 3 tiers.

                                         IdentificationPackages2.jpg

Définition des interfaces entre packages

Le concept d'interface est au cœur du concept objet et donc au cœur de la modélisation UML.

La notion d'interface peut être utilisée pour 2 objectifs différents. Soit on utilise l'interface pour définir le contrat d'utilisation d'un package. Soit on utilise l'interface comme un type d'objet générique.

L'interface d'encapsulation

Nous allons d'abord étudier l'interface utilisée pour encapsuler un package.
En effet, les attributs d'une classe doivent être encapsulés dans la classe et accessibles uniquement par l'intermédiaire des opérations publiques.
Les traitements que peut proposer une classe ne sont accessibles qu'à travers les opérations et messages publics que cette classe peut traiter.
Nous allons dans le même esprit définir pour les packages des interfaces qui auront ce rôle d'encapsulation des classes du package vis à vis du reste du système. Cela constitue une couche supplémentaire qui facilite le regroupement des entités.
Les fonctionnalités que le package offre sont ainsi définies dans une ou plusieurs interfaces visibles et accessibles par le reste du système.
Une fois les interfaces définies, il ne faut plus supprimer les fonctionnalités publiées dans ces dernières mais il est possible d'en proposer de nouvelles que les autres parties du système pourront utilisées ou pas.
En revanche l'intérieur du package qui réalise les différentes fonctionnalités listées dans les packages peuvent être modifiées à volonté dans la mesure ou elles proposent toujours les même fonctionnements.
La définition des interfaces aura donc un rôle majeur dans la maintenabilité et l'évolutivité du système.
Dans la représentation ci-dessous nous avons « IClasseMetier » représenté au format UML 1.x avec le rectangle et le stéréotype « interface » et au format UML 2.x avec les connecteurs en sphère et demi-sphère.
Le diagramme ci-dessous réalisé avec StarUML en notation UML 1.X et UML 2.x ne permet pas d'afficher les opérations de l'interface. L'interface « IClasseMetier » est réalisée par « ClasseMetier » et requise par « ClasseIHM ».

InterfacePackage.png

Selon les langages, une interface UML est une classe ne contenant que des méthodes abstraites comme en C++ ou une interface comme en Java. Le concept reste cependant tout à fait valable dans tous les langages même s'il n'existe pas de façon officielle comme en C ou en Assembleur.

La représentation détaillée de « IclasseMetier » pourrait être celle-ci.

IClasseMetier.png

L'interface d'abstraction

Dans notre exemple nous avons défini que nous ne souhaitions pas rendre la couche « Metier » complètement indépendante des couches « IHM » et « BDD ». Cependant il va bien falloir échanger des structures de données entre ces couches.
Nous allons donc définir des structures de données génériques que nous allons regrouper comme ci-dessous dans un package utilitaire et qui vont constituer les bases d'échange entre la couche « Metier » et les autres couches.

InterfaceAbstraction.png

 Enrichissement et validation du modèle candidat

A ce stade de l'étude nous disposons toujours des éléments collectés durant la capture des besoins qui constituent notre base de départ à toute réflexion, mais nous disposons maintenant d'un début d'architecture « candidate » que nous devons valider et enrichir pour nous diriger vers la réalisation.

Nous allons donc reprendre notre base c'est à dire les cas d'utilisation de la capture des besoins avec toutes leurs descriptions dynamiques et nous allons projeter dans notre début de modèle chacun des cas d'utilisation un par un pour valider et enrichir le modèle.

Cet exercice va obligatoirement faire apparaître des concepts que nous avons oublié et faire disparaître des concepts que nous avions jugé bons durant l'identification des classes candidates.

Ci-dessous nous reprenons les cas d'utilisation identifiés pour la partie commerciale et nous allons simplement essayé de traiter la réception de la demande de prix.

UseCaseEnrichissementModele.jpg

 

  Ci-dessous le diagramme d'activité qui résume le processus de réception d'une demande de prix client et qui traite cette demande de prix jusqu'à l'émission d'un devis client.
Ce diagramme ne présente pas les différentes actions internes à chaque activité mais chaque activité est elle même constituée d'une suite d'actions.
ActiviteEnrichissementModele.jpg

Nous constatons alors que la capture des besoins nous a fait associer différentes fonctionnalités à travers les diagrammes d'activité.
Nous allons nous servir de ces imbrications des cas d'utilisation qui apparaissent dans l'analyse des processus de notre client pour valider notre modèle.
Nous avons identifié pour l'enregistrement de la demande de prix client les classes ci-dessous :     
                          ClassesCandidatesEnrichissementModele.jpg

Voici maintenant ce que cela pourrait produire si nous projetons dans un diagramme de séquence l'une des suites possibles des opérations réalisées par l'assistante commerciale qui enregistre la demande de prix.

SequenceEnrichissementModele.jpg

Cette décomposition des actions menées par l'assistante commerciale à ainsi enrichi le diagramme de classe comme nous pouvons le vérifier ci-dessous.
De plus nous avons commencer à généraliser au niveau des interfaces des packages IHM et BDD les différentes opérations qui seront nécessaires.
ClassesEnrichissementModele.jpg

En procédant ainsi de façon systématique sur chaque cas d'utilisation nous pouvons progressivement définir l'application dans ces moindres détails.
Il est d'ailleurs souhaitable de générer le code au fur et à mesure de l'analyse et de le compiler afin de vérifier progressivement la cohérence du modèle et éviter d'avoir à reprendre une grande quantité d'éléments quand le modèle est déjà largement avancé.

Enrichissement par les diagrammes d'état et d'activité.

Le processus d'enrichissement, de validation et d'affinage du modèle que nous venons d'illustrer avec le diagramme de séquence est le même avec les diagrammes d'état ou d'activité pour préciser en détail le fonctionnement d'un package, d'une classe ou d'une opération.
Nous garderons toujours comme base de réflexion les schémas de la capture des besoins et nous aurons toujours comme objectif de préciser le modèle pour faciliter son implémentation, sa modularité et sa maintenabilité.

Génération du code de l'architecture.

Nous avons théoriquement généré et compilé le code modélisé tout au long de la phase d'analyse ce qui doit nous fournir à l'issue de cette phase un squelette parfaitement constitué avec :

  • Toutes les dépendances déclarées.
  • Tous les espaces de noms définis.
  • Toutes les opérations et tous les attributs définis.

Il ne nous reste plus qu'à programmer les opérations et les messages qui vont mettre en œuvre notre système.

Actions sur le document
Références
 
Site réalisé et hébergé par www.optragroup.fr