Séparer le quoi du comment
Un type abstrait de données décrit ce que l'on peut faire avec les données et les règles que ces opérations respectent. Il ne dit pas encore où les valeurs vivent ni comment les méthodes travaillent.
Le quoi
| Plan | Question | Exemple pour une pile |
|---|---|---|
| TAD | Quelles opérations et quelles règles ? | push, pop, isEmpty; dernier entré, premier sorti. |
| Interface Java | Quel contrat le compilateur peut-il vérifier ? | Les signatures de Pile<E>. |
| Implémentation | Quels objets et quelles instructions réalisent le contrat ? | ArrayList en interne, sommet à la fin. |
| Mémoire | Où les valeurs et références sont-elles rangées ? | Cases contiguës ou nœuds séparés. |
Exprimer le contrat en Java
Voici le contrat minimal utilisé dans le cours. Le paramètre E laisse le client choisir le type des éléments. Si ce mécanisme ne vous est pas familier, consultez l'annexe sur les types paramétrés.
L'interface ne contient ni ArrayList, ni Node, ni index. C'est volontaire. Un client qui utilise une pile ne devrait pas pouvoir contourner LIFO en retirant une valeur au milieu.
Le cas vide fait partie du contrat
pop() ne peut rien retourner si la pile est vide. Cette implémentation choisit une IllegalStateException. Le comportement doit être explicite, pas découvert au hasard d'un index invalide.Le code client type son champ avec l'interface utile. Il connaît la pile, pas les opérations supplémentaires de la classe concrète.
Un TAD, plusieurs rangements
Les deux représentations ci-dessous peuvent respecter exactement le même TAD. Seuls leurs gestes en mémoire diffèrent.
Sommet à la fin d'un tableau
push ajoute à droite. pop retire à droite.
Sommet au début des liens
push crée un nouveau head. pop avance head.
Ce que gagne le client
- Une API courte qui exprime LIFO.
- La possibilité de changer de classe concrète.
Ce que l'interface ne décide pas
- Le coût des opérations.
- La disposition des valeurs en mémoire.
Ce qu'il faut encore vérifier
- Les opérations fréquentes du scénario.
- Les cas limites de l'implémentation choisie.
Dépendre du contrat
- • Le client n'utilise que les opérations dont il a besoin.
- • Un remplacement d'implémentation reste local.
- • Le compilateur vérifie les signatures.
Dépendre des détails
- • Le client manipule directement le tableau interne.
- • Une méthode technique fuit dans tout le programme.
- • Changer le rangement oblige à corriger les appelants.
Choisir dans le bon ordre
Choisir d'abord une classe connue conduit souvent à tordre le besoin pour l'adapter à cette classe. Prenez les décisions dans l'autre sens.
Nommez le comportement
Avez-vous besoin d'un ordre LIFO, FIFO, d'une recherche par clé ou d'une hiérarchie ?Écrivez les opérations utiles
Gardez le contrat aussi étroit que le besoin. Prévoyez le cas vide ou l'absence d'une valeur.Repérez les opérations dominantes
Comptez les accès, les décalages, les copies et les liens suivis qu'elles provoqueront.Choisissez la représentation
Prenez la classe dont les gestes internes correspondent au scénario, puis cachez-la derrière le contrat utile.
Une interface n'est pas une décoration
Vérifiez vos réflexes
Vérifiez vos réflexes
Une réponse par question. La correction apparaît tout de suite.