Instructions: Sous-système de conception
Un sous-système de conception implémente le concept de composant logiciel. Ces instructions expliquent comment identifier et définir un sous-système de conception.
Relations
Description principale

Utilisation du sous-système

>Les sous-systèmes peuvent être utilisés de nombreuses manières pour diviser le système en unités qui peuvent :

  • être organisées, configurées ou distribuées de manière indépendante
  • être développées tant que l'interface reste identique
  • être déployées de manière indépendante au travers un ensemble de noeuds informatiques répartis
  • être modifiées de manière indépendante sans endommager d'autres parties du système

Les sous-systèmes sont donc parfaits pour modéliser les composants - les unités de remplacement dans un développement à base de composants - qui sont plus grands qu'une classe de conception unique.

De plus, les sous-systèmes peuvent aussi :

  • diviser le système en unités qui peuvent garantir une sécurité restreinte des ressources clés.
  • représenter des produits existants ou des systèmes externes dans la conception.

Identification des sous-systèmes

Une classe d'analyse complexe est mappée à un sous-système de conception si elle incarne un comportement qu'une classe de conception unique ne peut gérer seule. Une classe de conception complexe peut aussi devenir un sous-système si elle peut être implémentée comme un ensemble de classes qui collaborent.

Les sous-systèmes sont aussi un bon moyen d'identifier les parties du système à faire développer de manière indépendante par une autre équipe. Si les éléments de conception qui collaborent peuvent être entièrement contenus dans un package avec leurs collaborations, un sous-système apporte cependant une forme plus solide d'encapsulation qu'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.

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. Si les classes ou les sous-systèmes d'une collaboration interagissent uniquement pour produire un ensemble de résultats bien défini, la collaboration et ses éléments de conception qui collaborent doivent être encapsulés dans le sous-système.

Cette règle s'applique aussi aux sous-ensembles de collaboration. Vous pouvez encapsuler une partie ou la totalité de la collaboration, cela rendra la conception plus facile à comprendre.

Conseils

Conseils

Comment procéder

Cherchez l'optionalité Si une collaboration (ou sous-collaboration) particulière représente un comportement facultatif, incluez-la dans un sous-système. Les fonctions qui peuvent être supprimées, mises à jour ou remplacées doivent être considérées comme indépendantes.
Faites attention à l'interface utilisateur du système. Si l'interface utilisateur est relativement indépendante vis à vis des classes entité du système (les deux peuvent changer de manière indépendante et le feront), créez des sous-systèmes intégrés horizontalement : regroupez les classes frontière liées à l'interface utilisateur dans un sous-système et regroupez les classes entité liées dans un autre sous-système.
Si l'interface utilisateur et les classes entité qu'il affiche sont étroitement couplés (un changement dans l'une entraîne un changement dans l'autre), créez des sous-systèmes intégrés verticalement : regroupez les classes frontière et les classes entité liées dans le même sous-système.
Faites attention aux acteurs Séparez les fonctionnalités utilisées par deux différents acteurs, chaque acteur pouvant changer de manière indépendante leurs exigences vis à vis du système.
Créez des sous-systèmes pour encapsuler l'accès aux services et aux dispositifs externes .
Cherchez le couplage et la cohésion entre des éléments de conception Les classes et les sous-systèmes cohésifs ou avec un haut niveau de couplage collaborent pour fournir des ensembles de services. Organisez en sous-systèmes les éléments avec un haut niveau de couplage et séparez les éléments le long de lignes de couplage lâche. Dans certains cas, le couplage lâche peut être complètement supprimé en divisant les classes en classes plus petites avec des responsabilités plus cohésives ou en divisant à nouveau les sous-systèmes correctement.
Prêter attention à la substitution S'il existe plusieurs niveaux de service définis pour une fonction spécifique (par exemple une disponibilité haute, moyenne ou basse), représentez chaque niveau de service comme un sous-système séparé. Chacun d'eux réalisera le même ensemble d'interfaces. En faisant cela, les sous-systèmes sont substituables les uns aux autres.
Prêter attention à la distribution Bien qu'il puisse y avoir des instances multiples d'un sous-système particulier, s'exécutant chacune sur un noeud différent, dans de nombreuses architectures il est impossible pour l'instance unique d'un composant d'être divisée entre des noeuds. Lorsque le comportement d'un sous-système doit être divisé entre des noeuds, il vaut mieux que vous divisiez le sous-système en sous-systèmes plus petits, représentant chacun un composant, avec des une fonctionnalité plus restreinte.   Déterminez la fonctionnalité devant résider sur chaque noeud et créez un nouveau sous-système qui aura cette fonctionnalité et distribuera de manière adéquate les responsabilités et les éléments liés du sous-système original.   Les nouveaux sous-systèmes sont internes au sous-système original.

