- Le diagramme de classes - |
|
L'obtention du diagramme des classes du prototype courant s'effectuera de deux façons selon que l'on développe le premier prototype ou les suivants.
Cas du premier prototypeEn partant du diagramme des classes métier global, on détermine le sous-diagramme correspondant aux classes utilisées par le premier prototype. Les classes ou les paquetages non nécessaires sont provisoirement éliminés afin de simplifier le diagramme. Les relations qui lient les classes restantes aux classes éliminées sont elles-mêmes éliminées. Tous les attributs découverts lors de la conception globale sont insérés dans les classes, et de nouveaux peuvent être ajoutés en fonction des résultats de la phase précédente (définition du prototype). Seules les méthodes correspondant aux fonctions mises en œuvre dans le prototype sont ajoutées dans les classes correspondantes. Une classe d'interface est une classe abstraite dont toutes les méthodes sont abstraites. C'est le cas des Interfaces Java. Elle définit un type et un comportement par les prototypes des méthodes qui constituent l'interface. Application du principe d'ouverture/fermetureLa structuration du premier prototype est déterminante pour le développement des prototypes suivants afin de respecter au mieux la Règle de Non Régression des prototypes (RNR) qui est l'un des moyens proposés par MACAO pour faire respecter le principe général d'ouverture/fermeture Open-Closed Principle (OCP).
Pour améliorer la lisibilité de l'ensemble il est conseillé de préfixer le nom des interfaces par "I_" et de les placer toutes dans un package spécialisé. L'exemple ci-dessous montre un exemple de classes métier du protype 1 dérivées dans le prototype 2.
Dans le prototype 2 et les suivants, les références aux objets de type "ClasseMétier" se feront toujours en utilisant le nom de l'interface "I_ClasseMétier". Lors de l'ajout d'une méthode dans une classe dérivée dans un nouveau prototype, on devra rajouter sa signature dans l'interface et, par voie de conséquences, on devra également ajouter la méthode avec un corps vide dans chacune des classes qui implémentent cette interface. Remarquons que ceci constitue une dérogation à la RNR mais qui pourra se faire de façon quasi-automatique grâce aux possibilités de l'atelier de développement utilisé (Eclipse, Netbeans...). La figure ci-dessous illustre ce dernier cas :
Un cas plus complexe peut se produire lorsqu'une classe métier du prototype 1 est elle-même dérivée en plusieurs sous-classes. La modification des sous-classes de niveau le plus bas dans l'arbre d'héritage suivra le même principe que ci-dessus. Chacune des classes de l'arbre d'héritage implémentera une interface. L'ensemble des interfaces ainsi constitué sera structuré selon un arbre d'héritage identique à celui des classes d'objets. Exemple de structuration d'un arbre d'héritage dont les classes terminales sont dérivées dans le prototype 2 :
Nous énoncerons alors ici une première dérogation à la RNR
Toute modification apportée à une classe située à un noeud ou à la racine de l'arbre d'héritage (classe mère) s'effectuera directement dans la classe elle-même (sans dérivation). Toutes les classes mères d'un arbre d'héritage ne seront donc jamais dérivées dans les nouveaux prototypes. Ceci est dû au fait que les classes dérivées ne peuvent être dérivées à la fois de la nouvelle classe mère et des anciennes classes filles car cela reviendrait à réaliser un héritage multiple qui n'est pas recommandé et qui est surtout interdit dans des langages tels que Java. De ce fait, si une classe mère doit être modifiée dans un prototype recetté (ajout ou modification d'une méthode par exemple), il faudra enfreindre la RNR pour l'effectuer. Pour limiter cet inconvénient, il est fortement recommandé de répartir les méthodes le plus possible dans les classes filles et ne garder dans les classes intermédiares que les méthodes et attributs réellement communs aux classes dérivées. SI, malgré tout, une modification doit être faite sur une classe déjà recettée, cela est pris en compte par MACAO en permettant à l'équipe de développement d'émettre des DRNR (Dérogation à la Règle de Non-Regression). En fait, une DRNR permet aussi bien d'apporter une modification fonctionnelle à un prototype recetté que de réaliser une opération de refactoring afin de restructurer un module en lui appliquant un design pattern approprié (Strategy, Abstract Factory, Visitor...) ou en rajoutant simplement une classe d'interface permettant de casser une dépendance. Parmi tous les Design Patterns (DP) proposés par le GOF (Gang Of Four) ou par SUN (Design patterns J2EE), nous en retiendrons deux qui permettront de limiter considérablement les effets de dépendance des classes métier. Il s'agit des DP Stratégie (Strategy) et Fabrique Abstraite (Abstract Factory) du GOF.- Stratégie est un DP comportemental qui permet d'encapsuler dans une nouvelle classe une famille d'algorithmes interchangeables. Ce DP permet d'étendre les possibilités d'une classe au niveau d'un prototype ultérieur. Il nécessite cependant d'avoir bien analysé le problème afin de mettre en évidence les algorithmes qui évolueront au cours des prototypes suivants mais sans avoir besoin de connaître dès le départ quelles seront les évolutions exactes.A titre d'exemple, supposons que dans notre projet "Assurance automobile", la méthode d'affichage d'un contrat soit envisagée très simplement dans le premier prototype mais que l'on veuille, dans un des prototypes suivants (par exemple le deuxième) l'enrichir en affichant également la liste des véhicules assurés dans le contrat (application du pattern d'IHM Liaison - composition). Au lieu de dériver la classe complète Contrat_1 en Contrat_2 afin de changer la méthode d'affichage, il sera plus performant d'appliquer le DP Stratégie en déportant la méthode d'affichage d'un contrat dans une nouvelle classe munie d'une interface appropriée afin d'uniformiser son utilisation dans divers prototypes. L'interface "StrategyAffichContrat" donne accès à deux méthodes d'affichage, la méthode simple dans le prototype 1 et la méthode avec véhicules assurés dans le prototype 2. Reprenons l'exemple de l'assurance automobile en gardant les classes Contrat, Véhicule et Dossier. Les classes Contrat et Véhicule sont utilisées dans le prototype 1 alors que la classe Dossier n'est utilisée qu'à partir du prototype 2. La classe Vehicule est modifiée dans le prototype 2. Une interface de fabrique générale "Fabrique" a été définie dans le prototype 1 et est implémentée au niveau de chaque prototype pour fabriquer tous les objets métier qui y sont utilisés (FabriqueProto_1, FabriqueProto_2...). Les interfaces de chaque classe d'objets métier sont dérivées d'un interface générale "ObjetMétier". Leur implémentation s'effectue dans le prototype adéquat. Cas des autres prototypesLa conception des classes des prototypes suivants s'effectuera toujours en fonction des prototypes précédents. Toute évolution d'une classe déjà présente dans l'un des prototypes recettés sera réalisée par spécialisation de la classe existante sauf s'il existe de trop fortes dépendances qui obligeraient à dériver plusieurs autres classes. |
![]() |




