Instructions: Package de conception
Un package de conception est une construction utilisée pour segmenter le modèle de conception. Ces instructions expliquent comment identifier et définir les packages de conception.
Relations
Description principale

Introduction

Un modèle de conception peut être subdivisé en unités plus petites pour faciliter sa compréhension. En divisant le modèle de conception en packages et en sous-systèmes, puis en montrant comment ces groupes sont liés les uns aux autres, il est plus facile de comprendre la structure d'ensemble du modèle. Remarquez qu'un sous-système de conception est modélisé comme un composant qui réalise une interface ou plus ; pour plus d'informations, voir Produit : Sous-systèmes de conception et Instructions relatives au produit : Sous-systèmes de conception. Les packages de conception servent uniquement au regroupement.

Visibilité du contenu du package

Une classe contenue dans un package peut être publique ou privée. Une classe publique peut être associée à une autre classe. Une classe privée peut uniquement être associée à des classes contenues dans le package.

L'interface d'un package est constituée des classes publiques du package. L'interface package (les classes publiques) isole et implémente les dépendances sur les autres packages. De cette façon, le développement parallèle est simplifié car vous pouvez établir les interfaces plus tôt et les développeurs n'ont besoin de connaître que les changements des interfaces des autres packages.

Critères de segmentation des packages

Vous pouvez segmenter le modèle de conception pour plusieurs raisons :

  • Pour utiliser les packages et les sous-systèmes comme des unités d'organisation, de configuration ou de distribution lorsqu'un système est terminé.
  • L'allocation des ressources et les compétences des diverses équipes de développement peuvent impliquer la répartition du projet entre plusieurs groupes se trouvant sur des sites différents. Les sous-systèmes dont l'interface est bien définie sont un moyen de répartir le travail entre les équipes d'une manière contrôlée et coordonnée, permettant la réalisation simultanée de la conception et de l'implémentation.
  • Les sous-systèmes peuvent être utilisés pour structurer le modèle de conception de manière à refléter les types d'utilisateur. Beaucoup des demandes de changements proviennent des utilisateurs ; les sous-systèmes garantissent alors que les modifications n'affectent que les parties du système correspondant au type d'utilisateur associé à la modification.
  • Sous certaines applications, une partie des informations ne doit être accessible que pour un groupe restreint de personnes. Les sous-systèmes permettent de maintenir le secret là où il est requis.
  • Si vous construisez un système de prise en charge, vous pouvez, en utilisant des sous-systèmes et des packages, lui donner une structure similaire à celle du système qui va être pris en charge. De cette façon, vous pouvez synchroniser la maintenance des deux systèmes.
  • Les sous-systèmes sont utilisés pour représenter les produits existants et les services que le système utilise (par exemple les produits COTS et les bibliothèques), comme l'expliquent les sections suivantes.

Regroupement en packages des classes frontière

Lorsque les classes frontière sont distribuées aux packages, deux stratégies peuvent être appliquées ; il faut choisir l'une d'entre elles en fonction de la probabilité que les interfaces du système changent beaucoup ou non dans le futur.

  • S'il est probable que l'interface du système soit remplacée ou subisse des changements considérables, elle doit être séparée du reste du modèle de conception. Lorsque l'interface utilisateur est modifiée, seulement ces packages sont affectés. Basculer d'une interface en mode ligne à une interface en mode fenêtre est un exemple de changement majeur.

Diagramme décrit dans le texte d'accompagnement.

Si le but premier est de simplifier les changements majeurs de l'interface, les classes frontière doivent être placées dans un ou plusieurs packages séparés.

  • Si aucune modification majeure n'est prévue, les changements apportés aux services du système devraient être le principe à suivre, plutôt que les changements apportés à l'interface. Les classes frontière doivent alors être regroupées avec les classes entité et les classe de contrôle auxquelles elles sont liées fonctionnellement. De cette façon, il sera facile de voir les classes frontière affectées en cas de modification d'une classe entité ou d'une classe de contrôle.

Diagramme décrit dans le texte d'accompagnement.

Pour simplifier les changements apportés aux services du système, les classes frontière sont regroupées sous la forme de packages avec les classes auxquelles elles sont liées fonctionnellement.

Les classes frontière obligatoires qui ne sont pas liées fonctionnellement à des classes entité ou des classes de contrôle doivent être placées dans des packages séparés avec les classes frontière qui appartiennent à la même interface.

Si une classe frontière est associée à un service optionnel, regroupez-la avec les classes qui fournissent le service dans un sous-système séparé. Le sous-système se mappera à un composant optionnel qui sera fourni quand la fonctionnalité optionnelle sera demandé.