Une fois que la conception a été organisée en sous-systèmes, il faut mettre à jour les réalisations des cas d'utilisation en conséquence.

Sous-système de modélisation

Les sous-systèmes de conception sont modélisés à l'aide de composants UML. Cette construction offre les fonctions de modélisation suivantes :

  • un regroupement des classes pour définir une partie d'un système avec un niveau de granularité plus élevé
  • une séparation entre les interfaces visibles et l'implémentation interne
  • des exécutions en cours d'exécution

Remarques supplémentaires :

  • On doit donner un nom et une courte description à chaque sous-système de conception.
  • Les responsabilités de la classe d'analyse d'origine doivent être transférées au sous-système nouvellement créé. La description du sous-système doit être utilisée pour documenter les responsabilités.

Remarque : UML 2.0 définit aussi un stéréotype pour les composants appelés <<sous-systèmes>>, indiquant qu'ils peuvent, par exemple, être utilisés pour représenter les structures à grande échelle. Un sous-système de conception peut être ou non une structure à grande échelle. Dans les deux cas, ce sont des sous-systèmes de conception pour la perspective RUP. C'est une question que l'architecte du logiciel doit trancher : choisir, par exemple, de nommer des composants composés d'éléments comme des <<sous-systèmes>>.

Sous-systèmes représentant les produits existants Haut de la page

Lorsqu'un produit existant exporte des interfaces, comme des opérations (et peut-être des réceptions), mais cache tous les détails de l'implémentation, il peut être modélisé comme un sous-système dans la vue logique. Voici quelques exemples des produits que le sous-système utilise et que vous pouvez représenter par un sous-système :

  • La communication logicielle (middleware).
  • La prise en charge de l'accès à la base de données (prise en charge des mappages du système de gestion de base de données).
  • Les produits propres à l'application.

