Pour implémenter les opérations, effectuez les étapes suivantes :
-
Sélectionner un algorithme.
-
Sélectionner les structures de données appropriées aux algorithmes.
-
Définir de nouvelles classes et de nouvelles opérations si nécessaire.
-
Coder l'opération.
Sélectionner un algorithme
Beaucoup d'opérations sont assez simples pour être implémentées à partir de l'opération et de sa spécification.
Des algorithmes complexes sont requis pour deux raisons principales : pour implémenter les opérations complexes pour
lesquelles une spécification est fournie, et pour optimiser les opérations pour lesquelles un algorithme simple mais
inefficace sert de définition.
Sélectionner les structures de données adaptées aux algorithmes
Le choix des algorithmes implique le choix de la structure de données sur laquelle ils sont utilisés. De nombreuses
structures de données d'implémentation sont des classes de conteneurs (tableaux, listes, files d'attente, piles,
ensembles et variations de ces éléments). La plupart des langages orientés objet et des environnements de programmation
fournissent des bibliothèques de classes contenant ces types de composants réutilisables.
Définir de nouvelles classes et opérations si nécessaire
On peut identifier de nouvelles classes pour stocker les résultats intermédiaires, par exemple. De nouvelles opérations
de bas niveau peuvent être ajoutées à la classe pour décomposer une opération complexe. Ces opérations sont souvent
privées et appartiennent à la classe, c'est-à-dire qu'elles ne sont pas visibles hors de la classe elle-même.
Coder l'opération
Ecrivez le code de l'opération en commençant par sa déclaration d'interface. Suivez les recommandations de
programmation applicables.
L'état d'un objet peut être implémenté en faisant référence aux valeurs de ses attributs, sans aucune représentation
spécifique. Les transitions d'état d'un tel objet sont implicites dans le changement des valeurs des attributs, et les
différents comportements sont programmés via des instructions conditionnelles. Cette solution n'est pas
satisfaisante pour les comportements complexes car elle aboutit généralement à des structures complexes difficiles à
modifier lorsque des états supplémentaires sont ajoutés ou que les comportements changent.
Si le comportement de l'élément de conception (ou de ses éléments constitutifs) est dépendant de l'état, un ou
plusieurs diagrammes d'état-transition décrivent généralement le comportement des éléments du modèle dans l'élément de
conception. Lors de l'implémentation, ces diagrammes d'état-transition constituent des éléments d'entrée importants.
Les machines d'état représentées dans les diagrammes d'état-transition rendent explicites les états des objets ; les
transitions et le comportement requis sont également clairement définis. Pour implémenter une machine d'état, vous avez
le choix entre plusieurs méthodes :
-
Pour les machines d'états simples, définissez un attribut qui énumère les états possibles et utilisez-le pour
sélectionner le comportement pour les messages entrants. Par exemple, dans une déclaration de commutateur en Java
ou en C++. Cette solution n'est pas très adaptée aux machines d'états complexes et peut conduire à de mauvaises
performances d'exécution. Pour obtenir un exemple de cette méthode, voir [DOUG98], Chapitre
4, 4.4.3
-
Les machines d'état plus complexes peuvent utiliser le pattern d'état. Pour obtenir la description du pattern
d'état, voir [GAM94]. La section Pattern d'état de l'ouvrage [DOUG98] au chapitre 6, 6.2.3, décrit également cette approche.
-
Une approche orientée tables fonctionne bien pour les machines d'état très complexes, pour lesquelles la simplicité
de modification constitue un critère. Pour chaque état, chaque entrée d'une table correspond aux entrées des états
suivants appropriés et aux actions de transition associées. Pour obtenir un exemple de cette méthode, voir [DOUG98], Chapitre 6, 6.2.3, Pattern de table d'état.
Les machines d'états contenant des sous-états concurrents peuvent être implémentées en déléguant la gestion des états à
des objets actifs, sur la base d'un objet pour chaque sous-état concurrent, car ces sous-états représentent des calculs
indépendants (qui peuvent toutefois être en interaction). Chaque sous-état peut être géré à l'aide de l'une des
techniques décrites ci-dessus.
Si une classe ou des parties d'une classe peuvent être implémentées par la ré-utilisation d'une classe existante,
utilisez la délégation plutôt que l'héritage.
Déléguer signifie que la classe est implémentée avec l'aide d'autres classes. La classe référence un objet de l'autre
classe à l'aide d'une variable. Lorsqu'une opération est appelée, elle appelle à son tour une opération dans l'objet
référencé (de la classe réutilisée) pour procéder à l'exécution. Par conséquent, elle délègue une part de
responsabilité à l'autre classe.
Une association unidirectionnelle est implémentée en tant que pointeur (attribut contenant une référence d'objet). Si
la multiplicité est égale à un, elle est implémentée en tant que pointeur simple. Si la multiplicité prévoit
plusieurs occurrences, il s'agira alors d'un ensemble de pointeurs. Si l'option plusieurs est retenue,
vous pouvez utiliser une liste plutôt qu'un ensemble.
Une association bidirectionnelle est implémentée en tant qu'attribut à deux sens, à l'aide des techniques applicables
aux associations unidirectionnelles.
Une association qualifiée est implémentée comme une table de consultation (par exemple, une classe de dictionnaire
Smalltalk) dans l'objet qualifiant. Les valeurs de sélection de la table de consultation sont les qualificatifs et les
valeurs cible sont les objets de l'autre classe.
Si les valeurs des qualificatifs doivent être accédées dans un certain ordre, les qualificatifs peuvent être organisés
sous forme d'ensemble trié ou d'arborescence. Dans ce cas, le temps d'accès sera proportionnel à log N (N représentant
le nombre de valeurs de qualificatifs).
Si les qualificatifs sont issus d'un ensemble compact fini, leurs valeurs peuvent être mappées au sein d'une plage de
nombres entiers et l'association peut être implémentée efficacement en tant que tableau. Cette approche est plus
attrayante, surtout si l'association est bien remplie (par opposition à une association avec peu d'éléments) et elle
est idéale pour les ensembles finis et complets.
La plupart des langages orientés objet et des environnements de programmation fournissent des bibliothèques de classes
contenant des composants réutilisables permettant d'implémenter différents types d'associations.
Pour implémenter les attributs, appliquez l'une des trois méthodes suivantes : utilisez des types primitifs intégrés,
une classe existante, ou encore définissez une nouvelle classe. Définir une nouvelle classe offre souvent plus de
souplesse, mais cette procédure induit un adressage indirect inutile. Par exemple, le numéro de sécurité sociale d'une
personne peut être soit implémenté en tant qu'attribut de type Chaîne, soit en tant que nouvelle classe.
Autres implémentations d'attribut.
Il peut également arriver que des groupes d'attributs soient combinés pour constituer de nouvelles classes, comme
l'illustre l'exemple suivant. Les deux implémentations sont correctes.
Les attributs de Ligne sont implémentés sous forme d'associations à une classe Point.
|