Regroupement en packages des classes liées fonctionnellement

Un package doit être défini pour chaque groupe de classes liées fonctionnellement. Il existe plusieurs critères pratiques pour évaluer si deux classes sont liées fonctionnellement. Ces critères sont décrits ci-dessous, par ordre décroissant d'importance :

  • Si les modifications dans le comportement et/ou la structure d'une classe implique des changements dans l'autre classe, les deux classes sont liées fonctionnellement.

Exemple

Si un attribut est ajouté à la classe entité Commande, cela impliquera sûrement une mise à jour de la classe de contrôle administrateur de commande. Elles appartiennent donc au même package traitement des commandes.

  • Il est possible de voir si une classe est liée fonctionnellement à une autre en prenant une classe - une classe entité par exemple - et en observant ce qui se passe si on la retire du système. Toutes les classes qui deviennent superflues à cause de cette suppression sont d'une façon ou d'une autre liées à cette classe. Par superflue, on entend ici que la classe est utilisée seulement par la classe supprimée ou qu'elle dépend d'elle.

Exemple

Il y a un package traitement des commandes qui contient les deux classes de contrôle administrateur de commande et enregistrement de la commande, dans le système de traitement du dépôt. Ces deux classes de contrôle modélisent des services concernant le traitement des commandes dans le dépôt. Tous les attributs et les relations sont conservés dans la classe entité commande, qui n'existe que pour le traitement des commandes. Si la classe entité est supprimée, l'administrateur de commande et l'enregistrement de la commande deviennent inutiles, car ils ne sont nécessaires que s'il y a une commande. La classe entité commande doit donc être inclus dans le même package que les deux classes de contrôle.

Diagramme décrit dans le texte d'accompagnement.

L'administrateur de commande et l'enregistrement de la commande appartiennent au même paquet que la commande, parce qu'ils deviennent inutiles si la commande est supprimée du système.

  • Deux objets peuvent être fonctionnellement liées s'ils interagissent avec un grand nombre de messages ou s'ils ont une intercommunication complexe.

Exemple

La classe de contrôle exécuteur de tâche envoie et reçoit des messages de la part de l'interface transporteur. Cela indique aussi qu'ils devraient être inclus dans le même package traitement de la tâche.

  • Une classe frontière peut être fonctionnellement liée à une classe entité particulière si la fonction de la classe frontière est de présenter la classe entité.

Exemple

La classe frontière forme de la palette, dans le système de traitement du dépôt, présente à l'utilisateur une instance de la classe palette. Chaque palette est représentée par un numéro d'identification sur l'écran. Si les informations sur la palette changent, par exemple si on attribue un nom à la palette, la classe frontière peut être, elle aussi, obligée de changer. La forme de la palette devrait donc être dans le même package que la palette.

  • Deux classes peuvent être liées fonctionnellement si elles interagissent avec, ou si elles sont affectées par les changements d'un même acteur. Si deux classes n'impliquent pas le même acteur, elles ne devraient pas être dans le même package. Cette dernière règle peut, bien sûr, être ignorée pour des raisons plus importantes.

Exemple

Il y a un package traitement de la tâche dans le système de traitement du dépôt, qui inclut, entre autres, la classe de contrôle exécuteur de tâche. C'est le seul package lié à l'acteur transporteur, le transporteur physique qui peut transporter une palette dans le dépôt. L'acteur interagit avec la classe de contrôle exécuteur de tâche par la classe frontière interface du transporteur. Cette classe frontière devrait donc être incluse dans le package traitement de la tâche.

Diagramme décrit dans le texte d'accompagnement.

L'interface transporteur et l'exécuteur de tâche appartiennent au même package car ils sont tous deux affectés par les changement de l'acteur transporteur.

  • Deux classes peuvent être liées fonctionnellement s'il existe des relations entres elles (associations, agrégations etc.) Bien sûr, on ne peut se fier à ce critère les yeux fermés, mais il peut être utilisé quand aucun autre critère n'est applicable.
  • Une classe peut être fonctionnellement liée à la classe qui crée ses instances.

Les deux critères suivants déterminent quand deux classes ne doivent pas être placées dans le même package :

  • Deux classes liées à des acteurs différents ne devraient pas être placées dans le même package.
  • Une classe optionnelle et une classe obligatoire ne devraient pas être placées dans le même package.

Evaluation des la cohésion du package

Tout d'abord, les éléments d'un même package doivent tous avoir la même "optionalité" : il ne peut y avoir de modèle optionnel dans un package obligatoire.