Certains produits existants, comme les collections de types et les structures de données (comme les piles, les listes et les files d'attente) peuvent être mieux représentées par des package car ils n'indiquent pas que le comportement. De plus, c'est le contenu du package qui est important et utile et pas le package en lui-même, qui est juste un conteneur. 

Les utilitaires communs, comme les bibliothèques de mathématiques, peuvent être représentés comme des sous-systèmes s'ils exportent simplement des interfaces. Cependant, savoir si cela est utile ou sensé dépend de l'avis du concepteur au sujet de la chose modélisée.  Les sous-systèmes sont des constructions orientées objet (ces sont des composants modélisés) : un sous-système peut avoir des instances (si le concepteur en décide ainsi). Le langage UML permet une nouvelle façon de modéliser les groupes de variables globales et de procédures dans l'utilitaire, qui est le stéréotype d'une classe - l'utilitaire n'a pas d'instance. 

Lors de la définition du sous-système qui représente le produit, définissez aussi une interface ou plus pour représenter les interfaces du produit.

Restrictions concernant la dépendance des sous-systèmes Début de page

Les sous-systèmes de conception (modélisés comme des composants UML) ont une sémantique différente de celle des packages : un sous-système fournit un comportement au travers d'une ou plusieurs interfaces qu'il réalise. Les packages ne fournissent pas de comportement mais ils contiennent des choses qui, elles, en fournissent.

Il est utile d'utiliser un sous-système à la place d'un package car les sous-systèmes encapsulent leur contenu, fournissant un comportement seulement à travers leurs interfaces. Cela permet donc de modifier le contenu et les comportements internes d'un sous-système en toute liberté tant que l'interface du sous-système reste constante ; cela n'est pas possible avec un package. Les sous-systèmes fournissent aussi un élément de conception "remplaçable" : les deux composant de <<réalisation>> qui réalisent les mêmes interfaces (ou les composants de <<spécification>>) sont interchangeables.

Pour être sûr que les sous-systèmes sont remplaçables dans le modèle, quelques règles doivent être respectées :

  • Un sous-système doit éviter d'exposer son contenu. Dans l'idéal, aucun élément contenu dans un sous-système ne devrait avoir une visibilité "publique" ; de cette façon, aucun élément externe au sous-système ne pourrait dépendre de l'existence d'un élément spécifique se trouvant à l'intérieur du sous-système. Voici quelques exceptions :
    • Dans certaines technologies, les éléments externes d'un sous-système ne peuvent pas être modélisés comme une interface UML. Par exemple, une interface Java est modélisée comme une classe stéréotypée.
    • La conception d'un sous-système peut demander des classes d'exposition plutôt que des interfaces UML. Par exemple, une classe "déléguée" ou une classe "d'accès" peut être utilisée pour dissimuler une collaboration complexe à d'autres classes. On pourrait aussi utiliser un package ordinaire, mais un sous-système peut être utilisé pour souligner la tentative d'encapsuler le comportement et de cacher les détails internes.

  • Lorsque les éléments externes à un sous-système ne sont pas des interfaces UML, il est souvent utile d'avoir un diagramme (nommé, par exemple, "Vue externe) indiquant les éléments visibles du sous-système.
  • Un sous-système doit définir ses dépendances sur les interfaces du sous-système (ainsi que les éléments du sous système ayant une visibilité publique, comme dans les rares cas décrits ci-dessus). De plus, certains sous-systèmes peuvent partager un ensemble d'interfaces ou de définitions de classe ; dans ce cas, ces sous-systèmes "importent" le contenu des packages qui contiennent les éléments en commun. Cela est plus fréquent chez les packages des couches inférieures de l'architecture de façon s'assurer que les définitions communes des classes, qui doivent passer entre les sous-systèmes, sont définies de manière cohérente.

Vous trouverez ci-dessous un exemple de dépendance entre un sous-système et un package.

Diagramme décrit dans le texte d'accompagnement.

Dépendances entre un sous-système et un package dans le modèle de conception

Spécification et réalisation d'un sous-système début de page

Définitiondébut de page

Le langage UML ([UML04]) établit que :

Il existe un certain nombre de stéréotypes standard du langage UML, par exemple la <<spécification>> et la <<réalisation>> pour modéliser des composants ayant des définitions de spécification et de réalisation distincte où une spécification peut avoir plusieurs réalisations.

Un composant stéréotypé par la <<spécification>> spécifie un domaine d'objets sans définir l'implémentation physique de ces objets. Il aura seulement des interfaces fournies et nécessaires et ni classe de réalisation, ni sous-composant ne feront partie de sa définition.

Un composant stéréotypé par la <<réalisation>> spécifie un domaine d'objets et définit aussi l'implémentation physique de ces objets. Par exemple, un composant stéréotypé par la <<réalisation>> n'aura que des classes de réalisation et des sous-composants qui implémentent le comportement spécifié par un composant de <<spécification>> à part.

La séparation de la spécification et de la réalisation tient principalement compte de deux descriptions du sous-système. La spécification fonctionne comme un contrat définissant tout ce que le client a besoin de savoir pour utiliser le sous-système. La réalisation est la conception interne détaillée ayant pour but de guider l'implémenteur. Si vous voulez prendre ne charge plusieurs réalisations, créez des "sous-systèmes de réalisation" séparés et créer une réalisation entre chaque sous-système de réalisation et le sous-système de spécification.

Quand et comment l'utiliser ?

Si l'état interne et le comportement du sous-système sont relativement simples, on peut simplement définir le sous-système grâce à ses interfaces exposées, ses diagrammes d'état, pour décrire le comportement et un texte descriptif.

Pour des états et des comportements plus complexes, les classes d'analyse peuvent être utilisées pour spécifier le sous-système à un haut niveau d'abstraction. Pour les grands systèmes, la spécification d'un sous-système peut aussi inclure les cas d'utilisation. Voir Développer des systèmes à grande échelle avec le Rational Unified Process.

Il est très utile de donner une spécification séparée de la réalisation dans les situations suivantes :

  • l'état interne ou le comportement de la réalisation du sous-système est complexe et la spécification doit être exprimée aussi simplement que possible pour que les clients puissent l'utiliser de manière efficace.
  • le sous-système est une "composant d'assemblage" réutilisable pouvant être assemblé en plusieurs systèmes (voir Concept: Composant);
  • les éléments internes du sous-système vont être développés par une organisation séparée ;
  • les implémentations multiples du sous-système doivent être créées ;
  • le sous-système doit être remplacé par une autre version comportant d'importants changements internes mais pas de changements au niveau du comportement visible à l'extérieur.

Conserver une spécification séparée demande des efforts, c'est important, par exemple, de s'assurer que la réalisation du sous-système soit conforme avec la spécification. Vous trouverez les critères définissant s'il faut créer une spécification séparée et quand la créer dans Produit : Instructions relative au projet.

Dépendances

Une spécification doit définir ses dépendances. Cela correspond aux interfaces et aux éléments visibles des autres sous-systèmes et packages devant être disponibles dans toutes les réalisations du sous-système.

Une réalisation peut avoir des dépendances supplémentaires, introduites par le concepteur ou l'implémenteur. Par exemple, il peut être utile d'utiliser un composant externe pour simplifier l'implémentation, mais l'utilisation de ce composant est un détail devant être exposé aux clients. Ces dépendances supplémentaires doivent être enregistrées dans un diagramme séparé faisant partie de la réalisation.

Relation avec l'implémentation

Une spécification détaillée définit tout ce dont un client a besoin pour utiliser le sous-système. Cela signifie qu'il faut affiner les interfaces exposées et les éléments ayant une visibilité publique de façon à ce qu'ils aient un rapport de un à un avec le code. Les classes d'analyse introduites pour définir le comportement du sous-système doivent conserver un haut-niveau d'abstraction car elles doivent être indépendantes vis à vis des réalisations du sous-système.

Les éléments de réalisation d'un sous-système doivent être proches du code.

Voir Technique: mappage de la conception au code pour plus de détails sur ce sujet.

Représentation UML 1.x

Modélisation

Les sous-systèmes de conception doivent être modélisées comme des composants UML 2.0 ou des sous-systèmes UML 1.5. Ces constructions permettent des fonctions de modélisation comme la modularité, l'encapsulation et les instances capables de s'exécuter lors de l'exécution.

Voici quelques remarques supplémentaires sur ces options de modélisation :

  • Le sous-système du langage UML 1.5 incluaient de manière explicite la notion de "spécification" et de "réalisation" (définie ci-dessus dans la section intitulée Spécification et réalisation des sous-systèmes). Les composants du langage UML 2.0 prennent en charge la notion de spécification (sous la forme d'une ou de plusieurs interfaces fournies et obligatoires) et de réalisation (implémentation interne composée d'une ou plusieurs classes et des sous-composants qui effectuent ses comportements).
  • Les sous-systèmes de UML 1.5 étaient aussi des packages. Les composants de UML 2.0 ont des fonctions de regroupement sous forme de packages, cela signifie qu'ils peuvent posséder et importer de grands ensembles d'éléments de modèle.

Cependant, ces notations peuvent, plus ou moins, être utilisées de manière interchangeable. Vous trouverez des informations sur le fait de représenter les sous-systèmes de conception sous forme de sous-systèmes d'UML 1.5 ou de composants UML 2.0 dans les Instructions relatives au projet spécifiques à votre projet.

Si vos outils de modélisation visuelle prennent en charge les packages UML 1.5 mais pas les sous-systèmes UML 1.5, un package stéréotypé comme un <<sous-système>> peut être utilisé pour faire référence à un sous-système.

Restrictions concernant la dépendance du sous-système

Les mêmes restrictions et les mêmes remarques concernant la dépendance mentionnées dans la section intitulée Restrictions concernant la dépendance du sous-système s'appliquent aussi au sous-systèmes de conception modélisés comme des sous-systèmes UML 1.5.

Vous trouverez ci-dessous un exemple de dépendance entre un sous-système et un package :



Diagramme décrit dans le texte d'accompagnement.

Dépendances entre un sous-système et un package dans le modèle de conception

Spécification et réalisation du sous-système

Le langage UML 1.5 établit que :

Le contenu d'un sous-système est divisé en deux sous-ensemble : 1) les éléments de spécification et les 2) éléments de réalisation. Les éléments de spécification, ainsi que les opérations et les réceptions du sous-système, sont utilisés pour donner une spécification abstraite du comportement offert par les éléments de réalisation. La collection d'éléments de réalisation modélisent l'intérieur du l'unité comportementale du système physique.

La séparation de la spécification et de la réalisation tient principalement compte de deux descriptions du sous-système. La spécification fonctionne comme un contrat définissant tout ce que le client a besoin de savoir pour utiliser le sous-système. La réalisation est la conception interne détaillée ayant pour but de guider l'implémenteur.

Une option pour modéliser les spécifications et les réalisations, si elles ne sont pas prises en charge par l'environnement de modélisation, est de placer deux packages, la spécification et la réalisation, dans chaque sous-système.

Un des avantages des spécifications est qu'elles prennent en charge les réalisations multiples. Cela n'était pas pris en charge directement par UML 1.x. Pour prendre en charge des réalisations multiples en utilisant des sous-systèmes UML 1.5, créez des sous-systèmes de "réalisation" à part et dessiner une réalisation entre chaque sous-système de réalisation et le sous-système de spécification.

D'un point de vue général , les considérations au sujet de UML 2.0 s'appliquent ici aussi, (pour plus d'informations, voir Comment et quant utiliser les, Dépendances, et Relation avec l'implémentation).

Informations supplémentaires

Voir aussi Les différences entre UML 1.x et UML 2.0 pour plus d'informations.