Exemple

La classe entité obligatoire type d'article a, entre autres choses, un attribut appelé rassortir les contraintes. La fonction "rassortir"est cependant optionnelle pour le système. Article devrait donc être divisé en deux classes entité où la classe optionnelle se rapporte à la classe obligatoire.

Un package obligatoire ne doit pas dépendre d'un package optionnel.

Il est établit qu'un package ne peut pas être utilisé par deux acteurs différents. Un changement dans le comportement d'un acteur ne devrait pas, en effet, affecter les autres acteurs. Il existe des exceptions à cette règle, comme pour les packages qui constituent les services optionnels. Les packages de ce type ne doivent pas être divisés, quel que soit le nombre d'acteurs qui les utilisent. Il faut donc diviser toutes les classes et tous les packages utilisés par plusieurs acteurs, à moins que le package soit optionnel.

Toutes les classes d'un même package doivent être liées fonctionnellement. Si vous avez suivi les critères de la section "Etablir les packages des classes liées fonctionnellement", les classes d'un package seront liées entre elles fonctionnellement. Toutefois, une classe peut contenir "trop" de comportements ou de relations ne lui appartenant pas. Une partie de la classe devrait alors être "enlevée" pour devenir une nouvelle classe ou être ajoutée à une autre classe, qui appartiendra sûrement à un autre package.

Exemple

Le comportement d'une classe de contrôle A se trouvant dans un package, ne doit pas trop dépendre d'une classe B, d'un autre package. Pour isoler le comportement spécifique de B, la classe de contrôle A doit être divisée en deux classes de contrôle, A' et A". Le comportement spécifique de B est placé dans la nouvelle classe de contrôle A", qui est elle-même placée dans la même package que B. La nouvelle classe A" se voit attribuer une relation avec l'objet original A', comme la généralisation.

Diagramme décrit dans le texte d'accompagnement.

Pour isoler le comportement spécifique de B, la classe de contrôle A, qui manque d'homogénéité, est divisée en deux classes de contrôle, A' et A''.

Description des dépendances des packages

Si une classe d'un package et associée à une classe d'un autre package, alors ces packages dépendent l'un de l'autre. Les dépendances des packages sont modélisées en utilisant une relation de dépendance entre les packages. Les relations de dépendance nous aident à évaluer les conséquences des changements : un package duquel beaucoup de packages dépendent est plus difficile à modifier qu'un package dont aucun package ne dépend.

Beaucoup de ces dépendances seront découvertes pendant la spécification des packages, elles sont donc amenées à changer pendant le travail. La description d'une relation de dépendance peut inclure des informations concernant les relations de classe ayant causé cette dépendance. Il est difficile de tenir ces informations à jour. Cela ne devrait donc être fait que si les informations sont pertinentes et intéressantes.

Exemple

Dans le système de traitement du dépôt il existe une relation de dépendance entre le package traitement de la commande et le package traitement de l'article. Cette association a été créée car la classe entité commande dans le traitement de la commande a une association avec la classe entité type d'article dans l'autre package.

Diagramme décrit dans le texte d'accompagnement.

Le package traitement de la commande dépend du traitement de l'article, car il existe une association entre deux classes des packages.

Evaluation du couplage des packages

Le couplage de packages est à la fois bon et mauvais : il est bon car il implique une réutilisation mais il est mauvais car les dépendances qu'il entraîne rendent le système plus difficile à modifier et à faire évoluer. Certains principes généraux peuvent être suivis :

  • Les packages ne devraient pas être couplés transversalement (c'est à dire co-dépendants): par exemple, deux packages ne devraient pas dépendre l'un de l'autre.

Diagramme décrit dans le texte d'accompagnement.

Lorsque cela se produit, les packages doivent être réorganisés pour supprimer les couplages transversaux.

  • Les packages des couches inférieures ne doivent pas dépendre des packages des couches supérieures. Les packages ne doivent dépendre que des packages appartenant à la même couche ou à la couche juste inférieure.

Diagramme décrit dans le texte d'accompagnement.

Lorsque cela se produit, la fonctionnalité doit être à nouveau segmentée. Une solution est de définir les dépendances en terme d'interfaces et de les organiser dans la couche inférieure.

  • En général, les dépendances ne devraient pas sauter de couches, à moins que le comportement de dépendance ne soit commun à toutes les couches. La solution est de simplement faire transiter les appels d'opération entre les couches.
  • Les packages ne doivent pas dépendre des sous-systèmes. Ils ne doivent dépendre que d'autres packages ou d'interfaces.