French
French
French
Programmeur pragmatique,
pragmatique, Le
Le :: de
de compagnon
compagnon àà maître
maître
Andrew Hunt
David Thomas
Editeur : Addison Wesley
Première édition le 13 octobre 1999
ISBN : 0-201-61622-X, 352 pages
Jeux de coquillages..................................................................................77
Utilitaires Shell et systèmes Windows ................................................79
Utilisation des outils Unix sous Windows ................................................79
Les sections connexes incluent : ..................................................................80
Défis ..................................................................................................80
Édition avancée ..................................................................................................80
Un seul éditeur.............................................................................................80
Fonctionnalités de l'éditeur..............................................................................81
Productivité.................................................................................................82
Illustration 3.1. Trier les lignes dans un éditeur .......................................82
Où aller à partir d'ici ..................................................................82
Quels éditeurs sont disponibles ?................................................................83
Défis ..................................................................................................83
Contrôle du code source ..................................................................................83
Contrôle du code source et constructions .......................................................85
Mais mon équipe n'utilise pas le contrôle du code source ......................85
Produits de contrôle du code source ..................................................85
Les sections connexes comprennent : ..................................................................85
Défis..................................................................................................85
Débogage..................................................................................................86
Psychologie du débogage ..................................................................86
Un état d'esprit de débogage ..................................................................87
Par où commencer ..................................................................................87
Stratégies de débogage .......................................................................88
Reproduction desvos
Visualisez bogues
données ..................................................................................88
.......................................................................88
Illustration 3.2. Exemple de diagramme de débogueur d'une liste chaînée circulaire. Le
les flèches représentent des pointeurs vers des nœuds. ...............................................89
Traçage..............................................................................................89
Variables corrompues ? Vérifiez leur voisinage ..................................90
Ducking en caoutchouc ..................................................................................90
Processus d'élimination ....................................................................90
L'élément de surprise ..................................................................91
Liste de contrôle de débogage..............................................................92
Les sections connexes comprennent : ..................................................................92
Défis ..................................................................................................92
Manipulation de texte..................................................................................93
Les sections connexes comprennent : ..................................................................95
Exercices ..................................................................................................95
Générateurs de codes ....................................................................................95
Générateurs de code passifs ..................................................................96
Générateurs de code actifs .................................................................................97
Illustration 3.3. Le générateur de code actif crée du code à partir d'une base de données
schéma .......................................................................................................97
Tests ad hoc..............................................................................................169
Construire une fenêtre de test .......................................................................170
Une culture de test ..................................................................................171
Les sections connexes incluent : ..................................................................171
Exercices ..................................................................................................172
Sorciers maléfiques ..................................................................................172
Les sections associées incluent : ..................................................................173
Défis..............................................................................................173
Chapitre 7. Avant le projet ......................................................................174
La fosse aux exigences ..................................................................................174
Creuser pour les besoins ..................................................................175
Exigences en matière de documentation..................................................176
Parfois, l'interface est le système ..................................................176
Illustration 7.1. Modèle de cas d'utilisation de Cockburn ......................177
Illustration 7.2. Exemple de cas d'utilisation................................................178
Diagrammes de cas d'utilisation .......................................................179
Illustration 7.3. Cas d'utilisation d'UML—si simple qu'un enfant pourrait le faire !.........180
Surspécification .......................................................................................180
Voir plus loin ....................................................................................180
Juste une menthe ultra-mince de plus…................................................181
Maintenir un glossaire ..................................................................................181
Faites passer le mot .................................................................................182
Les sections connexes incluent : ..................................................................182
Défis ....................................................................................................182
Exercices ..................................................................................................182
Résoudre des énigmes impossibles ..................................................................183
Degrés de liberté ..................................................................................183
Il doit y avoir un moyen plus simple ! .......................................................184
Défis..............................................................................................185
Pas tant que vous n'êtes pas prêt ..................................................................185
Bon jugement ou procrastination ? ...............................................186
Défis ....................................................................................................186
Le piège des spécifications .......................................................................187
Les sections associées incluent : ..................................................................188
Défis..............................................................................................189
Cercles et flèches ...............................................................................189
Les méthodes sont-elles payantes ? .......................................................................190
Doit-on utiliser des méthodes formelles ? .......................................................190
Les sections connexes incluent : ..................................................................191
Défis ....................................................................................................191
Chapitre 8. Projets pragmatiques ..................................................................192
Des équipes pragmatiques ..................................................................................192
Pas de fenêtres cassées ..................................................................193
Grenouilles bouillies .......................................................................................193
Communiquer ....................................................................................193
Ne vous répétez pas.................................................................................194
Orthogonalité .......................................................................................194
Automatisation .......................................................................................196
Savoir quand arrêter d'ajouter de la peinture ..................................196
Les sections connexes incluent : ..................................................................196
Défis ....................................................................................................196
Automatisation ubiquitaire..............................................................................197
Tout en automatique ..................................................................................197
Compilation du projet ......................................................................198
Génération de code..............................................................................198
Tests de régression..............................................................................199
Marque récursive .......................................................................................199
Automatisation de la construction .......................................................................199
Versions finales ....................................................................................200
Administrivia automatique..................................................................200
Génération de sites Web ......................................................................200
Procédures d'approbation ......................................................................201
Les enfants du cordonnier .......................................................................201
Les sections connexes incluent : ..................................................................201
Défis ....................................................................................................202
Tests impitoyables..................................................................................202
Quoi tester..............................................................................................203
Tests unitaires ..................................................................................203
Tests d'intégration .......................................................................204
Validation et vérification .......................................................................204
Épuisement des ressources, erreurs et récupération..............204
Tests de performances ....................................................................205
Tests d'utilisabilité.........................................................................205
Regardez la convivialité en termes de facteurs humains. Y avait-il des miC'est tout
Rédaction..................................................................................................205
Commentaires dans le code..................................................................206
Documents exécutables ....................................................................208
Que faire si mon document n'est pas en texte brut ? ..................................................208
Rédacteurs techniques .......................................................................209
Imprimez-le ou tissez-le ..................................................................209
Langages de balisage.........................................................................210
Les sections connexes incluent : ..................................................................210
Défis ....................................................................................................211
Comment tester ......................................................................................211
Essais de conception/méthodologie ..................................................211
Tests de régression .......................................................................212
Données d'essai ......................................................................................212
Exercer les systèmes GUI ..................................................................213
Tester les tests..............................................................................213
Tester à fond ..................................................................................214
Quand tester ..................................................................................................214
Serrage du filet ..................................................................................215
Les sections connexes comprennent : ..................................................................215
Défis ....................................................................................................215
De grandes attentes.................................................................................216
Communiquer les attentes ..................................................................216
Le mille supplémentaire..............................................................................217
Les sections connexes comprennent : ..................................................................217
Défis ....................................................................................................218
Orgueil et préjugés ...............................................................................218
Annexe A. Ressources ..................................................................................220
Sociétés professionnelles .......................................................................220
Construire une bibliothèque..................................................................................221
Périodiques..............................................................................................221
Documents commerciaux hebdomadaires..............................................................221
Livres ..................................................................................................221
Analyse et conception ..................................................................................222
Equipes et Projets.................................................................................222
Environnements spécifiques.................................................................................222
Le Web ..................................................................................................223
Ressources Internet .......................................................................223
Rédacteurs ...............................................................................................223
Emacs ..................................................................................................223
[URL l] L'éditeur Emacs ................................................................223
[URL 2] L'éditeur XEmacs .............................................................224
vi .......................................................................................................................224
[URL 3] L'éditeur Vim................................................................224
[URL 4] L'éditeur elvis................................................................224
[URL 5] Mode Emacs Viper .........................................................224
Compilateurs, langages et outils de développement .......................224
[URL 6] Le compilateur GNU C/C++................................................224
[URL 7] Le langage Java de Sun .......................................224
[URL 8] Page d'accueil du langage Perl ................................225
[URL 9] Le langage Python................................................................225
[URL 10] PetitEiffel............................................................................225
[URL 11] ISE Eiffel ......................................................................225
[URL 12] Sather ................................................................................225
[URL 13] VisualWorks ................................................................225
[URL 14] L'environnement du langage Squeak ..................225
[URL 15] Le langage de programmation TOM .......................226
[URL 16] Le projet Beowulf ......................................................226
[URL 17] iContract—Outil de conception par contrat pour Java............226
Divers..............................................................................................232
[URL 57] Le projet GNU................................................................232
[URL 58] Informations sur le serveur Web .......................232
Bibliographie ..................................................................................................234
Annexe B. Réponses aux exercices ..................................................................237
Préface
Peu importe que vous soyez un développeur solitaire, membre d'un grand
équipe de projet ou un consultant travaillant avec plusieurs clients à la fois. Ce livre
vous aidera, en tant qu'individu, à faire un meilleur travail. Ce livre n'est pas
théorique - nous nous concentrons sur des sujets pratiques, sur l'utilisation de votre expérience pour
prendre des décisions plus éclairées. Le mot pragmatique vient du latin
pragmaticus — « compétent en affaires » — lui-même dérivé du grec
, signifiant "faire". C'est un livre sur le faire.
De nombreuses personnes vous proposent leur aide. Les vendeurs d'outils vantent les miracles
leurs produits sont performants. Les gourous de la méthodologie promettent que leurs techniques
garantir les résultats. Tout le monde prétend que son langage de programmation est le
mieux, et chaque système d'exploitation est la réponse à tous les maux imaginables.
Bien sûr, rien de tout cela n'est vrai. Il n'y a pas de réponses faciles. Il n'y a pas de
chose comme meilleure solution, qu'il s'agisse d'un outil, d'un langage ou d'un système d'exploitation.
Il ne peut y avoir que des systèmes plus appropriés dans un ensemble particulier de
circonstances.
C'est là que le pragmatisme entre en jeu. Vous ne devriez pas être marié à
technologie particulière, mais avoir une expérience et une expérience suffisamment larges
base pour vous permettre de choisir de bonnes solutions dans des situations particulières. Ton
l'arrière-plan découle d'une compréhension des principes de base de
l'informatique, et votre expérience provient d'un large éventail de domaines pratiques
projets. La théorie et la pratique se combinent pour vous rendre fort.
projet et utilisez votre expérience pour produire des solutions appropriées. Et toi
le faire en continu au fur et à mesure de l'avancement des travaux. Les programmeurs pragmatiques obtiennent
le travail est fait et faites-le bien.
Qui
Qui devrait
devrait lire
lire ce
ce livre
livre ??
Ce livre s'adresse aux personnes qui veulent devenir plus efficaces et plus
programmeurs productifs. Peut-être vous sentez-vous frustré de ne pas avoir l'air
réaliser votre potentiel. Peut-être regardez-vous des collègues qui semblent
utiliser des outils pour se rendre plus productifs que vous. Peut-être que votre
le travail actuel utilise des technologies plus anciennes et vous voulez savoir comment les nouvelles idées
peut être appliqué à ce que vous faites.
Nous ne prétendons pas avoir toutes (ou même la plupart) des réponses, et tous nos
des idées applicables dans toutes les situations. Tout ce que nous pouvons dire, c'est que si vous suivez notre
approche, vous acquerrez rapidement de l'expérience, votre productivité augmentera,
et vous aurez une meilleure compréhension de l'ensemble du processus de développement.
Et vous écrirez de meilleurs logiciels.
Qu'est-ce
Qu'est-ce qui
qui fait
fait un
un programmeur
programmeur pragmatique
pragmatique ??
Nous avons laissé les caractéristiques les plus élémentaires pour la fin. Tout pragmatique
Les programmeurs les partagent. Ils sont assez basiques pour être cités comme conseils :
Astuce
Astuce 11
Nous estimons qu'il ne sert à rien de développer un logiciel si vous ne vous souciez pas de
le faire bien.
Astuce
Astuce 22
Si cela vous semble être un travail acharné, alors vous faites preuve de réalisme
caractéristique. Cela va prendre une partie de votre temps précieux—du temps
qui est probablement déjà sous une pression énorme. La récompense est un plus
une implication active dans un travail que vous aimez, un sentiment de maîtrise sur un
gamme croissante de sujets, et le plaisir d'un sentiment de
amélioration. À long terme, votre investissement en temps sera remboursé comme
vous et votre équipe devenez plus efficaces, écrivez du code plus facile à
maintenir et passer moins de temps en réunion.
Pragmatistes
Pragmatistes individuels,
individuels, grandes
grandes équipes
équipes
Certaines personnes pensent qu'il n'y a pas de place pour l'individualité dans les grandes équipes ou
projets complexes. "La construction de logiciels est une discipline d'ingénierie", ont-ils
dire, "qui tombe en panne si les membres individuels de l'équipe prennent des décisions pour
eux-mêmes."
Nous qui ne taillons que des pierres devons toujours envisager des cathédrales.
-- Credo
Credo du
du travailleur
travailleur de
de la
la carrière
carrière
C'est
C'est un
un processus
processus continu
continu
Un touriste visitant l'Eton College en Angleterre a demandé au jardinier comment il avait obtenu le
pelouses si parfaites. « C'est facile », répondit-il, « Il suffit d'enlever la rosée tous les
matin, tondez-les tous les deux jours et roulez-les une fois par semaine."
Les grandes pelouses ont besoin de petites quantités de soins quotidiens, et elles sont donc excellentes
programmeurs. Les consultants en gestion aiment laisser tomber le mot kaizen dans
conversations. "Kaizen" est un terme japonais qui résume le concept de
apporter continuellement de nombreuses petites améliorations. Il était considéré comme
l'une des principales raisons des gains spectaculaires de productivité et de qualité
dans la fabrication japonaise et a été largement copié dans le monde entier.
Kaizen s'applique aussi aux particuliers. Chaque jour, travaillez pour affiner les compétences que vous
avoir et d'ajouter de nouveaux outils à votre répertoire. Contrairement aux pelouses d'Eton, vous
commencer à voir des résultats en quelques jours. Au fil des ans, vous serez étonné de
comment votre expérience s'est épanouie et vos compétences ont grandi.
Comment
Comment le
le livre
livre est
est organisé
organisé
Ce livre est écrit comme une collection de courtes sections. Chaque rubrique est
autonome et aborde un sujet particulier. Vous trouverez de nombreuses croix
références, qui aident à mettre chaque sujet en contexte. N'hésitez pas à lire le
sections dans n'importe quel ordre - ce n'est pas un livre que vous devez lire d'un bout à l'autre.
De temps à autre, vous rencontrerez une case intitulée Conseil nn (telle que Conseil 1, "Soin
À propos de votre métier" à la page xix). En plus de souligner des points dans le texte,
nous pensons que les pourboires ont leur propre vie - nous les suivons quotidiennement. Vous trouverez un
résumé de tous les conseils sur une carte détachable à l'intérieur de la couverture arrière.
Nous avons inclus des exercices et des défis, le cas échéant. Des exercices
ont normalement des réponses relativement simples, tandis que les défis sont
plus ouvert. Pour vous donner une idée de notre réflexion, nous avons inclus notre
réponses aux exercices de l'annexe B , mais très peu ont une seule réponse correcte.
solution. Les défis peuvent former la base de discussions de groupe ou d'essais
travailler dans des cours de programmation avancés.
Qu'est-ce
Qu'est-ce qu'il
qu'il yy aa dans
dans un
un nom?
nom?
"Quand j'utilise un mot," dit Humpty Dumpty, d'un ton plutôt méprisant, "il
signifie exactement ce que je choisis qu'il signifie - ni plus ni moins."
Lewis
Lewis Carroll,
Carroll, De
De l'autre
l'autre côté
côté du
du miroir
miroir
Après avoir dit tout cela, nous avons décidé de nous venger de l'ordinateur
scientifiques. Parfois, il existe de très bons mots de jargon pour les concepts,
mots que nous avons décidé d'ignorer. Pourquoi? Parce que le jargon existant est
normalement limité à un domaine de problème particulier, ou à une phase particulière
de développement. Cependant, l'une des philosophies de base de ce livre est que
la plupart des techniques que nous préconisons sont universelles : modularité
s'applique au code, aux conceptions, à la documentation et à l'organisation de l'équipe, par
exemple. Lorsque nous avons voulu utiliser le mot du jargon conventionnel dans un sens plus large
contexte, c'est devenu déroutant - nous ne semblions pas pouvoir surmonter les bagages
terme original apporté avec lui. Lorsque cela s'est produit, nous avons contribué au
déclin de la langue en inventant nos propres termes.
Code
Code source
source et
et autres
autres ressources
ressources
La plupart du code présenté dans ce livre est extrait d'une source compilable
fichiers, disponibles en téléchargement sur notre site Web :
http://www.pragmaticprogrammer.com
Vous y trouverez également des liens vers des ressources que nous jugeons utiles, ainsi que des mises à jour
au livre et aux nouvelles des autres développements du programmeur pragmatique.
Envoyez-nous
Envoyez-nous vos
vos commentaires
commentaires
Remerciements
Remerciements
Quand nous avons commencé à écrire ce livre, nous n'avions aucune idée du degré d'équipe
effort qu'il finirait par être.
rédacteur en chef (et un concepteur de couverture moyen!), Lorraine Ferrier et John Fuller pour
leur aide à la production, et l'infatigable Julie DeBaggis pour
nous gardant tous ensemble.
Au fil des ans, nous avons travaillé avec un grand nombre de clients progressistes,
où nous avons acquis et affiné l'expérience dont nous parlons ici. Récemment,
nous avons eu la chance de travailler avec Peter Gehrke sur plusieurs grands projets.
Son soutien et son enthousiasme pour nos techniques sont très appréciés.
Ce livre a été produit en utilisant LATEX, pic, Perl, dvips, ghostview, ispell,
Marque GNU, CVS, Emacs, XEmacs, EGCS, GCC, Java, iContract et
SmallEiffel, utilisant les shells Bash et zsh sous Linux. Le stupéfiant
Le fait est que tous ces logiciels formidables sont disponibles gratuitement. Nous devons une
un immense "merci" aux milliers de programmeurs pragmatiques du monde entier
qui ont contribué à ces travaux et à d'autres pour nous tous. Nous aimerions particulièrement
remercier Reto Kramer pour son aide avec iContract.
Enfin, mais non des moindres, nous avons une énorme dette envers nos familles. Non seulement ont
ils supportent des dactylographies tardives, d'énormes factures de téléphone et nos permanents
air de distraction, mais ils ont eu la grâce de lire ce que nous avons écrit,
fois après fois. Merci de nous faire rêver.
Andy Chasse
David Thomas
Qu'est-ce
Qu'est-ce qu'il
qu'il yy aa dans
dans un
un nom?
nom?
"Quand j'utilise un mot," dit Humpty Dumpty, d'un ton plutôt méprisant, "il
signifie exactement ce que je choisis qu'il signifie - ni plus ni moins."
Lewis
Lewis Carroll,
Carroll, De
De l'autre
l'autre côté
côté du
du miroir
miroir
Après avoir dit tout cela, nous avons décidé de nous venger de l'ordinateur
scientifiques. Parfois, il existe de très bons mots de jargon pour les concepts,
mots que nous avons décidé d'ignorer. Pourquoi? Parce que le jargon existant est
normalement limité à un domaine de problème particulier, ou à une phase particulière
de développement. Cependant, l'une des philosophies de base de ce livre est que
la plupart des techniques que nous préconisons sont universelles : modularité
s'applique au code, aux conceptions, à la documentation et à l'organisation de l'équipe, par
exemple. Lorsque nous avons voulu utiliser le mot du jargon conventionnel dans un sens plus large
contexte, c'est devenu déroutant - nous ne semblions pas pouvoir surmonter les bagages
terme original apporté avec lui. Lorsque cela s'est produit, nous avons contribué au
déclin de la langue en inventant nos propres termes.
Code
Code source
source et
et autres
autres ressources
ressources
La plupart du code présenté dans ce livre est extrait d'une source compilable
fichiers, disponibles en téléchargement sur notre site Web :
http://www.pragmaticprogrammer.com
Vous y trouverez également des liens vers des ressources que nous jugeons utiles, ainsi que des mises à jour
au livre et aux nouvelles des autres développements du programmeur pragmatique.
Envoyez-nous
Envoyez-nous vos
vos commentaires
commentaires
Remerciements
Remerciements
Quand nous avons commencé à écrire ce livre, nous n'avions aucune idée du degré d'équipe
effort qu'il finirait par être.
Au fil des ans, nous avons travaillé avec un grand nombre de clients progressistes,
où nous avons acquis et affiné l'expérience dont nous parlons ici. Récemment,
nous avons eu la chance de travailler avec Peter Gehrke sur plusieurs grands projets.
Son soutien et son enthousiasme pour nos techniques sont très appréciés.
Ce livre a été produit en utilisant LATEX, pic, Perl, dvips, ghostview, ispell,
Marque GNU, CVS, Emacs, XEmacs, EGCS, GCC, Java, iContract et
SmallEiffel, utilisant les shells Bash et zsh sous Linux. Le stupéfiant
Le fait est que tous ces logiciels formidables sont disponibles gratuitement. Nous devons une
un immense "merci" aux milliers de programmeurs pragmatiques du monde entier
qui ont contribué à ces travaux et à d'autres pour nous tous. Nous aimerions particulièrement
remercier Reto Kramer pour son aide avec iContract.
Enfin, mais non des moindres, nous avons une énorme dette envers nos familles. Non seulement ont
ils supportent des dactylographies tardives, d'énormes factures de téléphone et nos permanents
air de distraction, mais ils ont eu la grâce de lire ce que nous avons écrit,
fois après fois. Merci de nous faire rêver.
Andy Chasse
David Thomas
Le
Le chat
chat aa mangé
mangé mon
mon code
code source
source
JB
JB Bossuet,
Bossuet, Politique
Politique d'après
d'après les
les Saintes
Saintes Écritures,
Écritures, 1709
1709
Ces choses arrivent, et nous essayons de les gérer avec autant de professionnalisme que nous
peut. Cela signifie être honnête et direct. Nous pouvons être fiers de nos capacités,
mais nous devons être honnêtes à propos de nos défauts - notre ignorance ainsi que
nos erreurs.
Prendre
Prendre la
la responsabilité
responsabilité
La responsabilité est quelque chose que vous acceptez activement. Vous vous engagez
pour s'assurer que quelque chose est bien fait, mais vous n'avez pas nécessairement
contrôle sur tous les aspects de celui-ci. En plus de faire de son mieux,
vous devez analyser la situation pour les risques qui sont hors de votre contrôle. Toi
ont le droit de ne pas assumer la responsabilité d'une situation impossible, ou
celui où les risques sont trop grands. Vous devrez passer l'appel en fonction de
votre propre éthique et votre propre jugement.
Lorsque vous acceptez la responsabilité d'un résultat, vous devez vous attendre à
en être tenu pour responsable. Lorsque vous faites une erreur (comme nous le faisons tous) ou un
erreur de jugement, admettez-la honnêtement et essayez de proposer des options.
Ne blâmez pas quelqu'un ou quelque chose d'autre, et n'inventez pas d'excuse. Ne blâmez pas
tous les problèmes d'un fournisseur, d'un langage de programmation, de gestion ou
vos collègues. Tout cela peut jouer un rôle, mais c'est à vous de
proposer des solutions, pas des excuses.
S'il y avait un risque que le fournisseur ne vienne pas pour vous, alors vous
aurait dû avoir un plan d'urgence. Si le disque tombe en panne, prenant tout votre
code source avec - et vous n'avez pas de sauvegarde, c'est de votre faute. Récit
votre patron "le chat a mangé mon code source" ne le coupera tout simplement pas.
Astuce
Astuce 33
Avant d'approcher quelqu'un pour lui dire pourquoi quelque chose ne peut pas être fait,
en retard ou en panne, arrêtez-vous et écoutez-vous. Parlez au canard en plastique sur
votre moniteur, ou le chat. Votre excuse semble-t-elle raisonnable ou stupide ?
Comment ça va sonner à votre patron ?
Parcourez la conversation dans votre esprit. Quelle est la probabilité de l'autre personne
dire? Vont-ils demander : « Avez-vous essayé ceci… » ou « N'y avez-vous pas pensé ? »
Comment allez-vous répondre ? Avant d'aller leur annoncer la mauvaise nouvelle, y a-t-il
autre chose que vous pouvez essayer? Parfois, vous savez juste ce qu'ils vont faire
dites, alors épargnez-leur la peine.
Au lieu d'excuses, proposez des options. Ne dites pas que cela ne peut pas être fait; Expliquer quoi
peut être fait pour sauver la situation. Le code doit-il être jeté?
Éduquez-les sur la valeur du refactoring (voir Refactoring ). Avez-vous besoin de
passer du temps à prototyper pour déterminer la meilleure façon de procéder (voir
Prototypes et Post-it ) ? Avez-vous besoin d'introduire de meilleurs tests (voir
Code That's Easy to Test et Ruthless Testing) ou l'automatisation (voir
Ubiquitous Automation) pour éviter que cela se reproduise ? Peut-être toi
besoin de ressources supplémentaires. N'ayez pas peur de demander ou d'admettre que vous avez besoin
aider.
Essayez de débusquer les excuses boiteuses avant de les exprimer à haute voix. Si tu dois,
dites-le d'abord à votre chat. Après tout, si le petit Tiddles doit être blâmé….
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Prototypes et Post-it
• • Refactorisation
• • Code facile à tester
• • Automatisation omniprésente
• • Tests impitoyables
Défis
Défis
Entropie
Entropie logicielle
logicielle
Alors que le développement logiciel est à l'abri de presque toutes les lois physiques,
l'entropie nous frappe durement. L'entropie est un terme de la physique qui fait référence à la
quantité de "désordre" dans un système. Malheureusement, les lois de
la thermodynamique garantit que l'entropie dans l'univers tend vers une
maximum. Lorsque le désordre augmente dans les logiciels, les programmeurs l'appellent
"pourriture logicielle."
Dans les centres-villes, certains bâtiments sont beaux et propres, tandis que d'autres sont
carcasses pourrissantes. Pourquoi? Chercheurs dans le domaine de la criminalité et de la dégradation urbaine
découvert un mécanisme de déclenchement fascinant, qui transforme très rapidement un
bâtiment propre, intact et habité en une épave détruite et abandonnée
[ WK82].
Une fenêtre cassée, laissée non réparée pendant une longue période,
inculque aux habitants de l'immeuble un sentiment d'abandon, un sentiment
que les pouvoirs en place ne se soucient pas du bâtiment. Donc une autre fenêtre
se casse. Les gens commencent à jeter des ordures. Des graffitis apparaissent. Structurel sérieux
Astuce
Astuce 44
Nous avons vu des systèmes propres et fonctionnels se détériorer assez rapidement une fois
les fenêtres commencent à se casser. Il existe d'autres facteurs qui peuvent contribuer à
logiciel pourriture, et nous aborderons certains d'entre eux ailleurs, mais négligez
accélère la pourriture plus rapidement que tout autre facteur.
Éteindre
Éteindre les
les feux
feux
Un cas assez extrême, certes, mais c'est comme ça que ça doit être avec
logiciel. Une fenêtre cassée - un morceau de code mal conçu, un mauvais
décision de gestion avec laquelle l'équipe doit vivre pendant la durée de la
projet— c'est tout ce qu'il faut pour amorcer le déclin. Si vous vous retrouvez à travailler sur un
projet avec pas mal de fenêtres brisées, il est trop facile de se glisser dans le
état d'esprit de "Tout le reste de ce code est de la merde, je vais juste suivre le mouvement." Ce n'est pas
peu importe si le projet a bien fonctionné jusqu'à présent. Dans la version originale
expérience menant à la "théorie de la fenêtre brisée", une voiture abandonnée était assise
pendant une semaine intacte. Mais une fois qu'une seule fenêtre a été brisée, la voiture a été
dépouillé et retourné en quelques heures.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
Sans se décourager, les soldats ont fait bouillir une casserole d'eau et ont soigneusement placé trois
pierres dedans. Les villageois stupéfaits sont sortis pour regarder.
"C'est de la soupe aux cailloux", ont expliqué les soldats. « C'est tout ce que tu as mis dedans ? demandé
les villageois. "Absolument, même si certains disent que c'est encore meilleur avec un
quelques carottes…." Un villageois s'enfuit, revenant en peu de temps avec un panier de
carottes de son trésor.
Quelques minutes plus tard, les villageois ont de nouveau demandé "C'est ça?"
"Eh bien," dirent les soldats, "quelques pommes de terre lui donnent du corps." Off a couru un autre
villageois.
Au cours de l'heure qui a suivi, les soldats ont énuméré d'autres ingrédients susceptibles d'améliorer
la soupe : bœuf, poireaux, sel et herbes. Chaque fois qu'un villageois différent
courir pour piller leurs magasins personnels.
Finalement, ils avaient produit une grande marmite de soupe fumante. Les soldats
enlevé les pierres, et ils se sont assis avec tout le village pour profiter de la
premier repas carré que l'un d'entre eux avait mangé depuis des mois.
Il y a quelques morales dans l'histoire de la soupe aux pierres. Les villageois sont
trompés par les soldats, qui utilisent la curiosité des villageois pour obtenir de la nourriture
eux. Mais plus important encore, les soldats agissent comme un catalyseur, amenant le
village ensemble afin qu'ils puissent produire ensemble quelque chose qu'ils ne pourraient pas
ont fait par eux-mêmes - un résultat synergique. Finalement tout le monde gagne.
Vous pouvez être dans une situation où vous savez exactement ce qui doit être fait et
comment faire. L'ensemble du système apparaît juste devant vos yeux - vous savez que c'est
droite. Mais demandez la permission d'aborder le tout et vous serez accueilli
retards et regards vides. Les gens formeront des comités, les budgets auront besoin
l'approbation, et les choses vont se compliquer. Chacun gardera le sien
ressources. Parfois, cela s'appelle la "fatigue du démarrage".
Il est temps de sortir les pierres. Déterminez ce que vous pouvez raisonnablement demander.
Développez-le bien. Une fois que vous l'avez, montrez aux gens et laissez-les s'émerveiller. Alors
dire "bien sûr, ce serait mieux si on ajoutait…." Faire comme si ce n'était pas important.
Asseyez-vous et attendez qu'ils commencent à vous demander d'ajouter la fonctionnalité que vous
voulu à l'origine. Les gens trouvent plus facile de rejoindre un succès continu. Montrer
leur donner un aperçu de l'avenir et vous les inciterez à se rallier. [1]
[1] En faisant cela, vous serez peut-être rassuré par la ligne attribuée au contre-amiral Dr. Grace Hopper : "Il est plus facile de demander
Astuce
Astuce 55
D'un autre côté, l'histoire de la soupe aux pierres est aussi une histoire douce et graduelle.
tromperie. Il s'agit de se concentrer trop étroitement. Les villageois pensent à la
pierres et oublier le reste du monde. Nous y craquons tous, tous les jours.
Les choses nous tombent dessus.
Nous avons tous vu les symptômes. Les projets sortent lentement et inexorablement totalement
de main. La plupart des sinistres logiciels commencent trop petits pour être remarqués, et la plupart
les dépassements de projet se produisent un jour à la fois. Les systèmes dérivent de leur
spécifications fonctionnalité par fonctionnalité, tandis que patch après patch est ajouté à un
morceau de code jusqu'à ce qu'il ne reste plus rien de l'original. C'est souvent le
accumulation de petites choses qui casse le moral et les équipes.
Astuce
Astuce 66
Nous n'avons jamais essayé cela - honnêtement. Mais ils disent que si vous prenez une grenouille et
déposez-le dans de l'eau bouillante, il ressortira tout de suite. Toutefois, si
vous placez la grenouille dans une casserole d'eau froide, puis la chauffez progressivement, la grenouille
ne remarquera pas la lente augmentation de la température et restera en place jusqu'à ce que
cuit.
Notez que le problème de la grenouille est différent du problème des fenêtres cassées
discuté dans la section. 2Dans la théorie de la fenêtre brisée, les gens perdent la volonté
pour combattre l'entropie parce qu'ils perçoivent que personne d'autre ne s'en soucie. La grenouille juste
ne remarque pas le changement.
Ne soyez pas comme la grenouille. Gardez un œil sur la situation dans son ensemble. Révisez constamment
ce qui se passe autour de vous, pas seulement ce que vous faites personnellement.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Entropie logicielle
• • Programmation par coïncidence
• • Refactorisation
• • La fosse aux exigences
Défis
Défis
Logiciel
Logiciel assez
assez bon
bon
Roi
Roi Lear
Lear 1.4
1.4
Il y a une vieille blague à propos d'une entreprise américaine qui passe une commande pour
100 000 circuits intégrés avec un fabricant japonais. Partie de la
spécification était le taux de défauts : une puce sur 10 000. Quelques semaines plus tard, le
la commande est arrivée : une grande boîte contenant des milliers de circuits intégrés et une petite
n'en contenant que dix. Attachée à la petite boîte se trouvait une étiquette qui disait : "Ces
sont les fautifs."
Si seulement nous avions vraiment ce genre de contrôle sur la qualité. Mais le monde réel
ne nous laissera tout simplement pas produire beaucoup de choses vraiment parfaites, en particulier pas sans bogues
logiciel. Le temps, la technologie et le tempérament conspirent tous contre nous.
Cependant, cela ne doit pas être frustrant. Comme Ed Yourdon l'a décrit dans un
article dans IEEE Software [ You95 ], vous pouvez vous discipliner pour écrire
un logiciel suffisamment performant, suffisamment performant pour vos utilisateurs, pour l'avenir
mainteneurs, pour votre tranquillité d'esprit. Vous constaterez que vous êtes plus
productif et vos utilisateurs sont plus heureux. Et vous pourriez bien constater que votre
les programmes sont en fait meilleurs pour leur incubation plus courte.
Avant d'aller plus loin, nous devons nuancer ce que nous allons dire. Le
l'expression "assez bon" n'implique pas un code bâclé ou mal produit. Tous
les systèmes doivent répondre aux exigences de leurs utilisateurs pour réussir. Nous sommes
préconisant simplement que les utilisateurs aient la possibilité de participer à la
processus de décider quand ce que vous avez produit est assez bon.
Impliquez
Impliquez vos
vos utilisateurs
utilisateurs dans
dans le
le compromis
compromis
Normalement, vous écrivez des logiciels pour d'autres personnes. Souvent, vous vous souviendrez de
[2] Mais à quelle fréquence leur demandez-vous à quel point
obtenir des exigences de leur part.
veulent-ils que leur logiciel soit ? Parfois, il n'y aura pas de choix. Si vous êtes
travailler sur des stimulateurs cardiaques, la navette spatiale ou une bibliothèque de bas niveau qui sera
largement diffusées, les exigences seront plus strictes et votre
options plus limitées. Toutefois, si vous travaillez sur un tout nouveau produit,
vous aurez différentes contraintes. Les gens du marketing auront des promesses
à conserver, les éventuels utilisateurs finaux peuvent avoir fait des plans basés sur une livraison
calendrier, et votre entreprise aura certainement des contraintes de trésorerie. Il
ne serait pas professionnel d'ignorer les exigences de ces utilisateurs simplement pour ajouter
de nouvelles fonctionnalités au programme, ou pour peaufiner le code juste une fois de plus.
Nous ne prônons pas la panique : il est tout aussi peu professionnel de promettre
échelles de temps impossibles et de couper les coins d'ingénierie de base pour répondre à un
date limite.
La portée et la qualité du système que vous produisez doivent être spécifiées dans le cadre
des exigences de ce système.
Astuce
Astuce 77
Souvent, vous serez dans des situations où des compromis sont impliqués. Étonnamment,
de nombreux utilisateurs préfèrent aujourd'hui utiliser un logiciel avec quelques aspérités plutôt que
attendre un an pour la version multimédia. De nombreux départements informatiques avec des
les budgets seraient d'accord. Aujourd'hui, un bon logiciel est souvent préférable au parfait
logiciel demain. Si vous donnez à vos utilisateurs quelque chose avec quoi jouer tôt,
leurs commentaires vous conduiront souvent à une meilleure solution éventuelle (voir Tracer
balles).
Savoir
Savoir quand
quand s'arrêter
s'arrêter
À certains égards, la programmation est comme la peinture. Vous commencez avec une toile vierge
et certaines matières premières de base. Vous utilisez une combinaison de science, d'art et
artisanat pour déterminer quoi en faire. Vous dessinez une forme générale,
peignez l'environnement sous-jacent, puis remplissez les détails. Vous constamment
prenez du recul avec un œil critique pour voir ce que vous avez fait. De temps en temps
vous jetez une toile et recommencez.
Mais les artistes vous diront que tout le travail acharné est ruiné si vous ne savez pas
quand s'arrêter. Si vous ajoutez couche après couche, détail sur détail, la peinture
se perd dans la peinture.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Balles traçantes
• • La fosse aux exigences
• • Des équipes pragmatiques
• • De grandes attentes
Défis
Défis
Votre
Votre portefeuille
portefeuille de
de connaissances
connaissances
Benjamin
Benjamin Franklin
Franklin
Ah, ce bon vieux Ben Franklin, jamais à court d'idées pour une homélie lapidaire. Pourquoi, si nous
pourrait juste se coucher tôt et se lever tôt, nous serions super
programmeurs, n'est-ce pas ? Les lève-tôt pourraient attraper le ver, mais qu'est-ce que
arrive au ver précoce?
Dans ce cas, cependant, Ben a vraiment mis le doigt sur la tête. Vos connaissances
et l'expérience sont vos principaux atouts professionnels.
[3] Un actif qui expire est quelque chose dont la valeur diminue avec le temps. Les exemples incluent un entrepôt plein de bananes et un
Votre
Votre portefeuille
portefeuille de
de connaissances
connaissances
Nous aimons penser à tous les faits que les programmeurs connaissent sur l'informatique, les
domaines d'application dans lesquels ils travaillent, et toute leur expérience en tant que leur
Portefeuilles de connaissances. La gestion d'un portefeuille de connaissances ressemble beaucoup à
gérer un portefeuille financier :
Pour réussir dans votre carrière, vous devez gérer votre portefeuille de connaissances
en utilisant ces mêmes lignes directrices.
Construire
Construire votre
votre portefeuille
portefeuille
Astuce
Astuce 88
Buts
Buts
Maintenant que vous avez quelques directives sur quoi et quand ajouter à votre
portefeuille de connaissances, quelle est la meilleure façon d'acquérir des connaissances intellectuelles
capital avec lequel financer votre portefeuille? Voici quelques suggestions.
Il est important de continuer à investir. Une fois que vous vous sentez à l'aise avec certains
nouvelle langue ou un peu de technologie, passez à autre chose. Apprenez-en un autre.
Peu importe que vous utilisiez ou non l'une de ces technologies sur un
projet, ou même si vous les mettez sur votre CV. Le processus de
l'apprentissage élargira votre réflexion, vous ouvrira à de nouvelles possibilités et
de nouvelles façons de faire. La pollinisation croisée des idées est importante; Essayez de
appliquer les leçons que vous avez apprises à votre projet actuel. Même si votre
projet n'utilise pas cette technologie, vous pouvez peut-être emprunter quelques idées. Obtenir
familiarisé avec l'orientation objet, par exemple, et vous écrirez du C ordinaire
programmes différemment.
Opportunités
Opportunités d'apprentissage
d'apprentissage
Donc vous lisez avec voracité, vous êtes au courant de toutes les dernières nouveautés
développements dans votre domaine (ce qui n'est pas facile à faire), et quelqu'un vous demande
une question. Vous n'avez pas la moindre idée de la réponse, et librement
admettre autant.
Ne laissez pas cela s'arrêter là. Prenez-le comme un défi personnel pour trouver la réponse.
Demandez à un gourou. (Si vous n'avez pas de gourou dans votre bureau, vous devriez pouvoir
trouver un sur Internet : voir l'encadré sur la page ci-contre.) Rechercher sur le Web.
Aller à la bibliothèque.
[4]
[4] En cette ère du Web, beaucoup de gens semblent avoir oublié les véritables bibliothèques en direct remplies de matériel de recherche et
personnel.
Si vous ne pouvez pas trouver la réponse vous-même, découvrez qui peut. Ne le laissez pas reposer.
Parler à d'autres personnes vous aidera à construire votre réseau personnel, et vous pourriez
surprenez-vous en trouvant des solutions à d'autres problèmes sans rapport avec
le chemin. Et cet ancien portefeuille ne cesse de grossir….
Toutes ces lectures et recherches prennent du temps, et le temps est déjà compté
fournir. Vous devez donc planifier à l'avance. Ayez toujours quelque chose à lire dans un
sinon moment mort. Le temps passé à attendre les médecins et les dentistes peut être
une excellente occasion de rattraper votre retard de lecture, mais assurez-vous d'apporter votre
votre propre magazine avec vous, ou vous pourriez vous retrouver à feuilleter un
article écorné de 1973 sur la Papouasie-Nouvelle-Guinée.
Esprit
Esprit critique
critique
Le dernier point important est de penser de manière critique à ce que vous lisez et entendez.
Vous devez vous assurer que les connaissances de votre portfolio sont exactes et
non influencé par le battage publicitaire des fournisseurs ou des médias. Méfiez-vous des fanatiques qui insistent
que leur dogme fournit la seule réponse - cela peut être ou non
applicable à vous et à votre projet.
Astuce
Astuce 99
Malheureusement, il n'y a plus que très peu de réponses simples. Mais avec votre
vaste portefeuille, et en appliquant une analyse critique à la
• • Sachez exactement ce que vous voulez demander et soyez aussi précis que possible.
Tu peux être.
• • Formez votre question avec soin et politesse. Se souvenir
que vous demandez une faveur ; ne semble pas exiger un
répondre.
• • Une fois que vous avez formulé votre question, arrêtez-vous et regardez à nouveau
pour la réponse. Choisissez des mots-clés et recherchez sur le Web.
Recherchez les FAQ appropriées (listes des questions fréquemment posées
questions avec réponses).
• • Décidez si vous voulez demander publiquement ou en privé. Usenet
les news-groups sont de merveilleux lieux de rencontre pour les experts
sur n'importe quel sujet, mais certaines personnes se méfient de ces groupes
caractère public. Alternativement, vous pouvez toujours envoyer votre
gourou directement. Dans tous les cas, utilisez une ligne d'objet significative.
("Besoin d'aide!!! " ne suffit pas.)
• • Asseyez-vous et soyez patient. Les gens sont occupés, et cela peut prendre
jours pour obtenir une réponse précise.
torrent de publications techniques que vous lirez, vous pourrez comprendre les
réponses complexes.
Défis
Défis
• • Sortez et parlez de technologie avec des personnes qui ne sont pas impliquées dans
votre projet actuel, ou qui ne travaillent pas pour la même entreprise.
Réseautez dans la cafétéria de votre entreprise, ou cherchez peut-être des collègues
passionnés lors d'une réunion d'un groupe d'utilisateurs locaux.
Communiquer!
Communiquer!
Mae
Mae West,
West, Belle
Belle des
des années
années 90,
90, 1934
1934
Peut-être pourrions-nous tirer une leçon de Mme West. Ce n'est pas seulement ce que vous avez,
mais aussi comment vous l'emballez. Avoir les meilleures idées, le meilleur code ou le
la plupart des pensées pragmatiques sont finalement stériles à moins que vous ne puissiez communiquer
avec d'autres personnes. Une bonne idée est orpheline sans efficacité
communication.
En tant que développeurs, nous devons communiquer à plusieurs niveaux. Nous passons des heures à
réunions, écouter et parler. Nous travaillons avec les utilisateurs finaux, en essayant de
comprendre leurs besoins. Nous écrivons du code, qui communique nos intentions
à une machine et documente notre réflexion pour les générations futures de
développeurs. Nous rédigeons des propositions et des mémos demandant et justifiant
ressources, en signalant notre situation et en suggérant de nouvelles approches. Et nous
travailler au quotidien au sein de nos équipes pour défendre nos idées, modifier l'existant
pratiques et en suggérer de nouvelles. Une grande partie de notre journée se passe
communiquer, nous devons donc bien le faire.
Nous avons dressé une liste d'idées que nous trouvons utiles.
Sachez
Sachez ce
ce que
que vous
vous voulez
voulez dire
dire
Planifiez ce que vous voulez dire. Rédigez un plan. Ensuite, demandez-vous : "Est-ce que cela
comprendre ce que j'essaie de dire ?" Affinez-le jusqu'à ce que ce soit le cas.
Cette approche ne s'applique pas seulement à la rédaction de documents. Quand tu es
face à une réunion importante ou à un appel téléphonique avec un gros client, notez
notez les idées que vous souhaitez communiquer et planifiez quelques stratégies
pour les faire passer.
Connaissez
Connaissez votre
votre public
public
Vous ne communiquez que si vous transmettez des informations. Pour ce faire, vous
devez comprendre les besoins, les intérêts et les capacités de votre public.
Nous nous sommes tous assis dans des réunions où un geek du développement aveugle les yeux de
le vice-président du marketing avec un long monologue sur les mérites de
une technologie arcanique. Ce n'est pas communiquer : c'est juste parler, et c'est
ennuyeux. [5]
[5] Le mot ennuyer vient du vieux français enui, qui signifie aussi « ennuyer ».
Formez une image mentale forte de votre auditoire. La sagesse acrostiche, montrée
dans la figure 1.1 à la page suivante, peut aider.
Illustration
Illustration 1.1.
1.1. L'acrostiche
L'acrostiche de
de la
la sagesse
sagesse -- comprendre
comprendre un
un public
public
Supposons que vous souhaitiez suggérer un système Web pour permettre à vos utilisateurs finaux de
soumettre des rapports de bogues. Vous pouvez présenter ce système de différentes manières,
en fonction de votre public. Les utilisateurs finaux apprécieront de pouvoir
soumettre des rapports de bogues 24 heures sur 24 sans attendre au téléphone. Ton
le service marketing pourra utiliser ce fait pour augmenter les ventes. Gestionnaires
du service support aura deux raisons d'être satisfait : moins de personnel
seront nécessaires et le signalement des problèmes sera automatisé. Enfin,
les développeurs peuvent profiter de l'expérience avec le client-serveur basé sur le Web
technologies et un nouveau moteur de base de données. En faisant le pitch approprié
à chaque groupe, vous les enthousiasmerez tous pour votre projet.
Choisissez
Choisissez votre
votre moment
moment
du mal par son patron car du code source a été perdu, et vous aurez un
auditeur plus réceptif à vos idées sur les référentiels de code source. Faire
ce que vous dites est pertinent dans le temps, ainsi que dans le contenu. Parfois tout ça
prend la simple question « Est-ce le bon moment pour parler de… ? »
Choisissez
Choisissez un
un style
style
Ajustez le style de votre prestation en fonction de votre public. Certaines personnes veulent un
séance d'information formelle "juste les faits". D'autres aiment une conversation longue et variée avant
se mettre au travail. Lorsqu'il s'agit de documents écrits, certains aiment
reçoivent de gros rapports reliés, tandis que d'autres s'attendent à recevoir un simple mémo ou un e-mail. Si
dans le doute, demandez.
Faites
Faites en
en sorte
sorte que
que ça
ça ait
ait l'air
l'air bien
bien
Vos idées sont importantes. Ils méritent un beau véhicule pour véhiculer
à votre public.
Il n'y a plus d'excuse aujourd'hui pour produire des documents imprimés de mauvaise qualité.
Les traitements de texte modernes (ainsi que les systèmes de mise en page tels que LaTeX et
troff) peut produire une sortie époustouflante. Vous devez apprendre quelques notions de base
commandes. Si votre traitement de texte prend en charge les feuilles de style, utilisez-les. (Ton
société a peut-être déjà défini des feuilles de style que vous pouvez utiliser.)
comment définir les en-têtes et pieds de page. Regardez les exemples de documents
inclus avec votre forfait pour avoir des idées sur le style et la mise en page. Vérifier la
l'orthographe, d'abord automatiquement puis à la main. Après poinçon, leur orthographe
manquez des steaks que le vérificateur peut nouer du ketch.
Impliquez
Impliquez votre
votre public
public
Nous constatons souvent que les documents que nous produisons finissent par être moins importants
que le processus que nous suivons pour les produire. Si possible, impliquez votre
lecteurs avec les premières ébauches de votre document. Obtenez leurs commentaires et choisissez
leur cerveau. Vous établirez une bonne relation de travail, et vous aurez probablement
produire un meilleur document dans le processus.
Soyez
Soyez un
un auditeur
auditeur
Il y a une technique que vous devez utiliser si vous voulez que les gens vous écoutent :
écoute-les. Même s'il s'agit d'une situation où vous avez toutes les informations,
même s'il s'agit d'une réunion formelle avec vous debout devant 20 costumes - si
vous ne les écoutez pas, ils ne vous écouteront pas.
Revenez
Revenez aux
aux gens
gens
Si vous posez une question à quelqu'un, vous pensez qu'il est impoli s'il ne le fait pas
répondre. Mais à quelle fréquence échouez-vous à contacter les gens lorsqu'ils vous envoient
un e-mail ou un mémo demandant des informations ou demandant une action ? Dans
le rush de la vie quotidienne, c'est facile à oublier. Répondez toujours aux e-mails et
messages vocaux, même si la réponse est simplement "Je vous recontacterai plus tard".
Tenir les gens informés les rend beaucoup plus indulgents face aux
glisser, et leur faire sentir que vous ne les avez pas oubliés.
Astuce
Astuce 10
10
C'est à la fois ce que vous dites et la façon dont vous le dites
À moins que vous ne travailliez dans le vide, vous devez être capable de communiquer. Le
plus efficace que la communication, plus vous devenez influent.
Tout ce que nous avons dit sur la communication par écrit s'applique
également au courrier électronique. Le courrier électronique a évolué au point où il
est le pilier des communications intra et interentreprises. Le courrier électronique est
utilisé pour discuter de contrats, pour régler des différends et comme preuve dans
rechercher. Mais pour une raison quelconque, les gens qui n'enverraient jamais un
un document papier minable est heureux de lancer un e-mail d'apparence désagréable
autour du monde.
Résumé
Résumé
• • Prototypes et Post-it
• • Des équipes pragmatiques
Défis
Défis
Dans ce chapitre, nous allons rassembler ces idées et ces processus. Les deux premiers
sections, Les maux de la duplication et de l'orthogonalité, sont étroitement liées.
Le premier vous avertit de ne pas dupliquer les connaissances dans vos systèmes,
la seconde de ne pas diviser une seule connaissance sur plusieurs systèmes
Composants.
À mesure quepertinentes.
applications le rythme du changement
Dans s'accélère,
Réversibilité, il devient
nous verrons de plustechniques
quelques en plus difficile
qui de garder notre
aider à isoler vos projets de leur environnement changeant.
Les deux sections suivantes sont également liées. Dans Tracer Bullets, on parle d'un
style de développement qui vous permet de rassembler les exigences, de tester les conceptions,
et implémenter le code en même temps. Si cela semble trop beau pour être vrai, c'est :
les développements des balles traçantes ne sont pas toujours applicables. Quand ils ne le sont pas,
Prototypes et Post-it vous montrent comment utiliser le prototypage pour tester
architectures, algorithmes, interfaces et idées.
Alors que l'informatique mûrit lentement, les concepteurs produisent de plus en plus
langues de niveau supérieur. Alors que le compilateur qui accepte "faire en sorte" n'a pas
encore été inventés, dans Domain Languages nous présentons quelques-uns plus modestes
suggestions que vous pouvez appliquer vous-même.
Enfin, nous travaillons tous dans un monde où le temps et les ressources sont limités. Tu peux
mieux survivre à ces deux pénuries (et garder vos patrons plus heureux) si vous
devenez bon pour déterminer combien de temps les choses prendront, ce que nous couvrons dans
Estimation.
Les
Les maux
maux de
de la
la duplication
duplication
En tant que programmeurs, nous collectons, organisons, maintenons et exploitons les connaissances.
Nous documentons le savoir dans un cahier des charges, nous le faisons vivre dans
code en cours d'exécution, et nous l'utilisons pour fournir les vérifications nécessaires pendant les tests.
La plupart des gens supposent que la maintenance commence lorsqu'une application est
publié, cette maintenance consiste à corriger les bogues et à améliorer les fonctionnalités. Nous
pense que ces gens ont tort. Les programmeurs sont constamment en maintenance
mode. Notre compréhension change de jour en jour. De nouvelles exigences arrivent comme
nous concevons ou codons. Peut-être que l'environnement change. Quel que soit le
raison, la maintenance n'est pas une activité discrète, mais une partie courante de la
tout le processus de développement.
Nous estimons que la seule façon de développer des logiciels de manière fiable et de rendre notre
développements plus faciles à comprendre et à maintenir, est de suivre ce que nous appelons
le principe DRY :
Chaque élément de connaissance doit avoir un seul, sans ambiguïté, faisant autorité
représentation au sein d'un système.
Vous constaterez que le principe DRY apparaît à maintes reprises tout au long
ce livre, souvent dans des contextes qui n'ont rien à voir avec le codage. Nous ressentons
qu'il s'agit de l'un des outils les plus importants du programmeur pragmatique
boîte à outils.
Dans cette section, nous décrirons les problèmes de duplication et suggérerons des
stratégies pour y faire face.
Comment
Comment se
se produit
produit la
la duplication
duplication ??
La plupart des doublons que nous voyons appartiennent à l'une des catégories suivantes :
Duplication
Duplication imposée
imposée
Parfois, la duplication semble nous être imposée. Les normes du projet peuvent
exiger des documents qui contiennent des informations en double, ou des documents qui
informations en double dans le code. Plusieurs plates-formes cibles nécessitent chacune
leurs propres langages de programmation, bibliothèques et développement
environnements, ce qui nous oblige à dupliquer des définitions et des procédures partagées.
Les langages de programmation eux-mêmes nécessitent certaines structures qui
informations en double. Nous avons tous travaillé dans des situations où nous nous sentions
impuissant à éviter les doubles emplois. Et pourtant, il existe souvent des moyens de garder
chaque élément de connaissance en un seul endroit, en respectant le principe DRY, et
rendre nos vies plus faciles en même temps. Voici quelques techniques :
Le principe DRY nous dit de garder les connaissances de bas niveau dans le code,
où il appartient, et réserver les commentaires pour d'autres, de haut niveau
explications. Sinon, nous dupliquons les connaissances, et chaque changement
signifie changer à la fois le code et les commentaires. Les commentaires seront
deviennent inévitablement obsolètes et les commentaires peu fiables sont pires que
aucun commentaire du tout. (Voir Tout est, pour
écrit plus d'informations sur
commentaires.)
Dave a déjà travaillé sur un commutateur télex international. Tout à fait compréhensible,
le client exigeait une spécification de test exhaustive et exigeait que le
le logiciel passe tous les tests à chaque livraison. Pour s'assurer que les tests sont exacts
reflète la spécification, l'équipe les a générés par programmation
du document lui-même. Lorsque le client a modifié son cahier des charges, le
la suite de tests a changé automatiquement. Une fois que l'équipe a convaincu le client que
la procédure était solide, générer des tests d'acceptation ne prenait généralement qu'un
quelques secondes.
Il n'y a pas de technique facile pour surmonter les exigences d'une langue.
Alors que certains environnements de développement cachent le besoin de fichiers d'en-tête en
en les générant automatiquement, et Object Pascal vous permet d'abréger
déclarations de fonction répétées, vous êtes généralement coincé avec ce que vous êtes
donné. Au moins avec la plupart des problèmes linguistiques, un fichier d'en-tête qui
n'est pas d'accord avec la mise en œuvre générera une certaine forme de compilation
ou erreur de liaison. Vous pouvez toujours vous tromper, mais au moins on vous dira
à ce sujet assez tôt.
Duplication
Duplication par
par inadvertance
inadvertance
Mais que se passe-t-il quand Sally est malade et qu'on doit changer de chauffeur ?
Truck et DeliveryRoute contiennent tous deux un chauffeur. Lequel change-t-on ?
Il est clair que cette duplication est mauvaise. Normalisez-le en fonction du sous-jacent
modèle d'entreprise - un camion a-t-il vraiment un chauffeur dans le cadre de son activité sous-jacente?
ensemble d'attributs ? Est-ce qu'un itinéraire? Ou peut-être qu'il doit y avoir un troisième objet qui
relie un conducteur, un camion et un itinéraire. Quelle que soit l'éventuelle
solution, évitez ce type de données non normalisées.
Il existe un type légèrement moins évident de données non normalisées qui se produit lorsque
nous avons plusieurs éléments de données qui sont mutuellement dépendants. Regardons
u en
A première vue, cette classe peut sembler raisonnable. Une ligne a clairement un début
et end, et aura toujours une longueur (même si elle est nulle). Mais nous avons
reproduction. La longueur est définie par les points de début et de fin : modifiez l'un des
les points et la longueur changent. Il est préférable de faire la longueur d'un
c ah
Plus tard dans le processus de développement, vous pouvez choisir de violer le DRY
principe pour des raisons de performance. Cela se produit fréquemment lorsque vous devez
cachez les données pour éviter de répéter des opérations coûteuses. L'astuce consiste à localiser
l'impact. La violation n'est pas exposée au monde extérieur : seule la
el s
oP tin
Cet exemple illustre également un problème important pour les objets orientés
langages tels que Java et C++. Dans la mesure du possible, utilisez toujours accessor
fonctions pour lire et écrire les attributs des objets. [1] Cela facilitera les choses
pour ajouter des fonctionnalités, telles que la mise en cache, à l'avenir.
[1] L'utilisation des fonctions d'accès est liée au principe d'accès uniforme de Meyer |Mey97b], qui stipule que "Tous les services
offerts par un module doivent être disponibles à travers une notation uniforme, qui ne trahisse pas s'ils sont
Duplication
Duplication impatiente
impatiente
Chaque projet est soumis à des contraintes de temps, des forces qui peuvent pousser les meilleurs d'entre nous à
prendre des raccourcis. Besoin d'une routine similaire à celle que vous avez écrite ? Vous serez
tenté de copier l'original et d'apporter quelques modifications. Besoin d'une valeur pour
représentent le nombre maximum de points ? Si je change le fichier d'en-tête, le
tout le projet sera reconstruit. Peut-être que je devrais juste utiliser un nombre littéral ici;
et ici; et ici. Besoin d'une classe comme celle du runtime Java ? La provenance est
disponible, alors pourquoi ne pas simplement le copier et apporter les modifications dont vous avez besoin (licence
nonobstant les dispositions) ?
La duplication impatiente est une forme facile à détecter et à gérer, mais il faut
discipline et une volonté de passer du temps à l'avance pour éviter la douleur plus tard.
Duplication
Duplication inter-développeurs
inter-développeurs
Nous estimons que la meilleure façon d'y faire face est d'encourager les activités actives et
communication fréquente entre les développeurs. Mettre en place des forums pour discuter
problèmes communs. (Sur des projets passés, nous avons mis en place un Usenet privé
groupes de discussion pour permettre aux développeurs d'échanger des idées et de poser des questions. Ce
fournit un moyen de communication non intrusif, même à travers plusieurs
sites – tout en conservant un historique permanent de tout ce qui a été dit.) Nommer un
membre de l'équipe en tant que bibliothécaire du projet, dont le travail consiste à faciliter la
échange de connaissances. Avoir une place centrale dans l'arborescence des sources où
des routines utilitaires et des scripts peuvent être déposés. Et mettez un point d'honneur à lire
le code source et la documentation d'autres personnes, de manière informelle ou pendant
revues de code. Vous n'êtes pas en train d'espionner, vous apprenez d'eux. Et
rappelez-vous que l'accès est réciproque - ne vous méprenez pas sur les autres
fouiller (piaffe ?) dans votre code non plus.
Astuce
Astuce 12
12
Ce que vous essayez de faire, c'est de favoriser un environnement où il est plus facile de trouver
et réutiliser des trucs existants plutôt que de les écrire soi-même. Si ce n'est pas facile, les gens
ne le fera pas. Et si vous ne parvenez pas à réutiliser, vous risquez de dupliquer les connaissances.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Orthogonalité
• • Manipulation de texte
• • Générateurs de codes
• • Refactorisation
• • Des équipes pragmatiques
• • Automatisation omniprésente
• • Tout est écrit
Orthogonalité
Orthogonalité
L'orthogonalité est un concept critique si vous voulez produire des systèmes qui sont
facile à concevoir, construire, tester et étendre. Cependant, la notion de
l'orthogonalité est rarement enseignée directement. Il s'agit souvent d'une caractéristique implicite de
diverses autres méthodes et techniques que vous apprenez. C'est une erreur. Une fois
vous apprenez à appliquer directement le principe d'orthogonalité, vous remarquerez une
amélioration immédiate de la qualité des systèmes que vous produisez.
Qu'est-ce
Qu'est-ce que
que l'orthogonalité
l'orthogonalité ??
Un
Un système
système non
non orthogonal
orthogonal
Vous faites un tour en hélicoptère du Grand Canyon lorsque le pilote, qui a fait
l'erreur évidente de manger du poisson pour le déjeuner, gémit et s'évanouit soudainement.
Heureusement, il vous a laissé planer à 100 pieds au-dessus du sol. vous rationalisez
que le levier de pas collectif [2] contrôle la portance globale, donc en l'abaissant légèrement
commencera une descente douce vers le sol. Cependant, lorsque vous l'essayez, vous
découvrir que la vie n'est pas si simple. Le nez de l'hélicoptère tombe et vous
commencer à descendre en spirale vers la gauche. Soudain, vous découvrez que vous pilotez un
système où chaque entrée de commande a des effets secondaires. Abaissez le
levier gauche et vous devez ajouter un mouvement vers l'arrière compensateur pour
le manche droit et appuyez sur la pédale droite. Mais alors chacun de ces
les modifications affectent à nouveau tous les autres contrôles. Soudain, vous jonglez avec un
système incroyablement complexe, où chaque changement a un impact sur tous les autres
contributions. Votre charge de travail est phénoménale : vos mains et vos pieds sont constamment
se déplaçant, essayant d'équilibrer toutes les forces en interaction.
[2] Les hélicoptères ont quatre commandes de base. Le cyclique est le bâton que vous tenez dans votre main droite. Déplacez-le, et l'hélicoptère
se déplace dans la direction correspondante. Votre main gauche tient le levier de pas collectif. Tirez dessus et vous augmentez le
pas sur toutes les pales, générant de la portance. Au bout du levier de pas se trouve la manette des gaz. Enfin, vous avez deux pédales, qui
varier la quantité de poussée du rotor de queue et ainsi aider à faire tourner l'hélicoptère.
Avantages
Avantages de
de l'orthogonalité
l'orthogonalité
Astuce
Astuce 13
13
Gagnez
Gagnez en
en productivité
productivité
• • Les modifications sont localisées, de sorte que le temps de développement et le temps de test sont
réduit. Il est plus facile d'écrire relativement petit, autonome
composants qu'un seul gros bloc de code. Des composants simples peuvent
être conçu, codé, testé à l'unité, puis oublié - il n'est pas nécessaire
pour continuer à modifier le code existant lorsque vous ajoutez un nouveau code.
• • Une approche orthogonale favorise également la réutilisation. Si les composants
ont des responsabilités précises et bien définies, elles peuvent être combinées
avec de nouveaux composants d'une manière qui n'était pas envisagée par leur
exécutants originaux. Plus vos systèmes sont faiblement couplés, plus
ils sont plus faciles à reconfigurer et à réorganiser.
• • Il y a un gain de productivité assez subtil quand on combine
composantes orthogonales. Supposons qu'un composant fait M distinct
choses et un autre fait N choses. S'ils sont orthogonaux et que vous
les combiner, le résultat fait M × N choses. Cependant, si les deux
les composants ne sont pas orthogonaux, il y aura un chevauchement et le résultat
fera moins. Vous obtenez plus de fonctionnalités par unité d'effort en combinant
composantes orthogonales.
Réduire
Réduire les
les risques
risques
• • Les sections de code malades sont isolées. Si un module est malade, il est
moins susceptibles de propager les symptômes dans le reste du système. C'est
aussi plus facile de le découper et de le transplanter dans quelque chose de nouveau et
en bonne santé.
• • Le système résultant est moins fragile. Faites de petits changements et
correctifs à un domaine particulier, et tous les problèmes que vous générez seront
limité à cette zone.
• • Un système orthogonal sera probablement mieux testé, car il
sera plus facile à concevoir et à exécuter des tests sur ses composants.
• • Vous ne serez pas aussi étroitement lié à un fournisseur, un produit ou un
plate-forme, car les interfaces avec ces composants tiers seront
être isolé à de plus petites parties du développement global.
Regardons quelques-unes des façons dont vous pouvez appliquer le principe d'orthogonalité
à votre travail.
Équipes
Équipes de
de projet
projet
Avez-vous remarqué à quel point certaines équipes de projet sont efficaces, avec tout le monde
savoir quoi faire et y contribuer pleinement, tandis que les membres des autres
les équipes se chamaillent constamment et ne semblent pas pouvoir sortir de chacune
le chemin de l'autre ?
Il s'agit souvent d'un problème d'orthogonalité. Lorsque les équipes sont organisées avec beaucoup de
se chevauchent, les membres sont confus quant aux responsabilités. Chaque changement nécessite
une réunion de toute l'équipe, car n'importe lequel d'entre eux pourrait être concerné.
Comment organisez-vous les équipes en groupes avec des responsabilités bien définies
et chevauchement minimal ? Il n'y a pas de réponse simple. Cela dépend en partie de la
projet et votre analyse des domaines de changement potentiel. Cela dépend aussi
sur les personnes dont vous disposez. Notre préférence est de commencer par séparer
infrastructure à partir de l'application. Chaque composante majeure de l'infrastructure
(base de données, interface de communication, couche middleware, etc.)
propre sous-équipe. Chaque division évidente de la fonctionnalité de l'application est similaire
divisé. Ensuite, nous examinons les personnes que nous avons (ou prévoyons d'avoir) et ajustons le
groupements en conséquence.
Vous pouvez obtenir une mesure informelle de l'orthogonalité d'une équipe de projet
structure. Voyez simplement combien de personnes doivent participer à la discussion
chaque modification demandée. Plus le nombre est grand, moins il est orthogonal
le groupe. De toute évidence, une équipe orthogonale est plus efficace. (Cela dit,
nous encourageons également les sous-équipes à communiquer constamment entre elles.)
Conception
Conception
La plupart des développeurs sont familiers avec la nécessité de concevoir des systèmes orthogonaux,
bien qu'ils puissent utiliser des mots tels que modulaire, basé sur des composants et
couches pour décrire le processus. Les systèmes doivent être composés d'un ensemble de
modules coopérants, dont chacun implémente des fonctionnalités indépendantes
des autres. Parfois, ces composants sont organisés en couches, chacune
offrant un niveau d'abstraction. Cette approche en couches est un moyen puissant de
concevoir des systèmes orthogonaux. Parce que chaque couche utilise uniquement les abstractions
fournis par les couches en dessous, vous avez une grande flexibilité pour changer
implémentations sous-jacentes sans affecter le code. La superposition réduit également
le risque d'emballement des dépendances entre les modules. Vous verrez souvent
superposition exprimée dans des diagrammes tels que la figure 2.1 à la page suivante.
Illustration
Illustration 2.1.
2.1. Schéma
Schéma de
de couche
couche typique
typique
Il existe un test simple pour la conception orthogonale. Une fois que vous avez vos composants
cartographié, demandez-vous : si je change radicalement les exigences derrière
une fonction particulière, combien de modules sont concernés ? Dans une orthogonale
système, la réponse devrait être "un". [3] Déplacer un bouton sur un panneau GUI
ne devrait pas nécessiter de modification du schéma de la base de données. Ajouter
l'aide contextuelle ne doit pas modifier le sous-système de facturation.
[3] En réalité, c'est naïf. À moins d'être extrêmement chanceux, la plupart des changements d'exigences du monde réel affecteront plusieurs
fonctions dans le système. Cependant, si vous analysez le changement en termes de fonctions, chaque changement fonctionnel devrait toujours
Demandez-vous également à quel point votre conception est découplée des changements dans le réel
monde. Utilisez-vous un numéro de téléphone comme identifiant client ? Quoi
se passe-t-il lorsque la compagnie de téléphone réattribue les indicatifs régionaux ? Ne comptez pas sur le
propriétés des choses que vous ne pouvez pas contrôler.
Boîtes
Boîtes àà outils
outils et
et bibliothèques
bibliothèques
Veillez à préserver l'orthogonalité de votre système lorsque vous introduisez
boîtes à outils et bibliothèques tierces. Choisissez judicieusement vos technologies.
Nous avons déjà travaillé sur un projet qui nécessitait qu'un certain corps de code Java
exécuter à la fois localement sur une machine serveur et à distance sur une machine cliente. Le
les alternatives pour distribuer les classes de cette manière étaient RMI et CORBA. Si un
classe ont été rendues accessibles à distance à l'aide de RMI, chaque appel à une télécommande
méthode dans cette classe pourrait potentiellement lever une exception, ce qui signifie
qu'une implémentation naïve nous obligerait à gérer l'exception
chaque fois que nos cours à distance étaient utilisés. L'utilisation de RMI ici n'est clairement pas
orthogonal : le code appelant nos classes distantes ne devrait pas être conscient de
leurs emplacements. L'alternative - en utilisant CORBA - n'imposait pas que
restriction : nous pourrions écrire du code qui ne connaîtrait pas l'emplacement de nos classes.
Lorsque vous apportez une boîte à outils (ou même une bibliothèque d'autres membres de votre
équipe), demandez-vous si cela impose des modifications à votre code qui ne devraient pas
Soyez là. Si un schéma de persistance d'objet est transparent, alors il est orthogonal.
Si cela vous oblige à créer ou à accéder à des objets d'une manière spéciale, alors ce n'est pas le cas.
Garder ces détails isolés de votre code a l'avantage supplémentaire de
faciliter le changement de fournisseur à l'avenir.
49 ]). AOP vous permet d'exprimer en un seul endroit un comportement qui serait autrement
répartis dans votre code source. Par exemple, les messages de journal sont
normalement généré en saupoudrant des appels explicites à une fonction de journalisation
tout au long de votre source. Avec AOP, vous implémentez la journalisation orthogonalement à
les choses étant enregistrées. En utilisant la version Java d'AOP, vous pouvez écrire un
message de journal lors de la saisie d'une méthode eFr de classe
Si vous intégrez cet aspect dans votre code, des messages de trace seront générés. Si
vous ne le faites pas, vous ne verrez aucun message. Dans tous les cas, votre source d'origine est
inchangé.
Codage
Codage
Chaque fois que vous écrivez du code, vous courez le risque de réduire l'orthogonalité de
ton application. Sauf si vous surveillez constamment non seulement ce que vous êtes
faire mais aussi le contexte plus large de l'application, vous pourriez
dupliquer involontairement des fonctionnalités dans un autre module, ou exprimer
connaissances existantes deux fois.
Il existe plusieurs techniques que vous pouvez utiliser pour maintenir l'orthogonalité :
• • Gardez votre code découplé. Écrivez du code timide - des modules qui ne le font pas
révéler tout ce qui n'est pas nécessaire aux autres modules et qui ne s'appuie pas sur
implémentations d'autres modules. Essayez la loi de Déméter [ LH89 ],
dont nous discutons dans Découplage et la loi de Déméter. Si tu as besoin
pour changer l'état d'un objet, demandez à l'objet de le faire pour vous. Par ici
votre code reste isolé de l'implémentation de l'autre code et
augmente les chances que vous restiez orthogonal.
• • Évitez les données globales. Chaque fois que votre code fait référence à des données globales,
il se lie aux autres composants qui partagent ces données. Même
les globales que vous avez uniquement l'intention de lire peuvent entraîner des problèmes (par exemple,
si vous avez soudainement besoin de changer votre code pour qu'il soit multithread). Dans
général, votre code est plus facile à comprendre et à maintenir si vous
transmettez explicitement tout contexte requis dans vos modules. Dans
applications orientées objet, le contexte est souvent passé en paramètre à
constructeurs d'objets. Dans un autre code, vous pouvez créer des structures
contenant le contexte et en faire circuler les références.
Prenez l'habitude d'être constamment critique de votre code. Cherchez n'importe quel
possibilités de le réorganiser pour améliorer sa structure et son orthogonalité.
Ce processus s'appelle le refactoring, et il est si important que nous avons dédié
une section (voir Refactoring ).
Essai
Essai
Construire des tests unitaires est en soi un test intéressant d'orthogonalité. Qu'est-ce que ça fait
prendre pour construire et lier un test unitaire? Devez-vous faire glisser un grand pourcentage
du reste du système juste pour obtenir un test à compiler ou à lier ? Si oui, vous avez
trouvé un module qui n'est pas bien découplé du reste du système.
La correction des bogues est également un bon moment pour évaluer l'orthogonalité du système en tant que
ensemble. Lorsque vous rencontrez un problème, évaluez la localisation du correctif. Faire
vous ne modifiez qu'un seul module, ou les modifications sont-elles dispersées dans tout le
tout le système ? Lorsque vous apportez un changement, résout-il tout ou fait-il autre chose ?
des problèmes surgissent mystérieusement? C'est une bonne occasion d'apporter
automatisation à supporter. Si vous utilisez un système de contrôle de code source (et vous
après avoir lu le contrôle du code source
), balisez les corrections de bugs lorsque vous vérifiez le code
denombre
le retour après le test.source
de fichiers Vous pouvez
affectésensuite exécuter
par chaque des rapports
correction mensuels analysant les tendances dans
de bogue.
Documentation
Documentation
Vivre
Vivre avec
avec l'orthogonalité
l'orthogonalité
Si vous êtes amené dans un projet où les gens luttent désespérément pour
faire des changements, et où chaque changement semble causer quatre autres choses à
se tromper, rappelez-vous le cauchemar avec l'hélicoptère. Le projet
n'est probablement pas conçu et codé orthogonalement. Il est temps de refactoriser.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
Des
Des exercices
exercices
1.
1. Vous écrivez une classe appelée Split, qui divise les lignes d'entrée en champs.
Laquelle des deux signatures de classe Java suivantes est la plus orthogonale
c o
2.
2. Ce qui conduira à un design plus orthogonal : dialogue modal ou modal
des boites?
3.
3. Qu'en est-il des langages procéduraux par rapport à la technologie objet ? Qui
aboutit à un système plus orthogonal ?
Réversibilité
Réversibilité
Rien n'est plus dangereux qu'une idée si c'est la seule que vous ayez.
Emil-Auguste
Emil-Auguste Chartier,
Chartier, Propos
Propos sur
sur la
la religion,
religion, 1938
1938
Les ingénieurs préfèrent des solutions simples et uniques aux problèmes. Des tests mathématiques qui permettent
vous proclamer avec une grande confiance que x = 2 sont beaucoup plus confortables
que des essais flous et chaleureux sur les innombrables causes de la Révolution française.
La direction a tendance à être d'accord avec les ingénieurs : des réponses simples et faciles
bien sur les feuilles de calcul et les plans de projet.
"Mais vous avez dit que nous utiliserions la base de données XYZ ! Nous avons terminé le codage du projet à 85 %,
nous ne pouvons pas changer maintenant !" protesta le programmeur. "Désolé, mais notre entreprise
a décidé de standardiser sur la base de données PDQ à la place, pour tous les projets. C'est hors de
mes mains. Nous n'aurons qu'à recoder. Vous travaillerez tous les week-ends
jusqu'à nouvel ordre."
Les changements n'ont pas besoin d'être aussi draconiens, ni même aussi immédiats. Mais comme
le temps passe et votre projet avance, vous risquez de vous retrouver coincé dans un
position intenable. À chaque décision cruciale, l'équipe du projet s'engage
à une cible plus petite - une version plus étroite de la réalité qui a moins d'options.
Au moment où de nombreuses décisions critiques ont été prises, la cible devient si
petit que s'il bouge, ou que le vent change de direction, ou un papillon à Tokyo
bat des ailes, vous manquez.[4] Et vous risquez de manquer énormément.
[4] Prenez un système non linéaire ou chaotique et appliquez une petite modification à l'une de ses entrées. Vous pouvez obtenir un grand et souvent
résultat imprévisible. Le papillon cliché battant des ailes à Tokyo pourrait être le début d'une chaîne d'événements qui finit par
générant une tornade au Texas. Cela ressemble-t-il à des projets que vous connaissez ?
Le problème est que les décisions critiques ne sont pas facilement réversibles.
Une fois que vous décidez d'utiliser la base de données de ce fournisseur, ou ce modèle architectural,
ou un certain modèle de déploiement (client-serveur versus autonome, par
exemple), vous êtes engagé dans une ligne de conduite qui ne peut être annulée,
sauf à grands frais.
Réversibilité
Réversibilité
De nombreux sujets abordés dans ce livre visent à produire des informations flexibles et adaptables.
logiciel. En respectant leurs recommandations, en particulier le DRY
principe (page 26), découplage (page 138) et utilisation des métadonnées (page
144) – nous n'avons pas à prendre autant de décisions critiques et irréversibles. C'est
une bonne chose, parce que nous ne prenons pas toujours les meilleures décisions la première fois
autour. Nous nous engageons dans une certaine technologie seulement pour découvrir que nous ne pouvons pas embaucher
suffisamment de personnes possédant les compétences nécessaires. Nous verrouillons un certain tiers
fournisseur juste avant d'être racheté par son concurrent. Exigences,
les utilisateurs et le matériel changent plus vite que nous ne pouvons développer le logiciel.
Supposons que vous décidiez, au début du projet, d'utiliser une base de données relationnelle de
fournisseur A. Beaucoup plus tard, lors des tests de performances, vous découvrez que le
la base de données est tout simplement trop lente, mais que la base de données d'objets du fournisseur B est
plus rapide. Avec la plupart des projets conventionnels, vous n'auriez pas de chance. La plupart
temps, les appels à des produits tiers sont enchevêtrés dans le code. Mais si
vous avez vraiment abstrait l'idée d'une base de données - au point où elle
fournit simplement la persistance en tant que service, vous avez alors la possibilité de
changer de cheval en cours de route.
De même, supposons que le projet commence comme un modèle client-serveur, mais ensuite, tard
dans le jeu, le marketing décide que les serveurs sont trop chers pour certains
clients, et ils veulent une version autonome. À quel point cela serait-il difficile pour
toi ? Comme il ne s'agit que d'un problème de déploiement, cela ne devrait pas prendre plus de quelques
jours. Si cela prendrait plus de temps, alors vous n'avez pas pensé à la réversibilité.
L'autre sens est encore plus intéressant. Et si le stand-alone
le produit que vous fabriquez doit être déployé dans un client-serveur ou n-tier
mode? Cela ne devrait pas être difficile non plus.
Astuce
Astuce 14
14
Architecture
Architecture flexible
flexible
Alors que beaucoup de gens essaient de garder leur code flexible, vous devez également penser
sur le maintien de la flexibilité dans les domaines de l'architecture, du déploiement et
intégration des fournisseurs.
Des technologies telles que CORBA peuvent aider à isoler des parties d'un projet de
changements dans le langage ou la plate-forme de développement. La performance de Java est-elle
sur cette plate-forme pas à la hauteur des attentes ? Recoder le client en C++, et
rien d'autre ne doit changer. Le moteur de règles en C++ n'est-il pas assez flexible ?
Passez à une version Smalltalk. Avec une architecture CORBA, vous avez
prendre un coup uniquement pour le composant que vous remplacez ; L'autre
les composants ne devraient pas être affectés.
Normalement, vous pouvez simplement cacher un produit tiers derrière un bien défini,
interface abstraite. En fait, nous avons toujours été en mesure de le faire sur n'importe quel projet
nous avons travaillé. Mais supposons que vous ne puissiez pas l'isoler aussi proprement. Et qu'est-ce qui se passerait si
vous avez dû saupoudrer généreusement certaines déclarations tout au long du code ? Mettre
cette exigence dans les métadonnées et utiliser un mécanisme automatique, tel que
comme Aspects (voir page 39) ou Perl, pour insérer les instructions nécessaires dans le
code lui-même. Quel que soit le mécanisme que vous utilisez, rendez-le réversible. Si quelque chose
est ajouté automatiquement, il peut également être retiré automatiquement.
Personne ne sait ce que l'avenir nous réserve, surtout pas nous ! Alors activez votre
code to rock-n-roll : "rocker" quand c'est possible, encaisser les coups quand c'est possible
devoir.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
Mais pensez à l'évolution du code dans le même sens qu'à une boîte pleine de
Les chats de Schrödinger : chaque décision aboutit à une version différente du
avenir. Combien de futurs possibles votre code peut-il supporter ? Qui
ceux sont plus probables? À quel point sera-t-il difficile de les soutenir lorsque le
le temps vient?
Oserez-vous ouvrir la boîte ?
Balles
Balles traçantes
traçantes
[5] Pour être pédant, il existe de nombreuses façons de tirer avec une mitrailleuse dans le noir, notamment en fermant les yeux et en pulvérisant
balles. Mais c'est une analogie, et nous sommes autorisés à prendre des libertés.
Les balles traçantes sont chargées à intervalles réguliers sur la ceinture de munitions aux côtés des
munition. Lorsqu'ils sont tirés, leur phosphore s'enflamme et laisse une
piste pyrotechnique du pistolet à tout ce qu'ils ont touché. Si les traceurs sont
toucher la cible, alors les balles régulières le sont aussi.
L'analogie est peut-être violente, mais elle s'applique aux nouveaux projets, notamment
lorsque vous construisez quelque chose qui n'a pas été construit auparavant. Comme le
artilleurs, vous essayez d'atteindre une cible dans le noir. Parce que vos utilisateurs ont
jamais vu un système comme celui-ci auparavant, leurs exigences peuvent être vagues.
Parce que vous utilisez peut-être des algorithmes, des techniques, des langages ou des bibliothèques
que vous ne connaissez pas, vous faites face à un grand nombre d'inconnues. Et
parce que les projets prennent du temps à se terminer, vous pouvez à peu près garantir le
l'environnement dans lequel vous travaillez changera avant que vous n'ayez terminé.
Les programmeurs pragmatiques, cependant, ont tendance à préférer l'utilisation de balles traçantes.
Code
Code qui
qui brille
brille dans
dans le
le noir
noir
Les balles traçantes fonctionnent parce qu'elles fonctionnent dans le même environnement et
sous les mêmes contraintes que les balles réelles. Ils arrivent rapidement à la cible,
Ainsi, le tireur reçoit une rétroaction immédiate. Et d'un point de vue pratique
ils sont une solution relativement bon marché.
Pour obtenir le même effet dans le code, nous recherchons quelque chose qui nous permette de
une exigence à certains aspects du système final rapidement, visiblement et
de façon répétée.
Astuce
Astuce 15
15
Nous avons déjà entrepris un projet complexe de marketing de base de données client-serveur.
Une partie de son exigence était la capacité de spécifier et d'exécuter des
requêtes. Les serveurs étaient une gamme de bases de données relationnelles et spécialisées.
L'interface graphique du client, écrite en Pascal Objet, utilisait un ensemble de bibliothèques C pour fournir
une interface avec les serveurs. La requête de l'utilisateur était stockée sur le serveur dans un
Notation de type Lisp avant d'être convertie en SQL optimisé juste avant
exécution. Il y avait beaucoup d'inconnues et de nombreux environnements différents,
et personne ne savait trop comment l'interface graphique devait se comporter.
C'était une excellente occasion d'utiliser le code traceur. Nous avons développé le
framework pour le front-end, des bibliothèques pour représenter les requêtes, et un
structure permettant de convertir une requête stockée en une requête spécifique à la base de données. Alors
nous avons tout assemblé et vérifié que cela fonctionnait. Pour cette version initiale, tous
nous pourrions faire était de soumettre une requête qui répertorie toutes les lignes d'une table, mais il
prouvé que l'interface utilisateur pouvait parler aux bibliothèques, les bibliothèques pouvaient sérialiser
et désérialiser une requête, et le serveur pourrait générer du SQL à partir du résultat.
Au cours des mois suivants, nous avons progressivement étoffé cette structure de base,
ajouter de nouvelles fonctionnalités en augmentant chaque composant du code traceur
en parallèle. Lorsque l'interface utilisateur a ajouté un nouveau type de requête, la bibliothèque s'est agrandie et le
La génération SQL a été rendue plus sophistiquée.
Le code traceur n'est pas jetable : vous l'écrivez pour toujours. Il contient toutes les erreurs
vérifier, structurer, documenter et auto-vérifier que tout élément de
code de production a. Il n'est tout simplement pas entièrement fonctionnel. Cependant, une fois que vous
avez réalisé une connexion de bout en bout entre les composants de votre
système, vous pouvez vérifier à quelle distance vous vous trouvez de la cible, en ajustant si
nécessaire. Une fois que vous êtes sur la cible, ajouter des fonctionnalités est facile.
Le développement de Tracer est cohérent avec l'idée qu'un projet n'est jamais
terminé : il y aura toujours des modifications à apporter et des fonctions à ajouter. C'est
une approche incrémentale.
Les
Les balles
balles traçantes
traçantes n'atteignent
n'atteignent pas
pas toujours
toujours leur
leur cible
cible
Les balles traçantes montrent ce que vous frappez. Ce n'est peut-être pas toujours la cible.
Vous ajustez ensuite votre objectif jusqu'à ce qu'ils soient sur la cible. C'est le but.
C'est la même chose avec le code traceur. Vous utilisez la technique dans des situations où
vous n'êtes pas sûr à 100% de l'endroit où vous allez. Vous ne devriez pas être surpris si
vos deux premières tentatives échouent : l'utilisateur dit "ce n'est pas ce que je voulais dire"
ou les données dont vous avez besoin ne sont pas disponibles lorsque vous en avez besoin, ou des problèmes de performances
semblent probables. Trouvez comment changer ce que vous avez pour le rapprocher du
objectif, et soyez reconnaissant d'avoir utilisé une méthodologie de développement Lean.
Un petit corps de code a une faible inertie, il est facile et rapide à changer. Vous allez
être en mesure de recueillir des commentaires sur votre application et de générer un nouveau, plus
version précise plus rapidement et à moindre coût qu'avec toute autre méthode. Et
parce que chaque composant majeur de l'application est représenté dans votre traceur
code, vos utilisateurs peuvent être sûrs que ce qu'ils voient est basé sur
réalité, pas seulement une spécification papier.
Code
Code traceur
traceur versus
versus prototypage
prototypage
Vous pourriez penser que ce concept de code traceur n'est rien de plus que
prototypage sous un nom agressif. Il existe une différence. Avec un
prototype, vous visez à explorer des aspects spécifiques du système final. Avec
un vrai prototype, vous jeterez tout ce que vous aurez assemblé quand
essayer le concept et le recoder correctement en utilisant les leçons que vous avez
appris.
Par exemple, supposons que vous produisiez une application qui aide les expéditeurs
déterminer comment emballer des boîtes de taille impaire dans des conteneurs. Parmi d'autres
problèmes, l'interface utilisateur doit être intuitive et les algorithmes que vous
utiliser pour déterminer l'emballage optimal sont très complexes.
Vous pouvez prototyper une interface utilisateur pour vos utilisateurs finaux dans un outil graphique. Toi
code juste assez pour rendre l'interface réactive aux actions de l'utilisateur. Une fois
ils ont accepté la mise en page, vous pouvez la jeter et la recoder, ceci
temps avec la logique métier qui la sous-tend, en utilisant le langage cible. De la même manière,
vous voudrez peut-être prototyper un certain nombre d'algorithmes qui effectuent le
emballage proprement dit. Vous pouvez coder des tests fonctionnels de haut niveau et indulgents
langage tel que Perl et coder des tests de performances de bas niveau dans quelque chose
plus près de la machine. Dans tous les cas, une fois votre décision prise, vous
recommencer et coder les algorithmes dans leur environnement final, en s'interfaçant
au monde réel. C'est du prototypage, et c'est très utile.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Prototypes
Prototypes et
et Post-it
Post-it
De nombreuses industries différentes utilisent des prototypes pour tester des idées spécifiques ;
le prototypage est beaucoup moins cher que la production à grande échelle. Les constructeurs automobiles, pour
par exemple, peut construire de nombreux prototypes différents d'une nouvelle conception de voiture. Chaque
l'un est conçu pour tester un aspect spécifique de la voiture - l'aérodynamique,
style, caractéristiques structurelles, etc. Peut-être qu'un modèle en argile sera
construit pour les essais en soufflerie, peut-être qu'un modèle en bois de balsa et ruban adhésif sera
faire pour le département artistique, et ainsi de suite. Certains constructeurs automobiles franchissent cette étape
plus loin, et font maintenant beaucoup de travail de modélisation sur ordinateur,
réduisant encore plus les coûts. De cette façon, des éléments risqués ou incertains peuvent être
essayé sans s'engager à construire l'objet réel.
Nous avons tendance à penser que les prototypes sont basés sur du code, mais ils ne doivent pas toujours
être. Comme les constructeurs automobiles, nous pouvons construire des prototypes à partir de différents matériaux.
Les post-it sont parfaits pour prototyper des éléments dynamiques tels que le flux de travail
et la logique d'application. Une interface utilisateur peut être prototypée sous la forme d'un dessin sur un
tableau blanc, comme une maquette non fonctionnelle dessinée avec un programme de peinture, ou
avec un constructeur d'interface.
Les prototypes sont conçus pour répondre à quelques questions seulement, ils sont donc beaucoup
moins cher et plus rapide à développer que les applications qui entrent en production. Le
le code peut ignorer des détails sans importance, sans importance pour vous pour le moment,
mais probablement très important pour l'utilisateur plus tard. Si vous prototypez un
GUI, par exemple, vous pouvez vous en tirer avec des résultats ou des données incorrects. Sur le
d'autre part, si vous étudiez simplement le calcul ou les performances
aspects, vous pouvez vous en sortir avec une interface graphique assez médiocre, ou peut-être même pas d'interface graphique
du tout.
Mais si vous vous trouvez dans un environnement où vous ne pouvez pas abandonner le
détails, alors vous devez vous demander si vous construisez vraiment un prototype
du tout. Peut-être qu'un développement de style balle traçante serait plus
approprié dans ce cas (voir Tracer Bullets ).
Choses
Choses àà prototyper
prototyper
• • Architecture
• • Nouvelle fonctionnalité dans un système existant
• • Structure ou contenu des données externes
• • Outils ou composants tiers
• • Les problèmes de performance
• • Design de l'interface utilisateur
Le prototypage est une expérience d'apprentissage. Sa valeur ne réside pas dans le code produit,
mais dans les leçons apprises. C'est vraiment le but du prototypage.
Astuce
Astuce 16
16
Prototype à apprendre
Comment
Comment utiliser
utiliser les
les prototypes
prototypes
Étant donné qu'un prototype doit passer sous silence les détails et se concentrer sur des aspects spécifiques
du système envisagé, vous souhaiterez peut-être mettre en œuvre des prototypes
en utilisant un langage de très haut niveau - plus élevé que le reste du projet
(peut-être un langage tel que Perl, Python ou Tcl). Une scénarisation de haut niveau
le langage vous permet de différer de nombreux détails (y compris la spécification des types de données) et
produisent toujours un morceau de code fonctionnel (bien qu'incomplet [6] Si
ouvous
lent).
besoin de prototyper des interfaces utilisateur, d'étudier des outils tels que Tcl/Tk, Visual
Basique, Powerbuilder ou Delphi.
[6] Si vous recherchez des performances absolues (et non relatives), vous devrez vous en tenir à un langage proche
Les langages de script fonctionnent bien comme "colle" pour combiner des éléments de bas niveau en
nouvelles combinaisons. Sous Windows, Visual Basic peut coller ensemble COM
contrôles. Plus généralement, vous pouvez utiliser des langages tels que Perl et Python pour
lier ensemble des bibliothèques C de bas niveau, soit manuellement, soit automatiquement avec
des outils tels que le SWIG disponible gratuitement].[En
URL
utilisant
28 cette approche, vous
peut assembler rapidement des composants existants dans de nouvelles configurations pour voir
comment les choses fonctionnent.
Architecture
Architecture de
de prototypage
prototypage
De nombreux prototypes sont construits pour modéliser l'ensemble du système sous
considération. Contrairement aux balles traçantes, aucun des modules individuels
dans le système prototype doivent être particulièrement fonctionnels. En fait, vous pouvez
même pas besoin de coder pour prototyper l'architecture - vous pouvez prototyper
sur un tableau blanc, avec des Post-it ou des fiches. Qu'est-ce que tu cherches
c'est ainsi que le système se tient dans son ensemble, reportant encore une fois les détails. Ici
sont des domaines spécifiques que vous voudrez peut-être rechercher dans l'architecture
prototype:
Comment
Comment ne
ne pas
pas utiliser
utiliser de
de prototypes
prototypes
Avant de vous lancer dans un prototypage basé sur du code, assurez-vous que tout le monde
comprend que vous écrivez du code jetable. Les prototypes peuvent être
trompeusement attrayant pour les gens qui ne savent pas qu'ils sont juste
prototypes. Vous devez indiquer très clairement que ce code est jetable,
incomplet et impossible à compléter.
Si vous sentez qu'il y a une forte possibilité dans votre environnement ou votre culture que
le but du code prototype peut être mal interprété, il vaut peut-être mieux
avec l'approche de la balle traçante. Vous vous retrouverez avec un cadre solide sur
sur lesquelles fonder le développement futur.
Lorsqu'il est utilisé correctement, un prototype peut vous faire économiser énormément de temps, d'argent,
la douleur et la souffrance en identifiant et en corrigeant les problèmes potentiels
tôt dans le cycle de développement - le moment où corriger les erreurs est à la fois
pas cher et facile.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Des
Des exercices
exercices
4.
4. Le marketing aimerait s'asseoir et réfléchir à quelques pages Web
conçoit avec vous. Ils pensent à des cartes d'images cliquables pour prendre
vers d'autres pages, etc. Mais ils ne peuvent pas décider d'un modèle pour le
image—c'est peut-être une voiture, ou un téléphone, ou une maison. Vous avez une liste de cibles
pages et contenu ; ils aimeraient voir quelques prototypes. Oh au fait,
vous avez 15 minutes. Quels outils pourriez-vous utiliser ?
Langues
Langues du
du domaine
domaine
Ludwig
Ludwig Von
Von Wittgenstein
Wittgenstein
Les langages informatiques influencent la façon dont vous pensez à un problème, et comment
vous pensez à communiquer. Chaque langue est accompagnée d'une liste de
fonctionnalités - mots à la mode tels que saisie statique ou dynamique, précoce ou
liaison tardive, modèles d'héritage (simple, multiple ou aucun) - tous
peut suggérer ou obscurcir certaines solutions. Concevoir une solution avec Lisp en
l'esprit produira des résultats différents d'une solution basée sur le style C
penser, et vice versa. A l'inverse, et nous pensons plus important encore, la
langage du domaine du problème peut également suggérer une solution de programmation.
Lorsque vous écoutez les utilisateurs d'un système proposé, ils peuvent être en mesure de dire
vous expliquez exactement comment le système devrait fonctionner :
Écouter les transactions définies par le règlement ABC 12.3 sur un ensemble de X.25
lignes, traduisez-les au format 43B de la société XYZ, retransmettez-les sur
la liaison montante du satellite et la stocker pour une analyse future.
Si vos utilisateurs disposent d'un certain nombre d'instructions bien délimitées, vous pouvez
inventer un mini-langage adapté au domaine d'application qui exprime
e ax
Ce langage n'a pas besoin d'être exécutable. Au départ, il pourrait s'agir simplement d'un moyen de
capturer les exigences de l'utilisateur - une spécification. Cependant, vous pouvez
voulons envisager d'aller plus loin et de mettre en œuvre
langue. Votre spécification est devenue un code exécutable.
Une fois que vous avez écrit l'application, les utilisateurs vous donnent une nouvelle exigence :
les transactions avec des soldes négatifs ne doivent pas être stockées et doivent être envoyées
er t
C'était facile, n'est-ce pas ? Avec le support approprié en place, vous pouvez
programme beaucoup plus proche du domaine d'application. Nous ne suggérons pas que
vos utilisateurs finaux programment réellement dans ces langages. Au lieu de cela, vous donnez
vous un outil qui vous permet de travailler plus près de leur domaine.
Astuce
Astuce 17
17
Implémentation
Implémentation d'un
d'un mini-langage
mini-langage
Dans sa forme la plus simple, un mini-langage peut être dans un langage orienté ligne, facilement analysé
format. En pratique, nous utilisons probablement ce formulaire plus que tout autre. Ça peut
être analysé simplement à l'aide d'instructions switch ou d'expressions régulières dans
Vous pouvez également implémenter un langage plus complexe, avec un langage plus formel
syntaxe. L'astuce ici est de définir d'abord la syntaxe en utilisant une notation telle que
BNF. [7] Une fois que vous avez spécifié votre grammaire, il est normalement trivial de
convertissez-le en syntaxe d'entrée pour un générateur d'analyseur. C et C++
les programmeurs utilisent yacc (ou son implémentation librement disponible,
bison [ URL 27 ]) depuis des années. Ces programmes sont documentés en détail dans le
livre Lex et Yacc [ LMB92 ]. Les programmeurs Java peuvent essayer javaCC, qui peut
être trouvé à [ URL 26 ]. La réponse à l'exercice 7 de la page 282 montre un analyseur
écrit en utilisant
bison. Comme il le montre, une fois que vous connaissez la syntaxe, ce n'est vraiment pas un
beaucoup de travail pour écrire des mini-langages simples.
[7] BNF, ou Backus-Naur Form, vous permet de spécifier des grammaires hors-contexte de manière récursive. Tout bon livre sur le compilateur
[ 8
Langages
Langages de
de données
données et
et langages
langages impératifs
impératifs
Les langages que vous implémentez peuvent être utilisés de deux manières différentes.
Les langages de données produisent une certaine forme de structure de données utilisée par une application.
Ces langages sont souvent utilisés pour représenter les informations de configuration.
Par exemple, le programme sendmail est utilisé dans le monde entier pour
routage des e-mails sur Internet. Il possède de nombreuses fonctionnalités excellentes et
avantages, qui sont contrôlés par un fichier de configuration de mille lignes, écrit
e n u
F=sl
De toute évidence, la lisibilité n'est pas l'un des points forts de sendmail.
Illustration
Illustration 2.2.
2.2. Fichier
Fichier .rc
.rc Windows
Windows
Les langages impératifs vont encore plus loin. Ici la langue est
réellement exécuté, et peut donc contenir des instructions, des constructions de contrôle et
similaire (comme le script de la page 58).
Vous pouvez également utiliser vos propres langages impératifs pour faciliter le programme
entretien. Par exemple, il peut vous être demandé d'intégrer des informations provenant de
une application héritée dans votre nouveau développement d'interface graphique. Une façon courante de
y parvenir se fait par grattage d'écran; votre application se connecte au
application mainframe comme s'il s'agissait d'un utilisateur humain normal, émettant
frappes et "lire" les réponses qu'il reçoit. Vous pouvez scripter le
interaction à l'aide d'un mini-langage.[9]
[9] En fait, vous pouvez acheter des outils qui ne prennent en charge que ce type de script. Vous pouvez également rechercher des packages open source tels que
ol c
Lorsque l'application détermine qu'il est temps d'entrer un numéro de sécurité sociale
nombre, il invoque l'interpréteur sur ce script, qui contrôle alors le
transaction. Si l'interpréteur est intégré à l'application, les deux
peut même partager des données directement (par exemple, via un mécanisme de rappel).
Langages
Langages autonomes
autonomes et
et intégrés
intégrés
Un mini-langage n'a pas besoin d'être utilisé directement par l'application pour être
utile. Plusieurs fois, nous pouvons utiliser un langage de spécification pour créer des artefacts
(y compris les métadonnées) qui sont compilées, lues ou autrement utilisées par le
programme lui-même (voir Métaprogrammation).
Par exemple, à la page 100, nous décrivons un système dans lequel nous avons utilisé Perl pour
générer un grand nombre de dérivations à partir d'un schéma original
spécification. Nous avons inventé un langage commun pour exprimer la base de données
schéma, puis généré toutes les formes dont nous avions besoin—SQL, C, Web
pages, XML et autres. L'application n'a pas utilisé la spécification
directement, mais il s'appuyait sur la sortie qu'il produisait.
Il est courant d'intégrer des langages impératifs de haut niveau directement dans votre
application, afin qu'ils s'exécutent lorsque votre code s'exécute. Il s'agit clairement d'un
capacité puissante; vous pouvez modifier le comportement de votre application en
changer les scripts qu'il lit, le tout sans compiler. Cela peut considérablement
simplifier la maintenance dans un domaine d'application dynamique.
Développement
Développement facile
facile ou
ou maintenance
maintenance facile
facile ??
Nous avons examiné plusieurs grammaires différentes, allant du simple
formats orientés ligne à des grammaires plus complexes qui ressemblent à de vrais
langues. Étant donné que sa mise en œuvre demande des efforts supplémentaires, pourquoi choisiriez-vous un
grammaire plus complexe ?
Étant donné que la plupart des applications dépassent leur durée de vie prévue, vous êtes
probablement mieux de mordre la balle et d'adopter le plus complexe et
langage lisible à l'avant. L'effort initial sera remboursé plusieurs fois dans
réduction des coûts d'assistance et de maintenance.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Métaprogrammation
Défis
Défis
Des
Des exercices
exercices
5.
5. Nous voulons implémenter un mini-langage pour contrôler un dessin simple
package (peut-être un système de graphiques de tortues). La langue consiste en
commandes à une seule lettre. Certaines commandes sont suivies d'un seul
on bm
N 1 #p
6.
6. Concevoir une grammaire BNF pour analyser une spécification temporelle. La totalité de la
el s
7. pIm
7. léem
bison, ou un analyseur-générateur similaire.
8.
8. faire
Implémentez l'analyseur de temps en utilisant Perl. [Astuce : Expressions régulières
de bons analyseurs.]
Estimation
Estimation
Rapide! Combien de temps faudra-t-il pour envoyer Guerre et Paix sur une ligne modem 56k ?
De combien d'espace disque aurez-vous besoin pour un million de noms et d'adresses ?
Combien de temps faut-il pour qu'un bloc de 1 000 octets passe par un routeur ? Combien
mois faudra-t-il pour livrer votre projet?
À un certain niveau, ce sont toutes des questions dénuées de sens - elles manquent toutes
information. Et pourtant, ils peuvent tous être répondus, tant que vous êtes
estimation confortable. Et, dans le processus de production d'une estimation, vous
apprenez à mieux comprendre le monde dans lequel vivent vos programmes.
Astuce
Astuce 18
18
Quelle
Quelle est
est la
la précision
précision suffisante
suffisante ??
Dans une certaine mesure, toutes les réponses sont des estimations. C'est juste que certains sont plus
précis que d'autres. Donc, la première question que vous devez vous poser quand
quelqu'un vous demande un devis est le contexte dans lequel votre réponse sera
être pris. Ont-ils besoin d'une grande précision ou recherchent-ils un stade approximatif
chiffre?
• • Si votre grand-mère vous demande quand vous arriverez, elle est probablement
se demandant s'il faut vous préparer un déjeuner ou un dîner. D'autre part,
un plongeur coincé sous l'eau et à court d'air est probablement
intéressé par une réponse à la seconde près.
• • Quelle est la valeur de p ? Si vous vous demandez combien de bordure à
acheter pour mettre autour d'un parterre de fleurs circulaire, alors "3" est probablement bon
assez. [10] Si vous êtes à l'école, alors peut-être que "22/7" est un bon
approximation. Si vous êtes à la NASA, alors peut-être que 12 décimales suffiront
faire.
[10] « 3 » est également apparemment assez bon si vous êtes un législateur. En 1897, le projet de loi No.
246 a tenté de décréter que désormais p devrait avoir la valeur "3". Le projet de loi a été déposé indéfiniment à sa
deuxième lecture lorsqu'un professeur de mathématiques a souligné que leurs pouvoirs ne s'étendaient pas tout à fait à la réussite
L'un des aspects intéressants de l'estimation est que les unités que vous utilisez
faire une différence dans l'interprétation du résultat. Si tu dis ça
quelque chose prendra environ 130 jours ouvrables, alors les gens s'attendront à
qu'il soit assez proche. Cependant, si vous dites "Oh, environ six mois", alors
ils savent qu'il faut le chercher à tout moment entre cinq et sept mois à partir de maintenant.
Les deux chiffres représentent la même durée, mais "130 jours" probablement
implique un degré de précision plus élevé que vous ne le pensez. Nous vous recommandons
échelle des estimations de temps comme suit :
Estimation
Estimation du
du devis
devis en
en
1-15 jours jours
3-8 semaines semaines
8-30 semaines mois
30+ semaines réfléchissez bien avant de donner une estimation
Ainsi, si après avoir effectué tous les travaux nécessaires, vous décidez qu'un projet prendra
125 jours ouvrables (25 semaines), vous voudrez peut-être fournir une estimation de
"environ six mois."
Les mêmes concepts s'appliquent aux estimations de n'importe quelle quantité : choisir les unités de
votre réponse pour refléter l'exactitude que vous avez l'intention de transmettre.
D'où
D'où viennent
viennent les
les estimations
estimations ??
Toutes les estimations sont basées sur des modèles du problème. Mais avant que nous soyons trop
profondément dans les techniques de construction de modèles, nous devons mentionner une base
astuce d'estimation qui donne toujours de bonnes réponses : demandez à quelqu'un qui
déjà fait. Avant de vous engager trop dans la construction de modèles, lancez
autour de quelqu'un qui a été dans une situation similaire dans le passé.
Voyez comment leur problème a été résolu. Il est peu probable que vous trouviez jamais un exact
match, mais vous seriez surpris du nombre de fois où vous réussirez à dessiner
sur les expériences des autres.
Comprendre
Comprendre ce
ce qui
qui est
est demandé
demandé
Construire
Construire un
un modèle
modèle du
du système
système
La construction de modèles peut être à la fois créative et utile à long terme. Souvent, le
le processus de construction du modèle conduit à la découverte de modèles sous-jacents
et des processus qui n'étaient pas apparents à la surface. Vous voudrez peut-être même
réexaminer la question initiale : "Vous avez demandé un devis pour faire X.
Cependant, il semble que Y, une variante de X, pourrait être fait en environ la moitié du temps,
et vous perdez une seule fonctionnalité."
Décomposer
Décomposer le
le modèle
modèle en
en composants
composants
Une fois que vous avez un modèle, vous pouvez le décomposer en composants. Tu auras besoin
découvrir les règles mathématiques qui décrivent comment ces composants
interagir. Parfois, un composant apporte une valeur unique qui est ajoutée
dans le résultat. Certains composants peuvent fournir des facteurs multiplicateurs, alors que
d'autres peuvent être plus compliqués (comme ceux qui simulent l'arrivée de
trafic à un nœud).
Vous constaterez que chaque composant aura généralement des paramètres qui affectent
comment il contribue au modèle global. A ce stade, identifiez simplement chaque
paramètre.
Donnez
Donnez une
une valeur
valeur àà chaque
chaque paramètre
paramètre
Une fois que vous avez ventilé les paramètres, vous pouvez passer en revue et attribuer
chacun une valeur. Vous vous attendez à introduire des erreurs dans cette étape. L'astuce
est de déterminer quels paramètres ont le plus d'impact sur le résultat, et
concentrez-vous sur leur bon fonctionnement. Typiquement, les paramètres dont
les valeurs ajoutées dans un résultat sont moins significatives que celles qui sont
multiplié ou divisé. Doubler la vitesse d'une ligne peut doubler la quantité de données
reçu en une heure, tandis que l'ajout d'un délai de transit de 5 ms n'aura pas
effet notable.
Calculer
Calculer les
les réponses
réponses
Ce n'est que dans les cas les plus simples qu'une estimation aura une réponse unique. Toi
pourrait être heureux de dire "Je peux marcher cinq pâtés de maisons en 15 minutes."
Cependant, à mesure que les systèmes deviennent plus complexes, vous voudrez protéger votre
réponses. Exécutez plusieurs calculs, en faisant varier les valeurs de la critique
paramètres, jusqu'à ce que vous trouviez ceux qui pilotent vraiment le modèle. UN
tableur peut être d'une grande aide. Ensuite, formulez votre réponse en fonction de ces
paramètres. "Le temps de réponse est d'environ trois quarts de seconde si le
système a un bus SCSI et 64 Mo de mémoire, et une seconde avec 48 Mo
mémoire." (Remarquez comment "trois quarts de seconde" transmet un autre
sensation de précision supérieure à 750 ms.)
Pendant la phase de calcul, vous pouvez commencer à obtenir des réponses qui semblent
étrange. Ne soyez pas trop rapide pour les rejeter. Si votre arithmétique est correcte,
votre compréhension du problème ou votre modèle est probablement erroné. C'est
informations précieuses.
Gardez
Gardez une
une trace
trace de
de vos
vos prouesses
prouesses d'estimation
d'estimation
Nous pensons que c'est une bonne idée d'enregistrer vos estimations afin que vous puissiez voir à quel point
vous étiez. Si une estimation globale impliquait le calcul de sous-estimations, gardez
trace de ceux-ci également. Vous constaterez souvent que vos estimations sont assez bonnes, en
En fait, après un certain temps, vous vous y attendrez.
Lorsqu'une estimation s'avère erronée, ne vous contentez pas de hausser les épaules et de vous en aller. Trouver
pourquoi il diffère de votre supposition. Peut-être avez-vous choisi des paramètres qui
ne correspondait pas à la réalité du problème. Peut-être que votre modèle était erroné.
Quelleprochaine
votre que soit laestimation
raison, prenez le temps de découvrir ce qui s'est passé. Si tu fais,
sera meilleure.
Estimation
Estimation des
des calendriers
calendriers de
de projet
projet
Astuce
Astuce 19
19
Cela peut ne pas être populaire auprès de la direction, qui veut généralement un seul,
numéro dur et rapide avant même le début du projet. Vous devrez aider
qu'ils comprennent que l'équipe, leur productivité et l'environnement
déterminera le calendrier. En formalisant cela, et en affinant le planning
dans le cadre de chaque itération, vous leur donnerez la planification la plus précise
estimations que vous pouvez.
Que
Que dire
dire lorsqu'on
lorsqu'on lui
lui demande
demande une
une estimation
estimation
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Vitesse de l'algorithme
Défis
Défis
9.
9. On vous demande "Qui a une bande passante plus élevée : un 1Mbps
ligne de communication ou une personne marchant entre deux ordinateurs avec
une bande complète de 4 Go dans leur poche ? » Quelles contraintes imposerez-vous à votre
réponse pour vous assurer que la portée de votre réponse est correcte ? (Pour
exemple, vous pourriez dire que le temps nécessaire pour accéder à la bande est
ignoré.)
dix.
dix. Alors, qui a la bande passante la plus élevée ?
Chaque artisan commence son voyage avec un ensemble de base de bonne qualité
outils. Un menuisier peut avoir besoin de règles, de gabarits, de quelques scies, de bonnes
rabots, ciseaux fins, perceuses et entretoises, maillets et pinces. Ces outils permettront
être choisi avec amour, sera construit pour durer, effectuera des travaux spécifiques avec peu
se chevauchent avec d'autres outils et, peut-être le plus important, se sentiront bien dans
les mains du menuisier en herbe.
Les outils amplifient votre talent. Meilleurs sont vos outils et mieux vous savez
comment les utiliser, plus vous pouvez être productif. Commencez avec un ensemble de base de
outils généralement applicables. Au fur et à mesure que vous acquérez de l'expérience et que vous rencontrez
exigences particulières, vous ajouterez à cet ensemble de base. Comme l'artisan, attendez-vous
à ajouter régulièrement à votre boîte à outils. Soyez toujours à l'affût de meilleures façons de
faire des choses. Si vous rencontrez une situation où vous sentez que votre
les outils ne peuvent pas le couper, faites une note pour rechercher quelque chose de différent ou plus
puissant qui aurait aidé. Laissez le besoin piloter vos acquisitions.
Dans ce chapitre, nous parlerons de l'investissement dans votre propre boîte à outils de base. Comme avec
toute bonne discussion sur les outils, nous commencerons (dans The Power of Plain Text) par
en regardant vos matières premières, les choses que vous allez façonner. De là, nous allons
passer à l'établi ou, dans notre cas, à l'ordinateur. Comment pouvez-vous utiliser votre
ordinateur pour tirer le meilleur parti des outils que vous utilisez ? Nous en discuterons dans Shell
Jeux. Maintenant que nous avons du matériel et un banc sur lequel travailler, nous allons passer au
outil que vous utiliserez probablement plus que tout autre, votre éditeur. Dans l'édition avancée,
nous vous proposerons des moyens de vous rendre plus efficace.
Pour nous assurer que nous ne perdons jamais rien de notre précieux travail, nous devons toujours
utiliser un système de contrôle du code source, même pour des choses telles que notre
carnet d'adresses! Et, puisque M. Murphy était vraiment un optimiste après tout, vous
ne peut pas être un grand programmeur jusqu'à ce que vous deveniez hautement qualifié en débogage.
Vous aurez besoin de colle pour lier une grande partie de la magie ensemble. Nous discutons de certains
possibilités, telles que awk, Perl et Python, dans la manipulation de texte.
Tout comme les menuisiers construisent parfois des gabarits pour guider la construction de
pièces complexes, les programmeurs peuvent écrire du code qui écrit lui-même du code. Nous
discutez-en dans Générateurs de code.
Passez du temps à apprendre à utiliser ces outils et, à un moment donné, vous serez
surpris de découvrir vos doigts se déplaçant sur le clavier, manipulant
texte sans pensée consciente. Les outils seront devenus des extensions de
tes mains.
La
La puissance
puissance du
du texte
texte brut
brut
En tant que programmeurs pragmatiques, notre matériau de base n'est pas le bois ou le fer, c'est
connaissance. Nous rassemblons les exigences en tant que connaissances, puis exprimons que
connaissance de nos conceptions, implémentations, tests et documents. Et nous
croient que le meilleur format pour stocker les connaissances de manière persistante est le texte brut.
Avec le texte brut, nous nous donnons la capacité de manipuler les connaissances,
à la fois manuellement et par programme, en utilisant pratiquement tous les outils de notre
disposition.
Qu'est-ce
Qu'est-ce que
que le
le texte
texte brut
brut ??
Le texte brut est composé de caractères imprimables sous une forme qui peut être lue et
compris directement par les gens. Par exemple, bien que l'extrait suivant
est composé de caractères imprimables, il n'a pas de sens.
C ah
aDr gwin
Le texte brut ne signifie pas que le texte n'est pas structuré ; XML, SGML et
HTML sont d'excellents exemples de texte brut qui a une structure bien définie.
Vous pouvez faire tout ce que vous pourriez faire avec du texte brut avec du binaire
format, y compris la gestion des versions.
ym p
C o
Le problème avec la plupart des formats binaires est que le contexte nécessaire pour
comprendre que les données sont distinctes des données elles-mêmes. Vous êtes artificiellement
séparer les données de leur sens. Les données peuvent également être cryptées ; il
n'a absolument aucun sens sans la logique d'application pour l'analyser. Avec
texte brut, cependant, vous pouvez obtenir un flux de données auto-descriptif qui est
indépendamment de l'application qui l'a créé.
Astuce
Astuce 20
20
Désavantages
Désavantages
Il y a deux inconvénients majeurs à utiliser du texte brut : (1) Cela peut prendre plus de temps
espace à stocker qu'un format binaire compressé, et (2) il peut être
informatiquement plus coûteux à interpréter et à traiter un fichier texte brut.
En fonction de votre application, l'une ou l'autre de ces situations ou les deux peuvent être
inacceptable - par exemple, lors du stockage de données de télémétrie par satellite, ou
format interne d'une base de données relationnelle.
Mais même dans ces situations, il peut être acceptable de stocker des métadonnées sur
les données brutes en clair (voir Métaprogrammation).
Certains développeurs peuvent craindre qu'en mettant les métadonnées en texte brut, ils ne soient
l'exposer aux utilisateurs du système. Cette peur est déplacée. Les données binaires peuvent
être plus obscur que le texte brut, mais il n'est pas plus sûr. Si vous vous inquiétez de
les utilisateurs voyant des mots de passe, chiffrez-les. Si vous ne voulez pas qu'ils changent
Le
Le pouvoir
pouvoir du
du texte
texte
Étant donné que les fonctionnalités plus grandes et plus lentes ne sont pas les plus fréquemment demandées par
utilisateurs, pourquoi s'embêter avec du texte brut ? Quels sont les bénéfices?
Assurance
Assurance contre
contre l'obsolescence
l'obsolescence
Les formes de données lisibles par l'homme et les données auto-descriptives survivront à tous
d'autres formes de données et les applications qui les ont créées. Période.
Tant que les données survivent, vous aurez une chance de pouvoir utiliser
il - potentiellement longtemps après que l'application originale qui l'a écrit est caduque.
Vous pouvez analyser un tel fichier avec seulement une connaissance partielle de son format ; avec
la plupart des fichiers binaires, vous devez connaître tous les détails de l'ensemble du format afin
pour l'analyser avec succès.
Considérez un fichier de données d'un système[2] qui vous est donné. Tu sais
hérité
peu sur l'application d'origine ; tout ce qui est important pour vous, c'est qu'il
maintenu une liste des numéros de sécurité sociale des clients, que vous devez trouver
et extrait. Parmi les données, vous voyez
[ ]2
Reconnaissant le format d'un numéro de sécurité sociale, vous pouvez rédiger rapidement un
petit programme pour extraire ces données, même si vous n'avez aucune information sur
rien d'autre dans le fichier.
aM si
0FIELD1
Pendant qu'on y est,
Effet
Effet de
de levier
levier
Pratiquement tous les outils de l'univers informatique, à partir du code source
systèmes de gestion aux environnements de compilateur aux éditeurs et autonomes
filtres, peuvent fonctionner sur du texte brut.
La philosophie Unix
Par exemple, supposons que vous ayez un déploiement de production d'un grand
application avec un fichier de configuration complexe spécifique sendmail
au sitearrive
(
à l'esprit). Si ce fichier est en texte brut, vous pouvez le placer sous un code source
système de contrôle (voir Contrôle du code ), source
afin que vous conserviez automatiquement un
historique de tous les changements. Les outils de comparaison de fichiers tels que diff et fc vous permettent
pour voir en un coup d'œil les modifications apportées, tandis que la somme vous permet de
générer une somme de contrôle pour surveiller le fichier contre les accidents (ou malveillants)
modification.
Tests
Tests plus
plus faciles
faciles
Si vous utilisez du texte brut pour créer des données synthétiques afin de piloter des tests système, il est alors
une simple question d'ajouter, de mettre à jour ou de modifier les données de test sans avoir à
créer des outils spéciaux pour le faire. De même, la sortie en texte brut de
les tests de régression peuvent être trivialement analysés (avec diff, par exemple) ou
soumis à un examen plus approfondi avec Perl, Python ou un autre
outil de script.
Plus
Plus petit
petit dénominateur
dénominateur commun
commun
Même dans l'avenir des agents intelligents basés sur XML qui voyagent dans la nature et
Internet dangereux de manière autonome, négociant l'échange de données entre
eux-mêmes, le fichier texte omniprésent sera toujours là. En fait, dans
environnements hétérogènes, les avantages du texte brut peuvent l'emporter sur tous
des inconvénients. Vous devez vous assurer que toutes les parties peuvent communiquer
utilisant une norme commune. Le texte brut est cette norme.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
• • Concevoir une petite base de données de carnet d'adresses (nom, numéro de téléphone,
et ainsi de suite) en utilisant une représentation binaire simple dans votre
langue de choix. Faites-le avant de lire le reste de ce défi.
1. 1. Traduisez ce format en texte brut à l'aide de XML.
2. 2. Pour chaque version, ajoutez un nouveau champ de longueur variable appelé
directions dans lesquelles vous pourriez entrer des directions vers chaque personne
loger.
Quels sont les problèmes liés à la gestion des versions et à l'extensibilité ? Qui
formulaire était plus facile à modifier? Qu'en est-il de la conversion des données existantes ?
Jeux
Jeux de
de coquillages
coquillages
La réponse simple est non." Les interfaces graphiques sont merveilleuses, et elles peuvent être
plus rapide et plus pratique pour certaines opérations simples. Déplacement de fichiers,
lire des e-mails encodés MIME et taper des lettres sont toutes des choses que vous
pourrait vouloir faire dans un environnement graphique. Mais si tu fais tout ton travail
en utilisant des interfaces graphiques, vous manquez toutes les capacités de votre
environnement. Vous ne pourrez pas automatiser les tâches courantes ni utiliser la totalité
puissance des outils mis à votre disposition. Et vous ne pourrez pas combiner vos
outils pour créer des outils de macro personnalisés. Un avantage des interfaces graphiques est
WYSIWYG—ce que vous voyez est ce que vous obtenez. L'inconvénient est
WYSIAYG—ce que vous voyez est tout ce que vous obtenez.
Les environnements GUI sont normalement limités aux capacités que leurs
concepteurs prévus. Si vous avez besoin d'aller au-delà du modèle, le concepteur
à condition que vous n'ayez généralement pas de chance - et le plus souvent, vous avez besoin
aller au-delà du modèle. Les programmeurs pragmatiques ne se contentent pas de couper du code, ou
développer des modèles d'objets, ou écrire de la documentation, ou automatiser la construction
processus - nous faisons toutes ces choses. La portée d'un outil est généralement
limité aux tâches que l'outil est censé effectuer. Par exemple,
supposons que vous ayez besoin d'intégrer un préprocesseur de code (pour implémenter
conception par contrat, ou pragmas multi-traitements, ou autres) dans votre
IDE. À moins que le concepteur de l'EDI n'ait explicitement fourni des crochets pour cela
capacité, vous ne pouvez pas le faire.
Vous êtes peut-être déjà à l'aise de travailler à partir de l'invite de commande, dans
auquel cas vous pouvez ignorer cette section en toute sécurité. Sinon, vous devrez peut-être être
convaincu que la coquille est votre amie.
En tant que programmeur pragmatique, vous voudrez constamment effectuer des tâches ad hoc
opérations—choses que l'interface graphique peut ne pas prendre en charge. La ligne de commande est
mieux adapté lorsque vous souhaitez combiner rapidement quelques commandes pour
effectuer une requête ou une autre tâche. Voici quelques exemples.
Trouvez
Trouvez tous
tous les
les fichiers
fichiers .c
.c modifiés
modifiés plus
plus récemment
récemment que
que votre
votre Makefile.
Makefile.
t
Coquille… or
GUI… .. Ouvrez l'explorateur, accédez au répertoire correct, cliquez sur le Makefile et notez le
temps de modifications. Ensuite, affichez Outils/Rechercher et entrez *.c pour la spécification du fichier.
Sélectionnez l'onglet date et entrez la date que vous avez notée pour le Makefile dans le premier champ de date.
Appuyez ensuite sur OK.
Construire
Construire une
une archive
archive zip/tar
zip/tar de
de ma
ma source.
source.
pzi
Coquille… a
t a
GUI….. Ouvrez un utilitaire ZIP (tel que le shareware WinZip [ URL 41 ], sélectionnez "Create New
Archive", entrez son nom, sélectionnez le répertoire source dans la boîte de dialogue d'ajout, définissez le filtre sur
"* .c", cliquez sur "Ajouter", définissez le filtre sur "* .h", cliquez sur "Ajouter", puis fermez l'archive.
Quels
Quels fichiers
fichiers Java
Java n'ont
n'ont pas
pas été
été modifiés
modifiés la
la semaine
semaine dernière
dernière ??
t
Coquille… or
GUI… .. Cliquez et naviguez jusqu'à "Find files", cliquez sur le champ "Named" et tapez "* .java", sélectionnez le
Onglet "Date de modification". Sélectionnez ensuite "Entre". Cliquez sur la date de début et saisissez le
date de démarrage du projet. Cliquez sur la date de fin et tapez le
date d'il y a une semaine aujourd'hui (assurez-vous d'avoir un calendrier à portée de main). Cliquez sur "Rechercher maintenant".
Parmi
Parmi ces
ces fichiers,
fichiers, lesquels
lesquels utilisent
utilisent les
les bibliothèques
bibliothèques awt
awt ??
t
Coquille… or
GUI….. Chargez chaque fichier de la liste de l'exemple précédent dans un éditeur et recherchez le
De toute évidence, la liste pourrait s'allonger. Les commandes shell peuvent être obscures ou concises,
mais ils sont puissants et concis. Et, parce que les commandes shell peuvent être
combinés dans des fichiers de script (ou des fichiers de commande sous les systèmes Windows), vous
peut créer des séquences de commandes pour automatiser les choses que vous faites souvent.
Astuce
Astuce 21
21
Si vous n'avez pas passé beaucoup de temps à explorer les capacités de la commande
shell sur les systèmes que vous utilisez, cela peut sembler intimidant. Cependant, investissez
un peu d'énergie pour se familiariser avec votre coquille et les choses vont bientôt commencer
tomber en place. Jouez avec votre shell de commande et vous serez
surpris de voir à quel point cela vous rend plus productif.
Utilitaires
Utilitaires Shell
Shell et
et systèmes
systèmes Windows
Windows
Bien que les shells de commande fournis avec les systèmes Windows soient
s'améliorant progressivement, les utilitaires de ligne de commande Windows sont toujours inférieurs à
leurs homologues Unix. Cependant, tout n'est pas perdu.
[3] La licence publique générale GNU [ URL 57 ] est une sorte de virus légal que les développeurs Open Source utilisent pour protéger leurs
(et vos) droits. Vous devriez passer un peu de temps à le lire. En substance, il dit que vous pouvez utiliser et modifier des logiciels sous licence GPL,
mais si vous distribuez des modifications, elles doivent être sous licence conformément à la GPL (et marquées comme telles), et vous devez
rendre la source disponible. C'est la partie virale - chaque fois que vous dérivez une œuvre d'une œuvre sous GPL, votre travail dérivé doit
également être GPL. Cependant, cela ne vous limite en aucune façon lorsque vous utilisez simplement les outils - la propriété et la licence de
Alternativement, David Korn (de la renommée de Korn Shell) a mis en place un package
appelé uwin. Cela a les mêmes objectifs que la distribution Cygwin - c'est un
Environnement de développement Unix sous Windows. UWIN est livré avec un
version du shell Korn. Les versions commerciales sont disponibles auprès de Global
Technologies, Ltd. [ URL 30 ]. De plus, AT&T permet le téléchargement gratuit de
le package pour l'évaluation et l'utilisation académique. Encore une fois, lisez leur licence
avant d'utiliser.
Enfin, Tom Christiansen est (au moment de la rédaction) en train de mettre en place Perl
Power Tools , une tentative d'implémentation de tous les utilitaires Unix familiers
de manière portable, en Perl
], [ URL 32
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Automatisation omniprésente
Défis
Défis
• • Y a-t-il des choses que vous faites actuellement manuellement dans une interface graphique ?
Vous arrive-t-il de transmettre des instructions à des collègues qui impliquent un certain nombre de
étapes individuelles "cliquer sur ce bouton", "sélectionner cet élément" ? Ceux-ci pourraient-ils être
automatique?
• • Chaque fois que vous déménagez dans un nouvel environnement, assurez-vous
savoir quels coquillages sont disponibles. Voyez si vous pouvez apporter votre
shell actuel avec vous.
• • Recherchez des alternatives à votre shell actuel. Si vous rencontrez
un problème que votre shell ne peut pas résoudre, voyez si un autre shell pourrait
mieux faire face.
Édition
Édition de
de puissance
puissance
Nous avons déjà parlé des outils comme une extension de votre main. Bon ça
s'applique aux éditeurs plus qu'à tout autre outil logiciel. Vous devez pouvoir
manipuler le texte aussi facilement que possible, car le texte est le brut de base
matériel de programmation. Examinons quelques caractéristiques communes et
fonctions qui vous aident à tirer le meilleur parti de votre environnement d'édition.
Un
Un éditeur
éditeur
Nous pensons qu'il est préférable de bien connaître un éditeur et de l'utiliser pour toutes les éditions
tâches : code, documentation, mémos, administration système, etc.
Sans un seul éditeur, vous faites face à une Babel de confusion des temps modernes.
Vous devrez peut-être utiliser l'éditeur intégré dans l'IDE de chaque langue pour le codage,
et un produit bureautique tout-en-un pour la documentation, et peut-être un autre
éditeur intégré pour l'envoi d'e-mails. Même les frappes que vous utilisez pour éditer
les lignes de commande dans le shell peuvent [4] êtreIl différentes.
est difficile d'être compétent
dans l'un de ces environnements si vous avez un ensemble différent de montage
conventions et commandes dans chacun.
[4] Idéalement, le shell que vous utilisez devrait avoir des raccourcis clavier qui correspondent à ceux utilisés par votre éditeur. Bash, par exemple,
prend en charge
raccourcis
les deux clavier vi et emacs.
Vous devez être compétent. En tapant simplement de manière linéaire et en utilisant une souris pour couper
et la pâte ne suffit pas. Vous ne pouvez pas être aussi efficace que vous le pouvez
Astuce
Astuce 22
22
Choisissez un éditeur, connaissez-le parfaitement et utilisez-le pour toutes les tâches d'édition. Si tu
utiliser un seul éditeur (ou ensemble de raccourcis clavier) pour toutes les activités d'édition de texte,
vous n'avez pas besoin de vous arrêter et de réfléchir pour accomplir une manipulation de texte :
les frappes nécessaires seront un réflexe. L'éditeur sera une extension de votre
main; les touches chanteront en se frayant un chemin à travers le texte et la pensée.
C'est notre objectif.
Assurez-vous que l'éditeur que vous choisissez est disponible sur toutes les plateformes que vous utilisez.
Emacs, vi, CRiSP, Brief et autres sont disponibles sur plusieurs plateformes,
souvent dans les versions GUI et non GUI (écran texte).
Fonctionnalités
Fonctionnalités de
de l'éditeur
l'éditeur
Une fonctionnalité telle que la coloration syntaxique peut sembler un extra frivole, mais
en réalité, cela peut être très utile et améliorer votre productivité. Une fois que vous obtenez
habitué à voir des mots-clés apparaître dans une couleur ou une police différente, une erreur de frappe
un mot-clé qui n'apparaît pas de cette façon vous saute aux yeux bien avant que vous ne tiriez
le compilateur.
Productivité
Productivité
Un nombre surprenant de personnes que nous avons rencontrées utilisent l'utilitaire de bloc-notes de Windows pour
modifier leur code source. C'est comme utiliser une cuillère à café comme une pelle - simplement
taper et utiliser le copier-coller de base à la souris ne suffit pas.
Quel genre de choses aurez-vous besoin de faire qui ne peut pas être fait de cette façon ?
Eh bien, il y a le mouvement du curseur, pour commencer. Des frappes simples qui bougent
vous en unités de mots, lignes, blocs ou fonctions sont bien plus efficaces que
taper à plusieurs reprises une frappe qui vous déplace caractère par caractère ou ligne
par ligne.
O u
déclarations par ordre alphabétique, et quelqu'un d'autre a enregistré quelques
fichiers qui ne respectent pas cette norme (cela peut sembler extrême, mais sur un
grand projet, cela peut vous faire gagner beaucoup de temps à parcourir une longue liste de
déclarations d'importation). Vous souhaitez parcourir rapidement quelques fichiers et trier un
petite partie d'entre eux. Dans des éditeurs tels que vi et Emacs, vous pouvez le faire facilement
(voir Figure 3.1 )
Illustration
Illustration 3.1.
3.1. Trier
Trier les
les lignes
lignes dans
dans un
un éditeur
éditeur
Certains éditeurs peuvent aider à rationaliser les opérations courantes. Par exemple, lorsque
vous créez un nouveau fichier dans une langue particulière, l'éditeur peut fournir une
modèle pour vous. Cela pourrait inclure :
• • Nom de la classe ou du module renseigné (dérivé du nom du fichier)
• • Votre nom et/ou déclarations de droits d'auteur
Une autre fonctionnalité utile est l'indentation automatique. Plutôt que d'avoir à indenter
manuellement (en utilisant l'espace ou la tabulation), l'éditeur indente automatiquement pour vous
au moment opportun (après avoir tapé une accolade ouvrante, par exemple). Le gentil
partie de cette fonctionnalité est que vous pouvez utiliser l'éditeur pour fournir une cohérence
style d'indentation pour votre projet.[5]
[5] Le noyau Linux est développé de cette façon. Ici, vous avez des développeurs dispersés géographiquement, dont beaucoup travaillent sur le
mêmes morceaux de code. Il existe une liste publiée de paramètres (dans ce cas, pour Emacs) qui décrit l'indentation requise
style.
Où
Où aller
aller en
en partant
partant d'ici
d'ici
Si
Si cela
cela vous
vous ressemble…
ressemble… Alors
Alors pensez
pensez à…
à…
J'utilise uniquement les fonctionnalités
Choisissezdeunbase
éditeur
de puissant et apprenez-le bien.
de nombreux éditeurs différents.
J'ai un éditeur préféré, mais je Apprenez-les. Réduisez le nombre de frappes dont vous avez besoin pour
n'utilisez pas toutes ses fonctionnalités.
taper.
J'ai un éditeur préféré et Essayez de l'étendre et de l'utiliser pour plus de tâches que vous ne le faites déjà.
utilisez-le dans la mesure du possible.
Je pense que tu es fou. Bloc-notes
Tant que vous êtes heureux et productif, allez-y ! Mais si vous trouvez
est le meilleur éditeur jamais créé.
sujet à "l'envie des éditeurs", vous devrez peut-être réévaluer
ta position.
Quels
Quels éditeurs
éditeurs sont
sont disponibles
disponibles ??
Défis
Défis
George
George Santayana,
Santayana, Vie
Vie de
de raison
raison
L'une des choses importantes que nous recherchons dans une interface utilisateur est la
clé—un seul bouton qui nous pardonne nos erreurs. C'est encore mieux si le
l'environnement prend en charge plusieurs niveaux d'annulation et de rétablissement, vous pouvez donc revenir en arrière
et récupérer de quelque chose qui s'est passé il y a quelques minutes. Mais
et si l'erreur s'était produite la semaine dernière et que vous aviez allumé votre ordinateur
allumé et éteint dix fois depuis ? Eh bien, c'est l'un des nombreux avantages de
[6] Nous utilisons le SCCS en majuscules pour désigner les systèmes de contrôle de code source génériques. Il existe également un système spécifique appelé "sccs",
Un SCCS vous permettra également d'identifier les versions de votre logiciel. Une fois identifié,
vous pourrez toujours revenir en arrière et régénérer la version, indépendamment
des changements qui ont pu se produire plus tard.
Nous utilisons souvent un SCCS pour gérer les branches dans l'arbre de développement. Pour
exemple, une fois que vous avez publié un logiciel, vous voudrez normalement
continuer à développer pour la prochaine version. En même temps, vous devrez
traiter les bogues dans la version actuelle, en envoyant des versions corrigées aux clients.
Vous voudrez que ces corrections de bogues soient intégrées à la prochaine version (le cas échéant), mais
vous ne voulez pas expédier le code en cours de développement aux clients. Avec un SCCS
vous pouvez générer des branches dans l'arborescence de développement chaque fois que vous générez
Une libération. Vous appliquez des corrections de bogues au code dans la branche et continuez
se développant sur le tronc principal. Étant donné que les corrections de bogues peuvent être pertinentes pour le
tronc principal également, certains systèmes vous permettent de fusionner les modifications sélectionnées à partir de
automatiquement la branche dans le tronc principal.
Les systèmes de contrôle du code source peuvent conserver les fichiers qu'ils gèrent dans un
référentiel—un excellent candidat pour l'archivage.
Astuce
Astuce 23
23
Contrôle
Contrôle du
du code
code source
source et
et constructions
constructions
La construction est reproductible car vous pouvez toujours reconstruire la source telle qu'elle
existé à une date donnée.
Mais
Mais mon
mon équipe
équipe n'utilise
n'utilise pas
pas le
le contrôle
contrôle du
du code
code source
source
N'oubliez pas qu'un SCCS s'applique également aux choses que vous faites à l'extérieur
de travail.
Produits
Produits de
de contrôle
contrôle du
du code
code source
source
L'annexe A , donne les URL des systèmes de contrôle de code source représentatifs,
certains commerciaux et d'autres disponibles gratuitement. Et bien d'autres produits sont
disponible : recherchez des pointeurs vers la FAQ sur la gestion de la configuration.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Orthogonalité
• • La puissance du texte brut
• • Tout est écrit
Défis
Défis
Débogage
Débogage
Sophocle,
Sophocle, Ajax
Ajax
Malheureusement, nous avons encore des "bogues" dans le système, mais pas du genre volant.
Mais le sens du XIVe siècle - un croque-mitaine - est peut-être encore plus
applicable aujourd'hui qu'elle ne l'était alors. Les défauts logiciels se manifestent dans un
diverses manières, des exigences mal comprises aux erreurs de codage.
Malheureusement, les systèmes informatiques modernes sont encore limités à faire ce
vous leur dites de faire, pas nécessairement ce que vous voulez qu'ils fassent.
Personne n'écrit un logiciel parfait, il est donc évident que le débogage prendra beaucoup de temps
majeure partie de votre journée. Examinons quelques-uns des problèmes liés à
débogage et quelques stratégies générales pour trouver des bogues insaisissables.
Psychologie
Psychologie du
du débogage
débogage
Acceptez le fait que le débogage n'est que la résolution de problèmes et attaquez-le comme
tel.
Après avoir trouvé le bogue de quelqu'un d'autre, vous pouvez passer du temps et de l'énergie à poser
blâmez le sale coupable qui l'a créé. Dans certains lieux de travail, cela fait partie de
la culture, et peut être cathartique. Cependant, dans le domaine technique, vous
veulent se concentrer sur la résolution du problème, pas sur le blâme.
Astuce
Astuce 24
24
Résoudre le problème, pas le blâme
Peu importe que le bug soit de votre faute ou de quelqu'un d'autre. C'est
toujours ton problème.
Un
Un état
état d'esprit
d'esprit de
de débogage
débogage
Edward
Edward Bulwer-Lytton,
Bulwer-Lytton, Le
Le renié
renié
Avant de commencer le débogage, il est important d'adopter le bon état d'esprit. Toi
besoin de désactiver de nombreuses défenses que vous utilisez chaque jour pour protéger votre ego,
éliminez toutes les pressions du projet auxquelles vous pourriez être soumis et obtenez-vous
confortable. Avant tout, rappelez-vous la première règle de débogage :
Astuce
Astuce 25
25
Ne pas paniquer
Il est facile de paniquer, surtout si vous êtes confronté à une échéance ou si vous avez un
un patron ou un client nerveux qui respire dans votre cou pendant que vous essayez de
trouver la cause du bug. Mais il est très important de prendre du recul, et
pensez réellement à ce qui pourrait causer les symptômes que vous croyez
indiquer un bogue.
Si votre première réaction en voyant un bogue ou en voyant un rapport de bogue est "c'est
impossible », vous avez tout à fait tort. Ne gaspillez pas un seul neurone dans le train
de pensée qui commence par "mais ça ne peut pas arriver" parce qu'il est clair que c'est possible,
et a.
Attention à la myopie lors du débogage. Résistez à l'envie de corriger uniquement les symptômes
vous voyez : il est plus probable que le problème réel soit plusieurs étapes supprimées
de ce que vous observez, et peut impliquer un certain nombre d'autres
choses. Essayez toujours de découvrir la cause profonde d'un problème, pas seulement cette
aspect particulier de celui-ci.
Où
Où commencer
commencer
Avant de commencer à regarder le bogue, assurez-vous que vous travaillez sur le code
qui a été compilé proprement, sans avertissements. Nous définissons régulièrement le compilateur
niveaux d'avertissement aussi élevés que possible. Cela n'a pas de sens de perdre du temps
essayer de trouver un problème que le compilateur pourrait trouver pour vous ! Nous devons le faire
se concentrer sur les problèmes les plus difficiles à résoudre.
Lorsque vous essayez de résoudre un problème, vous devez rassembler toutes les données pertinentes.
Malheureusement, le rapport de bug n'est pas une science exacte. Il est facile d'être induit en erreur par
coïncidences, et vous ne pouvez pas vous permettre de perdre du temps à déboguer les coïncidences.
Vous devez d'abord être précis dans vos observations.
La précision des rapports de bogues est encore réduite lorsqu'ils passent par un
tierce partie - vous devrez peut-être surveiller l'utilisateur qui a signalé le bogue
en action pour obtenir un niveau de détail suffisant.
Andy a déjà travaillé sur une grande application graphique. À l'approche de la libération, le
les testeurs ont signalé que l'application plantait à chaque fois qu'ils peignaient un
caresser avec un pinceau particulier. Le programmeur responsable a fait valoir que
Il n'y avait rien de mal à cela; il avait essayé de peindre avec, et il
a très bien fonctionné. Ce dialogue a fait des allers-retours pendant plusieurs jours, avec
les tempéraments montent rapidement.
Finalement, nous les avons réunis dans la même pièce. Le testeur a choisi le
outil pinceau et peint un trait du coin supérieur droit au coin inférieur gauche
coin. L'application a explosé. "Oh," dit le programmeur, dans un petit
voix, qui a ensuite admis timidement qu'il n'avait fait que des coups d'essai
du coin inférieur gauche au coin supérieur droit, ce qui n'a pas révélé le bogue.
Stratégies
Stratégies de
de débogage
débogage
Une fois que vous pensez savoir ce qui se passe, il est temps de découvrir ce que
programme pense se passe.
Reproduction d'insectes
Non, nos bugs ne se multiplient pas vraiment (bien que certains d'entre eux soient
probablement assez vieux pour le faire légalement). Nous parlons d'un autre
genre de reproduction.
Mais nous voulons plus qu'un bogue qui peut être reproduit en suivant
une longue série d'étapes; nous voulons un bogue qui peut être reproduit
avec une seule commande. Il est beaucoup plus difficile de corriger un bogue si vous devez y aller
à travers 15 étapes pour arriver au point où le bogue apparaît.
Parfois en vous forçant à isoler les circonstances qui
affichez le bogue, vous aurez même un aperçu de la façon de le corriger.
Visualisez
Visualisez vos
vos données
données
Souvent, le moyen le plus simple de discerner ce que fait un programme ou ce qu'il est
va faire - est d'avoir un bon aperçu des données sur lesquelles il fonctionne. Le plus simple
exemple de ceci est une approche simple "nom de variable = valeur de données",
qui peut être implémenté sous forme de texte imprimé ou sous forme de champs dans une boîte de dialogue GUI
ou liste.
Mais vous pouvez obtenir un aperçu beaucoup plus approfondi de vos données en utilisant un débogueur
qui vous permet de visualiser vos données et toutes les interrelations qui
exister. Il existe des débogueurs qui peuvent représenter vos données sous forme de survol 3D
à travers un paysage de réalité virtuelle, ou sous forme de tracé de forme d'onde 3D, ou tout simplement
schémas structurels simples, comme le montre la figure 3.2 à la page suivante. Comme
vous suivez votre programme en une seule étape, des images comme celles-ci peuvent valoir la peine
bien plus que mille mots, car le bogue que vous avez chassé
vous saute soudainement aux yeux.
Illustration
Illustration 3.2.
3.2. Exemple
Exemple de
de diagramme
diagramme de
de débogueur
débogueur d'une
d'une liste
liste chaînée
chaînée circulaire.
circulaire. Le
Le
les
les flèches
flèches représentent
représentent des
des pointeurs
pointeurs vers
vers des
des nœuds.
nœuds.
Même si votre débogueur a une prise en charge limitée de la visualisation des données, vous pouvez toujours
faites-le vous-même, soit à la main, avec du papier et un crayon, soit avec un
programmes de traçage.
Tracé
Tracé
Les instructions de suivi sont ces petits messages de diagnostic que vous imprimez sur le
écran ou à un fichier qui dit des choses telles que "arrivé ici" et "valeur de x = 2". C'est
une technique primitive par rapport aux débogueurs de style IDE, mais il est
particulièrement efficace pour diagnostiquer plusieurs classes d'erreurs que les débogueurs
ne peut pas. Le traçage est inestimable dans tout système où le temps lui-même est un facteur :
processus simultanés, systèmes en temps réel et applications basées sur des événements.
Vous pouvez utiliser des instructions de traçage pour "explorer" le code. C'est toi
peut ajouter des instructions de traçage au fur et à mesure que vous descendez dans l'arborescence des appels.
Les messages de suivi doivent être dans un format régulier et cohérent ; vous voudrez peut-être
les analyser automatiquement. Par exemple, si vous deviez retrouver un
fuite de ressources (telle que des ouvertures/fermetures de fichiers déséquilibrées), vous pouvez suivre chaque
ouvrir et fermer chacun dans un fichier journal. En traitant le fichier journal avec Perl, vous
pourrait facilement identifier où se produisait l'ouverture incriminée.
Esquive
Esquive en
en caoutchouc
caoutchouc
Une technique très simple mais particulièrement utile pour trouver la cause d'un
problème est simplement de l'expliquer à quelqu'un d'autre. L'autre personne doit
regardez l'écran par-dessus votre épaule et hochez constamment la tête
(comme un canard en caoutchouc qui monte et descend dans une baignoire). Ils n'ont pas besoin de
dis un mot; le simple fait d'expliquer, étape par étape, ce qu'est le code
censé faire fait souvent sauter le problème hors de l'écran et annoncer
lui-même.
[7]
[7] Pourquoi "l'esquive en caoutchouc" ? Pendant ses études de premier cycle à l'Imperial College de Londres, Dave a beaucoup travaillé avec un chercheur
assistant nommé Greg Pugh, l'un des meilleurs développeurs que Dave ait connus. Pendant plusieurs mois, Greg a transporté un petit
canard en caoutchouc jaune, qu'il plaçait sur son terminal pendant le codage. Il a fallu un certain temps avant que Dave ait le courage de demander...
Cela semble simple, mais en expliquant le problème à une autre personne, vous devez
énoncez explicitement des choses que vous pouvez tenir pour acquises lorsque vous traversez
Processus
Processus d'élimination
d'élimination
Dans la plupart des projets, le code que vous déboguez peut être un mélange de
code d'application écrit par vous et d'autres membres de votre équipe de projet,
produits tiers (base de données, connectivité, librairies graphiques,
communications spécialisées ou algorithmes, etc.) et la plateforme
environnement (système d'exploitation, bibliothèques système et compilateurs).
Il est possible qu'un bogue existe dans le système d'exploitation, le compilateur ou un tiers
produit, mais cela ne devrait pas être votre première pensée. Il est beaucoup plus probable
que le bogue existe dans le code de l'application en cours de développement. C'est
généralement plus rentable de supposer que le code de l'application est incorrect
appeler dans une bibliothèque que de supposer que la bibliothèque elle-même est cassée. Même
si le problème vient d'un tiers, vous devrez quand même éliminer votre
code avant de soumettre le rapport de bogue.
Nous avons travaillé sur un projet où un ingénieur senior était convaincu que le
L'appel système select a été interrompu sur Solaris. Aucune quantité de persuasion ou de logique
pourrait changer d'avis (le fait que toutes les autres applications de mise en réseau sur
la boîte fonctionnait bien n'était pas pertinente). Il a passé des semaines à écrire des solutions de contournement,
qui, pour une raison étrange, ne semble pas résoudre le problème. Quand enfin
forcé de s'asseoir et de lire la documentation sur sélectionner, il a découvert le
problème et l'a corrigé en quelques minutes. Nous utilisons maintenant l'expression
"select est cassé" comme un doux rappel chaque fois que l'un de nous commence à blâmer
le système pour une faute susceptible d'être la nôtre.
Astuce
Astuce 26
26
N'oubliez pas que si vous voyez des empreintes de sabots, pensez à des chevaux et non à des zèbres. Le système d'exploitation est
probablement pas cassé. Et la base de données est probablement très bien.
Si vous "n'avez changé qu'une seule chose" et que le système a cessé de fonctionner, celui-là
chose était susceptible d'être responsable, directement ou indirectement, peu importe comment
tiré par les cheveux semble-t-il. Parfois, la chose qui a changé est en dehors de votre
contrôle : nouvelles versions du système d'exploitation, du compilateur, de la base de données ou d'autres tiers
le logiciel peut faire des ravages avec un code précédemment correct. De nouveaux bogues pourraient
arriver. Les bogues pour lesquels vous aviez une solution de contournement sont corrigés, brisant le
solution de contournement. Les API changent, les fonctionnalités changent ; bref c'est une toute nouvelle
jeu de balle, et vous devez retester le système dans ces nouvelles conditions. Donc
gardez un œil attentif sur le calendrier lorsque vous envisagez une mise à niveau ; vous pouvez
voulez attendre après la prochaine version.
Si, toutefois, vous n'avez pas d'endroit évident pour commencer à chercher, vous pouvez toujours compter sur
sur une bonne recherche binaire à l'ancienne. Voir si les symptômes sont présents à
l'un des deux endroits éloignés dans le code. Regardez ensuite au milieu. Si la
problème est présent, alors le bogue se situe entre le début et le milieu
indiquer; sinon, c'est entre le milieu et la fin. Tu peux
continuez de cette façon jusqu'à ce que vous réduisiez suffisamment l'endroit pour
Identifiez le problème.
L'élément
L'élément de
de surprise
surprise
Lorsque vous vous retrouvez surpris par un insecte (peut-être même en marmonnant "c'est
impossible" dans votre souffle où nous ne pouvons pas vous entendre), vous devez
réévaluer les vérités qui vous sont chères. Dans cette routine de liste chaînée, celle que vous
savait qu'il était à l'épreuve des balles et ne pouvait pas être la cause de ce bogue - est-ce que
tu testes toutes les conditions aux limites? Cet autre morceau de code que vous avez été
utilisé pendant des années - il ne pouvait pas encore y avoir de bogue. Pourrait-il?
Bien sûr que c'est possible. La quantité de surprise que vous ressentez quand quelque chose se passe
le mal est directement proportionnel au degré de confiance et de foi que vous avez en
le code en cours d'exécution. C'est pourquoi, face à un échec « surprenant », vous
devez réaliser qu'une ou plusieurs de vos hypothèses sont fausses. Ne brille pas
sur une routine ou un morceau de code impliqué dans le bogue parce que vous le "connaissez"
travaux. Prouve le. Prouvez-le dans ce contexte, avec ces données, avec ces limites
conditions.
Astuce
Astuce 27
27
Lorsque vous rencontrez un bogue surprise, au-delà du simple fait de le corriger, vous devez
déterminer pourquoi cet échec n'a pas été détecté plus tôt. Demandez-vous si vous
besoin de modifier l'unité ou d'autres tests pour qu'ils l'aient attrapé.
Pendant que vous y êtes, y a-t-il d'autres endroits dans le code qui pourraient être
sensible à ce même bug? Il est maintenant temps de les trouver et de les réparer. Faire
sûr que quoi qu'il soit arrivé, vous saurez si cela se reproduit.
S'il a fallu beaucoup de temps pour corriger ce bogue, demandez-vous pourquoi. Y a-t-il quelque chose que vous
pouvez-vous faire pour faciliter la correction de ce bogue la prochaine fois ? Peut-être toi
pourrait intégrer de meilleurs crochets de test ou écrire un analyseur de fichiers journaux.
Faites tout cela, et j'espère que vous ne serez pas surpris la prochaine fois.
Liste
Liste de
de contrôle
contrôle de
de débogage
débogage
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Programmation affirmée
• • Programmation par coïncidence
• • Automatisation omniprésente
• • Tests impitoyables
Défis
Défis
Manipulation
Manipulation de
de texte
texte
Les programmeurs pragmatiques manipulent le texte de la même manière que les menuisiers
façonner le bois. Dans les sections précédentes, nous avons discuté de certains outils spécifiques—shells,
éditeurs, débogueurs que nous utilisons. Ceux-ci sont similaires à un travailleur du bois
burins, scies et rabots - des outils spécialisés pour bien faire un ou deux travaux.
Cependant, de temps en temps, nous devons effectuer une transformation non
facilement manipulé par l'ensemble d'outils de base. Nous avons besoin d'un texte général
outil de manipulation.
[8] Ici, le routeur signifie l'outil qui fait tourner les lames de coupe très, très rapidement, pas un dispositif d'interconnexion de réseaux.
Ces langages sont des technologies habilitantes importantes. En les utilisant, vous pouvez
pirater rapidement des utilitaires et des idées de prototypes - des tâches qui peuvent prendre cinq ou
dix fois plus longtemps en utilisant les langages conventionnels. Et que se multipliant
facteur est d'une importance cruciale pour le type d'expérimentation que nous faisons.
Passer 30 minutes à essayer une idée folle est bien mieux que ça
passer cinq heures. Passer une journée à automatiser des composants importants d'un
le projet est acceptable ; passer une semaine pourrait ne pas l'être. Dans leur livre Le
Practice of Programming [ KP99 ], Kernighan et Pike ont construit le même
programme en cinq langues différentes. La version Perl était la plus courte (17
lignes, par rapport à C's 150). Avec Perl, vous pouvez manipuler du texte, interagir
avec des programmes, parler sur des réseaux, conduire des pages Web, effectuer des
arithmétique de précision et écrivez des programmes qui ressemblent à Snoopy jurant.
Astuce
Astuce 28
28
Nous utilisons presque tous les jours des langages de manipulation de texte. Beaucoup d'idées dans
ce livre peut y être mis en œuvre plus simplement que dans tout autre
langue dont nous sommes conscients. Ces langages facilitent l'écriture de code
générateurs, que nous verrons ensuite.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Des
Des exercices
exercices
11.
11. Votre programme C utilise un type énuméré pour représenter l'un des 100
États. Vous aimeriez pouvoir imprimer l'état sous forme de chaîne (comme
opposé à un nombre) à des fins de débogage. Écrivez un script qui
tli d
oPr d
e t
12.
12. A mi-chemin de l'écriture de ce livre, nous avons réalisé que nous n'avions pas mis le
utiliser la directive stricte dans beaucoup de nos exemples Perl. Écrire un scénario
qui passe par le .p1 vole dans un répertoire et ajoute un use strict à
la fin du bloc de commentaires initial à toutes les mouches qui n'ont pas déjà
un. N'oubliez pas de conserver une sauvegarde de toutes les mouches que vous changez.
Générateurs
Générateurs de
de codes
codes
En tant que programmeurs, nous nous retrouvons souvent dans une position similaire. Nous devons le faire
obtenir la même fonctionnalité, mais dans des contextes différents. Nous devons répéter
informations à différents endroits. Parfois, nous avons juste besoin de nous protéger
du syndrome du canal carpien en réduisant la saisie répétitive.
De la même manière qu'un menuisier investit du temps dans un gabarit, un programmeur peut
construire un générateur de code. Une fois construit, il peut être utilisé tout au long de la vie du
projet à peu de frais.
Astuce
Astuce 29
29
1. 1. Les générateurs de code passifs sont exécutés une fois pour produire un résultat. Depuis
ce moment-là, le résultat devient autonome - il est divorcé
du générateur de code. Les sorciers dont il est question dans Evil Wizards,
ainsi que certains outils CASE, sont des exemples de code passif
générateurs.
2. 2. Les générateurs de code actifs sont utilisés chaque fois que leurs résultats sont
requis. Le résultat est jetable, il peut toujours être reproduit
par le générateur de code. Souvent, les générateurs de code actifs lisent une forme
de script ou de fichier de contrôle pour produire leurs résultats.
Générateurs
Générateurs de
de code
code passifs
passifs
Les générateurs de code passifs économisent la frappe. Ils sont essentiellement paramétrés
modèles, générant une sortie donnée à partir d'un ensemble d'entrées. Une fois le résultat
produit, il devient un fichier source à part entière dans le projet ; il sera édité,
compilé et placé sous contrôle de source comme n'importe quel autre fichier. Ses origines
sera oublié.
Alors que les générateurs de code passifs sont simplement une commodité, leur
les cousins sont une nécessité si vous voulez suivre le principe DRY. Avec un
générateur de code actif, vous pouvez prendre une seule représentation d'un morceau de
connaissances et convertissez-les dans toutes les formes dont votre application a besoin. C'est
pas de duplication, car les formes dérivées sont jetables et sont
généré au besoin par le générateur de code (d'où le mot actif).
Chaque fois que vous essayez d'obtenir deux environnements disparates pour
travailler ensemble, vous devriez envisager d'utiliser des générateurs de code actifs.
Vous développez peut-être une application de base de données. Ici, vous traitez
avec deux environnements—la base de données et le langage de programmation que vous
utilisent pour y accéder. Vous avez un schéma et vous devez définir des
structures reflétant la disposition de certaines tables de base de données. Vous pourriez juste
les coder directement, mais cela viole le principe DRY : la connaissance du
schéma serait alors exprimé en deux endroits. Lorsque le schéma change,
vous devez vous rappeler de changer le code correspondant. Si une colonne est
supprimé d'une table, mais la base de code n'est pas modifiée, vous pourriez même ne pas
obtenir une erreur de compilation. La première fois que vous le saurez, c'est lorsque vos tests
commencer à échouer (ou lorsque l'utilisateur appelle).
Une alternative consiste à utiliser un générateur de code actif - prenez le schéma et utilisez
pour générer le code source des structures, comme illustré à la Figure 3.3 .
Désormais, chaque fois que le schéma change, le code utilisé pour y accéder change également,
automatiquement. Si une colonne est supprimée, son champ correspondant dans le
la structure disparaîtra, et tout code de niveau supérieur qui utilise cette colonne
échouera à compiler. Vous avez attrapé l'erreur au moment de la compilation, pas dans
production. Bien sûr, ce schéma ne fonctionne que si vous créez le code
génération fait partie du processus de construction
[9] lui-même.
[9] Comment procédez-vous pour créer du code à partir d'un schéma de base de données ? Il existe plusieurs façons. Si le schéma est tenu dans un appartement
Alternativement, si vous utilisez un outil pour créer le schéma directement dans la base de données, vous devriez pouvoir extraire le
informations dont vous avez besoin directement à partir du dictionnaire de données de la base de données. Perl fournit des bibliothèques qui vous donnent accès à la plupart
principales bases de données.
Illustration
Illustration 3.3.
3.3. Le
Le générateur
générateur de
de code
code actif
actif crée
crée du
du code
code àà partir
partir d'une
d'une base
base de
de données
données
schéma
schéma
Illustration
Illustration 3.4.
3.4. Génération
Génération de
de code
code àà partir
partir d'une
d'une représentation
représentation indépendante
indépendante du
du langage.
langage.
Dans
Dans le
le fichier
fichier d'entrée,
d'entrée, les
les lignes
lignes commençant
commençant par
par 'M'
'M' marquent
marquent le
le début
début d'un
d'un message
message
définition,
définition, les
les lignes
lignes 'F'
'F' définissent
définissent les
les champs
champs et
et 'E'
'E' est
est la
la fin
fin du
du message.
message.
Les
Les générateurs
générateurs de
de code
code n'ont
n'ont pas
pas besoin
besoin d'être
d'être complexes
complexes
Tout ce discours sur l'actif et le passif qui peut vous laisser avec le
l'impression que les générateurs de code sont des bêtes complexes. Ils n'ont pas besoin de l'être.
Normalement, la partie la plus complexe est l'analyseur, qui analyse le fichier d'entrée.
Les
Les générateurs
générateurs de
de code
code n'ont
n'ont pas
pas besoin
besoin de
de générer
générer de
de code
code
Bien que de nombreux exemples de cette section montrent des générateurs de code qui
produire la source du programme, cela ne doit pas toujours être le cas. Vous pouvez utiliser le code
générateurs pour écrire à peu près n'importe quelle sortie : HTML, XML, texte brut - n'importe
texte qui pourrait être une entrée ailleurs dans votre projet.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Des
Des exercices
exercices
13.
13. Écrivez un générateur de code qui prend le fichier d'entrée de la ,figure
et 3.4
génère une sortie dans deux langues de votre choix. Essayez de le rendre facile
pour ajouter de nouvelles langues.
Chapitre 4. Paranoïa pragmatique
Astuce
Astuce 30
30
Cela a-t-il fait mal ? Ça ne devrait pas. Acceptez-le comme un axiome de la vie. Embrasse le.
Le célébrer. Parce que le logiciel parfait n'existe pas. Personne dans le brief
l'histoire de l'informatique n'a jamais écrit un logiciel parfait. C'est
peu de chances que vous soyez le premier. Et à moins que vous n'acceptiez cela comme un fait, vous
finir par perdre du temps et de l'énergie à poursuivre un rêve impossible.
Alors, compte tenu de cette réalité déprimante, comment un programmeur pragmatique la transforme-t-il
en avantage ? C'est le sujet de ce chapitre.
Tout le monde sait qu'ils sont personnellement le seul bon conducteur sur Terre.
Le reste du monde est là pour les attraper, soufflant à travers les panneaux d'arrêt,
se faufiler entre les voies, ne pas indiquer les virages, parler au téléphone,
lisant le journal, et ne respectant généralement pas nos normes. Alors on
conduire défensivement. Nous guettons les problèmes avant qu'ils ne surviennent, anticipons les
inattendu, et ne nous mettons jamais dans une position à partir de laquelle nous ne pouvons pas
nous tirer d'affaire.
Mais les programmeurs pragmatiques vont encore plus loin. Ils ne font pas confiance
eux-mêmes non plus. Sachant que personne n'écrit de code parfait, y compris
eux-mêmes, les programmeurs pragmatiques codent pour se défendre contre leurs propres
erreurs. Nous décrivons la première mesure défensive dans Design by Contract :
les clients et les fournisseurs doivent s'entendre sur les droits et les responsabilités.
Dans Dead Programs Tell No Lies, nous voulons nous assurer que nous ne causerons aucun dommage
pendant que nous travaillons sur les bogues. Nous essayons donc de vérifier les choses souvent et
terminer le programme si les choses tournent mal.
La programmation assertive décrit une méthode simple de vérification le long de la
way — écrivez du code qui vérifie activement vos hypothèses.
Les exceptions, comme toute autre technique, peuvent causer plus de mal que de bien sinon
utilisé correctement. Nous discuterons des problèmes dans Quand utiliser les exceptions.
Au fur et à mesure que vos programmes deviennent plus dynamiques, vous vous retrouverez à jongler avec le système
ressources : mémoire, fichiers, périphériques, etc. Dans Comment équilibrer
ressources, nous vous proposerons des moyens de vous assurer de ne laisser tomber aucun des
des balles.
Quand tout le monde cherche à vous avoir, la paranoïa est juste une bonne idée.
Alien
Alien boisé
boisé
Conception
Conception par
par contrat
contrat
Ralph
Ralph Waldo
Waldo Emerson,
Emerson, Essais
Essais
La gestion des systèmes informatiques est difficile. Traiter avec les gens est encore plus difficile.
Mais en tant qu'espèce, nous avons eu plus de temps pour comprendre les problèmes de l'homme
interactions. Certaines des solutions que nous avons proposées au cours des dernières
millénaires peuvent également être appliqués à l'écriture de logiciels. Un des meilleurs
des solutions pour assurer l'utilisation en clair est le contrat.
Peut-être avez-vous un contrat de travail qui précise les heures que vous
travail et les règles de conduite que vous devez suivre. En contrepartie, l'entreprise paie
vous un salaire et d'autres avantages. Chaque partie respecte ses obligations et chacun
avantages.
C'est une idée utilisée dans le monde entier, formellement et informellement, pour aider
les humains interagissent. Peut-on utiliser le même concept pour aider les modules logiciels
interagir? La réponse est oui."
DBC
DBC
[1] Basé en partie sur des travaux antérieurs de Dijkstra, Floyd, Hoare, Wirth et d'autres. Pour plus d'informations sur Eiffel lui-même, voir
[ URL 10 ] et [ URL 11 ].
Chaque fonction et méthode d'un système logiciel fait quelque chose. Avant cela
commence que quelque chose, la routine peut avoir une certaine attente de l'état
du monde, et il peut être en mesure de faire une déclaration sur l'état de la
monde quand il se termine. Meyer décrit ces attentes et affirmations comme
suit :
• • Conditions préalables. Qu'est-ce qui doit être vrai pour que la routine soit
appelé; les exigences de la routine. Une routine ne devrait jamais être appelée
lorsque ses conditions préalables seraient violées. C'est celui de l'appelant
responsabilité de transmettre de bonnes données (voir encadré page 115).
• • Postconditions. Ce que la routine est garantie de faire ; l'état
du monde lorsque la routine est terminée. Le fait que la routine ait un
la postcondition implique qu'elle se terminera : les boucles infinies ne sont pas
autorisé.
• • Invariants de classe. Une classe assure que cette condition est toujours
vrai du point de vue d'un appelant. Lors du traitement interne d'un
routine, l'invariant peut ne pas tenir, mais au moment où la routine se termine
et que le contrôle revient à l'appelant, l'invariant doit être vrai. (Note
qu'une classe ne peut donner un accès en écriture illimité à aucune donnée
membre qui participe à l'invariant.)
Examinons le contrat d'une routine qui insère une valeur de données dans un
liste unique et ordonnée. Dans iContract, un préprocesseur pour Java disponible chez
[ URL 17 ] ,
p u
Ici, nous disons que les nœuds de cette liste doivent toujours être en augmentation
commande. Lorsque vous insérez un nouveau nœud, il ne peut pas déjà exister, et nous vous garantissons
que le nœud sera trouvé après l'avoir inséré.
Souvent, une postcondition utilisera des paramètres passés dans une méthode pour
vérifier le bon comportement. Mais si la routine est autorisée à changer le
paramètre transmis, vous pourrez peut-être contourner le
contracter. Eiffel ne permet pas que cela se produise, mais Java oui. Ici, nous
utiliser le mot-clé Java finale pour indiquer nos intentions que le
Le paramètre ne doit pas être modifié dans la méthode. Ce n'est pas
à toute épreuve–les sous-classes sont libres de redéclarer le paramètre comme
non définitif. Alternativement, vous pouvez utiliser la syntaxe iContract
variable @pre pour obtenir la valeur d'origine de la variable telle qu'elle existait sur
entrée dans la méthode.
Le contrat entre une routine et tout appelant potentiel peut donc être lu comme
Si toutes les conditions préalables de la routine sont remplies par l'appelant, la routine doit
garantir que toutes les postconditions et tous les invariants seront vrais lorsqu'il
complète.
Si l'une ou l'autre des parties ne respecte pas les termes du contrat, un recours
(ce qui avait été précédemment convenu) est invoquée : une exception est déclenchée ou la
programme se termine, par exemple. Quoi qu'il arrive, ne vous méprenez pas
que le non-respect du contrat est un bogue. Ce n'est pas quelque chose qui
ne devrait jamais arriver, c'est pourquoi les conditions préalables ne doivent pas être utilisées pour
effectuer des choses telles que la validation des entrées utilisateur.
Astuce
Astuce 31
31
Les sous-classes doivent être utilisables via l'interface de la classe de base sans le
besoin pour l'utilisateur de connaître la différence.
En d'autres termes, vous voulez vous assurer que le nouveau sous-type que vous avez
créé vraiment "est-un-klnd-de" le type de base - qu'il prend en charge le même
méthodes, et que les méthodes ont le même sens. Nous pouvons le faire
avec des contrats. Nous n'avons besoin de spécifier un contrat qu'une seule fois, dans la classe de base, pour
l'appliquer automatiquement à chaque future sous-classe. Une sous-classe peut,
éventuellement, accepter un plus large éventail d'entrées ou donner des garanties plus solides. Mais
il doit accepter au moins autant et garantir autant que sa société mère.
Sans contrat, tout ce que le compilateur peut faire est de s'assurer qu'une sous-classe
est conforme à une signature de méthode particulière. Mais si on met une classe de base
contrat en place, nous pouvons maintenant nous assurer que toute future sous-classe ne peut pas modifier
le sens de nos méthodes. Par exemple, vous voudrez peut-être établir un
contrat pour setFont tel que le suivant, qui garantit que la police que vous
s e
Mise
Mise en
en œuvre
œuvre de
de la
la DBC
DBC
Le plus grand avantage de l'utilisation de DBC peut être qu'il force le problème de
exigences et garanties au premier plan. En énumérant simplement à
au moment de la conception, quelle est la plage du domaine d'entrée, quelles sont les conditions aux limites
sont, et ce que la routine promet de livrer - ou, plus important encore, ce que
il ne promet pas de livrer - est un énorme bond en avant pour mieux écrire
logiciel. En ne déclarant pas ces choses, vous revenez à la programmation en
coïncidence , où de nombreux projets commencent, se terminent et échouent.
Dans les langues qui ne prennent pas en charge DBC dans le code, cela peut aller jusqu'à
vous pouvez y aller, et ce n'est pas trop mal. DBC est, après tout, une technique de conception.
Même sans vérification automatique, vous pouvez mettre le contrat dans le code comme
commentaires et toujours obtenir un avantage très réel. Si rien d'autre, le commenté
les contrats vous donnent un point de départ pour chercher en cas de problème.
Assertions
Assertions
Bien que la documentation de ces hypothèses soit un bon début, vous pouvez obtenir beaucoup
plus grand avantage en demandant au compilateur de vérifier votre contrat pour vous. Tu peux
émuler partiellement cela dans certaines langues en utilisant des assertions (voir Assertive
La programmation ). Pourquoi seulement partiellement ? Ne pouvez-vous pas utiliser des assertions pour faire
tout ce que DBC peut faire ?
Malheureusement, la réponse est non. Pour commencer, il n'y a pas de support pour
propagation des assertions dans une hiérarchie d'héritage. Cela signifie que si
vous remplacez une méthode de classe de base qui a un contrat, les assertions qui
mettre en œuvre ce contrat ne sera pas appelé correctement (sauf si vous dupliquez
manuellement dans le nouveau code). Vous devez vous rappeler d'appeler la classe
invariant (et tous les invariants de classe de base) manuellement avant de quitter chaque
méthode. Le problème fondamental est que le contrat n'est pas automatiquement
forcée.
De plus, il n'y a pas de concept intégré d'"anciennes" valeurs ; c'est-à-dire les valeurs telles qu'elles
existait à l'entrée d'une méthode. Si vous utilisez des assertions pour appliquer
contrats, vous devez ajouter du code à la condition préalable pour enregistrer toute information
vous voudrez utiliser dans la postcondition. Comparez cela avec iContract, où
la postcondition peut simplement faire« référence
Variable @pre », ou avec Eiffel, qui
p er
Enfin, le système d'exécution et les bibliothèques ne sont pas conçus pour prendre en charge
contrats, ces appels ne sont donc pas contrôlés. C'est une grande perte, car c'est
souvent à la frontière entre votre code et les bibliothèques qu'il utilise que le
la plupart des problèmes sont détectés (voir Dead Programs Tell No Lies pour plus
discussion détaillée).
Support
Support linguistique
linguistique
Mais qu'en est-il des langages plus populaires tels que C, C++ et Java ? Pour
ces langages, il existe des préprocesseurs qui traitent les contrats embarqués
dans le code source d'origine sous forme de commentaires spéciaux. Le préprocesseur développe
ces commentaires au code qui vérifie les assertions.
Pour C et C++, vous voudrez peut-être étudier Nana [ URL 18 ]. Nana n'est pas
gérer l'héritage, mais il utilise le débogueur au moment de l'exécution pour surveiller
affirmations d'une manière inédite.
Pour Java, il y a iContract [ URL 17 ]. Il prend des commentaires (sous forme JavaDoc)
et génère un nouveau fichier source avec la logique d'assertion incluse.
Les préprocesseurs ne sont pas aussi bons qu'une installation intégrée. Ils peuvent être salissants pour
intégrer dans votre projet, et les autres bibliothèques que vous utilisez n'auront pas de contrats.
Mais ils peuvent toujours être très utiles ; lorsqu'un problème est découvert ceci
façon - surtout un que vous n'auriez jamais trouvé - c'est presque comme
la magie.
DBC
DBC et
et Crashing
Crashing Early
Early
DBC correspond bien à notre concept de plantage précoce (voir Programmes morts
Ne dis pas de mensonges). Supposons que vous ayez une méthode qui calcule les racines carrées (comme
comme dans la classe Eiffel DOUBLE ). Il a besoin d'une condition préalable qui limite la
domaine aux nombres positifs. Une précondition Eiffel est déclarée avec le
mot-clé exigent, et une postcondition est déclarée avec assurer, vous pouvez donc
éc eri
Autres
Autres utilisations
utilisations des
des invariants
invariants
Jusqu'à présent, nous avons discuté des conditions préalables et postérieures qui s'appliquent aux individus.
méthodes et invariants qui s'appliquent à toutes les méthodes d'une classe, mais il
sont d'autres façons utiles d'utiliser les invariants.
Invariants
Invariants de
de boucle
boucle
Obtenir les bonnes conditions aux limites sur une boucle non trMal peut être
problématique. Les boucles sont sujettes au problème de la banane (je sais épeler
« banane », mais je ne sais pas quand m'arrêter), erreurs de clôture (ne sachant pas
s'il faut compter les poteaux de clôture ou les espaces entre eux), et le
erreur omniprésente "off by one" [ URL 52
].
Les invariants peuvent aider dans ces situations : un invariant de boucle est une déclaration de
l'objectif final d'une boucle, mais est généralisé de sorte qu'il est également valable avant
la boucle s'exécute et à chaque itération de la boucle. Tu peux y penser
comme une sorte de contrat miniature. L'exemple classique est une routine qui trouve
al av
Invariants
Invariants sémantiques
sémantiques
Vous pouvez utiliser des invariants sémantiques pour exprimer des exigences inviolables, une sorte
de "contrat philosophique".
Nous avons déjà écrit un commutateur de transaction par carte de débit. Une exigence majeure était
que l'utilisateur
appliqué d'une carte
à leur compte deuxdefois.
débit
Enne devraittermes,
d'autres jamais quel
effectuer la même
que soit le typetransaction
de
le mode d'échec peut se produire, l'erreur doit être du côté de non
traiter une transaction plutôt que de traiter une transaction en double.
Cette loi simple, directement inspirée des exigences, s'est avérée très
utile pour trier les scénarios de récupération d'erreurs complexes, et guidé le
conception détaillée et mise en œuvre dans de nombreux domaines.
Veillez à ne pas confondre les exigences qui sont des lois fixes et inviolables avec
ceux qui ne sont que des politiques susceptibles de changer avec une nouvelle direction
régime. C'est pourquoi nous utilisons le terme d'invariants sémantiques - il doit être
central au sens même d'une chose, et non soumis aux caprices de
policy (à quoi servent les règles métier plus dynamiques).
Lorsque vous trouvez une exigence qui se qualifie, assurez-vous qu'elle devient une
partie bien connue de la documentation que vous produisez, qu'elle soit
il s'agit d'une liste à puces dans le document d'exigences qui est signé
triple exemplaire ou juste une grosse note sur le tableau blanc commun que tout le monde voit.
Essayez de l'énoncer clairement et sans ambiguïté. Par exemple, dans la carte de débit
exemple, on pourrait écrire
E RR EN FAVEUR DU CONSOMMATEUR .
Il s'agit d'une déclaration claire, concise et sans ambiguïté qui s'applique dans de nombreux
différents domaines du système. C'est notre contrat avec tous les utilisateurs du système,
notre garantie de comportement.
Contrats
Contrats et
et agents
agents dynamiques
dynamiques
Il est certain que tout système qui s'appuie sur la technologie des agents a un rôle critique à jouer
dépendance vis-à-vis des accords contractuels, même s'ils sont dynamiquement
généré.
Mais si nous ne pouvons pas utiliser les contrats à la main, nous ne pourrons pas les utiliser
automatiquement. Alors la prochaine fois que vous concevez un logiciel, concevez son
contrat aussi.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Orthogonalité
• • Les programmes morts ne mentent pas
• • Programmation affirmée
• • Comment équilibrer les ressources
• • Le découplage et la loi de Déméter
• • Couplage temporel
• • Programmation par coïncidence
• • Code facile à tester
• • Des équipes pragmatiques
Défis
Défis
• • Points à méditer : Si DBC est si puissant, pourquoi n'est-il pas utilisé plus
largement? Est-ce difficile de trouver le contrat ? Est-ce que ça te fait
pensez à des problèmes que vous préférez ignorer pour l'instant ? Cela vous oblige-t-il à
PENSER!? Clairement, c'est un outil dangereux !
Des
Des exercices
exercices
14.
14. Qu'est-ce qui fait un bon contrat ? N'importe qui peut ajouter des conditions préalables et
postconditions, mais vous seront-elles utiles ? Pire encore, vont-ils
fait plus de mal que de bien ? Pour l'exemple ci-dessous et pour
ceux des Exercices 15 et 16, décidez si le contrat spécifié est
bon, mauvais ou laid, et expliquez pourquoi.
Prenons d'abord un exemple Eiffel. Ici, nous avons une routine pour
ajouter une chaîne à une liste circulaire doublement liée (rappelez-vous que
les préconditions sont étiquetées avec require et les postconditions avec
a s
15.
15. Ensuite, essayons un exemple en Java, un peu similaire à l'exemple
dans l'exercice 14. insertNumber insère un entier dans une liste ordonnée.
eL s
16.
16. Voici un fragment d'une classe de pile en Java. Est-ce un bon contrat ?
/
17.
17. Les exemples classiques de DBC (comme dans les Exercices 14-16) montrent une
implémentation d'un ADT (Abstract Data Type) - généralement une pile ou
file d'attente. Mais peu de gens écrivent vraiment ce genre de messages de bas niveau
Des classes .
Donc, pour cet exercice, concevez une interface vers un mixeur de cuisine. Ce sera
éventuellement être un mélangeur basé sur le Web, compatible Internet et CORBA,
mais pour l'instant nous avons juste besoin de l'interface pour le contrôler. Il a dix vitesses
paramètres (0 signifie désactivé). Vous ne pouvez pas le faire fonctionner à vide, et vous pouvez changer
la vitesse une seule unité à la fois (c'est-à-dire de 0 à 1, et de 1 à 2,
pas de 0 à 2).
18.
18. Combien y a-t-il de nombres dans la série 0,5,10,15,…, 100 ?
Les
Les programmes
programmes morts
morts ne
ne mentent
mentent pas
pas
Avez-vous remarqué que parfois d'autres personnes peuvent détecter que les choses ne sont pas
bien avec vous avant de vous rendre compte du problème vous-même ? C'est le même
avec le code des autres. Si quelque chose commence à mal tourner avec l'un de nos
programmes, c'est parfois une routine de bibliothèque qui l'attrape en premier. Peut-être un
pointeur errant nous a fait écraser un descripteur de fichier avec quelque chose
sans signification. Le prochain appel à lire l'attrapera. Peut-être un dépassement de tampon
a détruit un compteur que nous sommes sur le point d'utiliser pour déterminer la quantité de mémoire à
allouer. Peut-être que nous aurons un échec de malloc. Une erreur de logique quelques
il y a un million d'instructions signifie que le sélecteur d'une instruction case n'est pas
plus le 1, 2 ou 3 attendu. Nous allons frapper le cas par défaut (ce qui est l'une des raisons
pourquoi chaque instruction case/switch doit avoir une valeur par défaut
clause - nous voulons savoir quand "l'impossible" s'est produit).
Il est facile de tomber dans la mentalité "ça ne peut pas arriver". La plupart d'entre nous ont écrit
code qui n'a pas vérifié qu'un fichier s'est bien fermé, ou qu'une trace
la déclaration a été rédigée comme prévu. Et toutes choses étant égales par ailleurs, il est probable
dont nous n'avions pas besoin - le code en question n'échouerait pas dans des conditions normales
conditions. Mais nous codons défensivement. Nous recherchons des pointeurs malveillants dans
d'autres parties de notre programme saccageant la pile. Nous vérifions que le
les versions correctes des bibliothèques partagées ont été effectivement chargées.
Toutes les erreurs vous donnent des informations. Vous pourriez vous convaincre que l'erreur
ne peut pas arriver, et choisissez de l'ignorer. Au lieu de cela, les programmeurs pragmatiques disent
eux-mêmes que s'il y a une erreur, quelque chose de très, très mauvais a
arrivé.
Astuce
Astuce 32
32
Accident précoce
Crash,
Crash, ne
ne pas
pas jeter
jeter
L'un des avantages de détecter les problèmes le plus tôt possible est que vous pouvez
planter plus tôt. Et souvent, planter votre programme est la meilleure chose que vous
peut faire. L'alternative peut être de continuer, en écrivant des données corrompues sur certains
base de données vitale ou commander la machine à laver dans son vingtième
cycle d'essorage consécutif.
Vous pouvez faire la même chose dans d'autres langues. Si vous n'avez pas d'exception
mécanisme, ou si vos bibliothèques ne lèvent pas d'exceptions, assurez-vous que vous
g éer
ov di
sEn u
En c a
De toute évidence, il est parfois inapproprié de simplement quitter un programme en cours d'exécution.
Vous avez peut-être réclamé des ressources qui pourraient ne pas être libérées, ou vous pouvez
besoin d'écrire des messages de journal, de ranger les transactions ouvertes ou d'interagir avec
d'autres processus. Les techniques dont nous discutons dans Quand utiliser , sera
les exceptions
aide ici. Cependant, le principe de base reste le même : lorsque votre code
découvre que quelque chose qui était censé être impossible vient de se produire,
votre programme n'est plus viable. Tout ce qu'il fait à partir de maintenant
devient suspect, alors mettez-y fin dès que possible. Un programme mort
fait normalement beaucoup moins de dégâts qu'un infirme.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Programmation
Programmation assertive
assertive
Oscar
Oscar Wilde,
Wilde, Le
Le Portrait
Portrait de
de Dorian
Dorian Gray
Gray
"Ce code ne sera plus utilisé dans 30 ans, donc les dates à deux chiffres conviennent."
« Cette application ne sera jamais utilisée à l'étranger, alors pourquoi l'internationaliser ?
"count ne peut pas être négatif." "Ce printf ne peut pas échouer."
Astuce
Astuce 33
33
Si cela ne peut pas se produire, utilisez des assertions pour vous assurer que cela ne se produira pas
Chaque fois que vous vous surprenez à penser "mais bien sûr cela ne pourrait jamais
arrive", ajoutez du code pour le vérifier. La façon la plus simple de le faire est d'utiliser des assertions.
Dans la plupart des implémentations C et C++, vous trouverez une affirmer
certaine
ouforme de
Macro _assert qui vérifie une condition booléenne. Ces macros peuvent être
ein s
p u
Les assertions sont également des contrôles utiles sur le fonctionnement d'un algorithme. Peut-être avez-vous
éc tri
Bien sûr, la condition passée à une assertion ne doit pas avoir d'effet secondaire
(voir encadré page 124). Rappelez-vous également que les assertions peuvent être désactivées
a u
N'utilisez pas d'assertions à la place d'une véritable gestion des erreurs. Vérification des assertions
d e
Et juste parce que les macros assert fournies appellent exit lorsqu'une assertion
échoue, il n'y a aucune raison pour que les versions que vous écrivez échouent. Si vous avez besoin de libérer
Laisser
Laisser les
les assertions
assertions activées
activées
Désactiver les assertions lorsque vous livrez un programme à la production, c'est comme
franchir un fil sans filet parce que vous l'avez traversé une fois en
pratique. Il y a une valeur considérable, mais il est difficile d'obtenir une assurance-vie.
Même si vous rencontrez des problèmes de performances, désactivez uniquement les assertions qui
t'a vraiment frappé. L'exemple de tri ci-dessus peut être un élément essentiel de
C'est gênant quand le code que nous ajoutons pour détecter les erreurs
finit par créer de nouvelles erreurs. Cela peut arriver avec des assertions si
l'évaluation de la condition a des effets secondaires. par exemple, en Java, il
serait mauvais de coder quelque chose comme
ewhil (
votre application, et peut devoir être rapide. Ajouter le chèque signifie un autre
passer par les données, ce qui pourrait être inacceptable. Rendez cela particulier
[2] mais laissez le reste dedans.
cocher en option,
[2] Dans les langages basés sur C, vous pouvez soit utiliser le préprocesseur, soit utiliser des instructions if pour rendre les assertions facultatives. Beaucoup
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Débogage
• • Conception par contrat
• • Comment équilibrer les ressources
• • Programmation par coïncidence
Des
Des exercices
exercices
19.
19. Une rapide vérification de la réalité. Laquelle de ces choses "impossibles" peut arriver ?
annuaire)
3 .
4. 4. Un triangle avec une somme d'angle intérieur \u8800 180°
5. 5. Une minute qui n'a pas 60 secondes
6 .
20.
20. Développer une simple classe de vérification d'assertions pour Java .
Quand
Quand utiliser
utiliser les
les exceptions
exceptions
Dans Dead Programs Tell No Lies , nous avons suggéré qu'il est bon de
recherchez toutes les erreurs possibles, en particulier les erreurs inattendues. Cependant,
en pratique, cela peut conduire à un code assez laid ; la logique normale de votre
programme peut finir par être totalement obscurci par la gestion des erreurs, en particulier si
vous êtes abonné à l'école "une routine doit avoir une seule déclaration de retour"
de programmation (nous ne le faisons pas). Nous avons vu du code qui ressemble à quelque chose comme
s u
Le flux normal de contrôle est maintenant clair, avec toute la gestion des erreurs déplacée
vers un seul endroit.
Qu'est-ce
Qu'est-ce qui
qui est
est exceptionnel
exceptionnel ??
L'un des problèmes avec les exceptions est de savoir quand les utiliser. Nous
croient que les exceptions devraient rarement être utilisées dans le cadre du fonctionnement normal d'un programme
couler; les exceptions doivent être réservées aux événements imprévus. Supposons qu'un
une exception non détectée mettra fin à votre programme et vous demandera : "Est-ce que
ce code s'exécute toujours si je supprime tous les gestionnaires d'exceptions ?" Si la réponse est
"non", alors peut-être que des exceptions sont utilisées dans des cas non exceptionnels
circonstances.
Par exemple, si votre code tente d'ouvrir un fichier en lecture et que ce fichier ne
n'existe pas, faut-il lever une exception ?
Notre réponse est : "Cela dépend." Si le fichier aurait dû être là, alors un
exception est justifiée. Quelque chose d'inattendu s'est produit : un fichier que vous étiez
s'attendre à exister semble avoir disparu. D'autre part, si vous
n'ont aucune idée si le fichier doit exister ou non, alors il ne semble pas
exceptionnel si vous ne le trouvez pas, et un retour d'erreur est approprié.
p u
Cependant, le deuxième cas peut impliquer l'ouverture d'un fichier spécifié par l'utilisateur
sur la ligne de commande. Ici, une exception n'est pas justifiée, et le code semble
d iféer
Notez que l'appel FileInputStream peut toujours générer une exception, qui
la routine passe. Cependant, l'exception sera générée uniquement sous
circonstances vraiment exceptionnelles; simplement essayer d'ouvrir un fichier qui ne
exist générera un retour d'erreur conventionnel.
Astuce
Astuce 34
34
Les
Les gestionnaires
gestionnaires d'erreurs
d'erreurs sont
sont une
une alternative
alternative
Un gestionnaire d'erreurs est une routine appelée lorsqu'une erreur est détectée. Toi
peut enregistrer une routine pour gérer une catégorie spécifique d'erreurs. Quand l'un de
ces erreurs se produisent, le gestionnaire sera appelé.
Il y a des moments où vous voudrez peut-être utiliser des gestionnaires d'erreurs, soit au lieu de
ou à côté des exceptions. De toute évidence, si vous utilisez un langage tel que C,
qui ne prend pas en charge les exceptions, c'est l'une de vos quelques autres options (voir
le défi à la page suivante). Cependant, les gestionnaires d'erreurs peuvent parfois être
utilisé même dans les langages (tels que Java) qui ont une bonne gestion des exceptions
schéma intégré.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
• • Les langages qui ne prennent pas en charge les exceptions ont souvent d'autres
transfert non local du mécanisme de contrôle (C a longjmp/setjmp, pour
exemple). Considérez comment vous pourriez implémenter une sorte d'ersatz
mécanisme d'exception utilisant ces facilités. Quels sont les bénéfices
et périls ? Quelles mesures spéciales devez-vous prendre pour vous assurer que
les ressources ne sont pas orphelines ? Est-il judicieux d'utiliser ce type de
solution chaque fois que vous codez en C?
Des
Des exercices
exercices
21.
21. Lors de la conception d'une nouvelle classe de conteneur, vous identifiez les éléments suivants
Comment
Comment équilibrer
équilibrer les
les ressources
ressources
Bill
Bill Cosby,
Cosby, Paternité
Paternité
Nous gérons tous des ressources à chaque fois que nous codons : mémoire, transactions, threads,
mouches, minuteries - toutes sortes de choses avec une disponibilité limitée. La plupart du temps,
l'utilisation des ressources suit un schéma prévisible : vous allouez la ressource, utilisez
puis désallouez-le.
Cependant, de nombreux développeurs n'ont pas de plan cohérent pour faire face à
allocation et désallocation des ressources. Alors laissez-nous vous suggérer une astuce simple :
Astuce
Astuce 35
35
Cette astuce est facile à appliquer dans la plupart des cas. Cela signifie simplement que le
la routine ou l'objet qui alloue une ressource doit être responsable de
le désaffecter. Voyons comment cela s'applique en regardant un exemple de certains
mauvais code - une application qui ouvre un fichier, lit les informations client
à partir de celui-ci, met à jour un champ et réécrit le résultat. Nous avons éliminé l'erreur
am pni
ov di
À première vue, la routine updateCustomer semble plutôt bonne. Il semble
mettre en œuvre la logique dont nous avons besoin - lecture d'un enregistrement, mise à jour du solde,
et réécrire l'enregistrement. Cependant, cette propreté cache une grande
problème. Les routines readCustomer et writeCustomer sont étroitement couplés [3]
[3] Pour une discussion sur les dangers du code couplé, voir Decoupling and the Law of Demeter .
} }
Tout semble correct lors des tests. Cependant, lorsque le code entre en production,
il s'effondre après plusieurs heures, se plaignant d'un trop grand nombre de fichiers ouverts. Parce que
writeBalance n'est pas appelé dans certaines circonstances, le fichier n'est pas
se fermer.
Cela résoudra le problème - le fichier sera désormais fermé quel que soit le nouveau
équilibre,
le Global mais le correctif
cFichier. signifie
On tombe dansdésormais que
un piège, et lestrois routines
choses vontsont couplées via
commencer
descente rapide si nous continuons sur ce parcours.
Le conseil Finissez ce que vous commencez nous dit que, idéalement, la routine qui alloue
une ressource devrait aussi le libérer. Nous pouvons l'appliquer ici en refactorisant le code
lég èer
ov di
Allocations
Allocations d'imbrication
d'imbrication
Le modèle de base pour l'allocation des ressources peut être étendu pour les routines qui
besoin de plus d'une ressource à la fois. Il n'y a plus que deux
suggestions:
1. 1. Libérez les ressources dans l'ordre inverse de celui dans lequel vous
les allouer. De cette façon, vous n'aurez pas de ressources orphelines si une ressource
contient des références à un autre.
2. 2. Lors de l'allocation du même ensemble de ressources à différents endroits
votre code, attribuez-les toujours dans le même ordre. Cela réduira
la possibilité d'un blocage. (Si le processus A revendique la ressource1 et est
sur le point de réclamer la ressource2, tandis que le processus B a réclamé la ressource2 et
essaie d'obtenirressource1, les deux processus attendront indéfiniment.)
Objets
Objets et
et exceptions
exceptions
Cette approche présente des avantages particuliers lorsque vous travaillez avec des langues
comme C++, où les exceptions peuvent interférer avec la désallocation des ressources.
Équilibrage
Équilibrage et
et exceptions
exceptions
Les langages qui prennent en charge les exceptions peuvent compliquer la désallocation des ressources.
Si une exception est levée, comment garantissez-vous que tout ce qui est alloué
avant l'exception est rangé? La réponse dépend dans une certaine mesure de
la langue.
Équilibrage
Équilibrage des
des ressources
ressources avec
avec des
des exceptions
exceptions C++
C++
Notez que le nœud que nous créons est libéré à deux endroits—une fois dans la routine
chemin de sortie normal et une fois dans le gestionnaire d'exceptions. C'est une évidence
violation du principe DRY et un problème de maintenance en attente de
arriver.
Cependant, nous pouvons utiliser la sémantique de C++ à notre avantage. Objets locaux
sont automatiquement détruits en sortant de leur bloc englobant. Ce
nous donne quelques options. Si les circonstances le permettent, nous pouvons changer "n"
d 'u
Ici, nous nous appuyons sur C++ pour gérer la destruction de l'objet Node
automatiquement, qu'une exception soit levée ou non.
Si le passage d'un pointeur n'est pas possible, le même effet peut être obtenu
en enveloppant la ressource (dans ce cas, oPun
Désormais, la classe wrapper, NodeResource, garantit que lorsque ses objets sont
détruits les nœuds correspondants sont également détruits. Pour plus de commodité, le
wrapper fournit un opérateur de déréférencement
->, afin que ses utilisateurs puissent accéder
directement les champs de l'objet Node contenu.
Parce que cette technique est si utile, la bibliothèque C++ standard fournit la
classe de modèle auto_ptr, qui vous donne des wrappers automatiques pour
o b
Équilibrage
Équilibrage des
des ressources
ressources en
en Java
Java
Contrairement à C++, Java implémente une forme paresseuse de destruction automatique d'objets.
Les objets non référencés sont considérés comme candidats à la récupération de place,
et leur méthode finalize sera appelée si jamais la collecte des ordures
les réclamer. Bien qu'il s'agisse d'une commodité pour les développeurs, qui n'obtiennent plus le
responsable de la plupart des fuites de mémoire, il est difficile d'implémenter des ressources
nettoyage à l'aide du schéma C++. Heureusement, les concepteurs de Java
la langue a judicieusement ajouté une fonctionnalité de langue pour compenser,
e le
clause. Lorsqu'un Le bloc try contient une clause finally, le code de cette clause est
garantie d'être exécutée si une instruction du bloc try est exécutée. Il
n'a pas d'importance si une exception est levée (ou même si le code dans le
try block exécute un return )—le code de la clause finally sera exécuté.
C e
} }
La routine utilise un fichier temporaire, que nous voulons supprimer, quel que soit
comment la routine se termine.Le bloc
Le finally nous permet d'exprimer cela de manière concise.
Lorsque
Lorsque vous
vous ne
ne pouvez
pouvez pas
pas équilibrer
équilibrer les
les ressources
ressources
Il y a des moments où le modèle d'allocation des ressources de base n'est tout simplement pas
approprié. Généralement, cela se trouve dans les programmes qui utilisent des données dynamiques
structures. Une routine allouera une zone de mémoire et la reliera à
une structure plus grande, où il peut rester pendant un certain temps.
Enfin, si le suivi des ressources devient difficile, vous pouvez écrire votre propre
forme de ramasse-miettes automatique limité en implémentant une référence
schéma de comptage sur vos objets alloués dynamiquement. Le livre Plus
Effective C++ [ Mey96 ] consacre une section à ce sujet.
Vérification
Vérification du
du solde
solde
Parce que les programmeurs pragmatiques ne font confiance à personne, y compris à nous-mêmes, nous nous sentons
que c'est toujours une bonne idée de construire du code qui vérifie réellement que
les ressources sont en effet libérées de manière appropriée. Pour la plupart des applications, cela
signifie normalement produire des emballages pour chaque type de ressource, et utiliser
ces wrappers pour garder une trace de toutes les allocations et désallocations. A certains
points dans votre code, la logique du programme dictera que les ressources seront
dans un certain état : utilisez les emballages pour vérifier cela.
Par exemple, un programme de longue durée qui traite les demandes sera probablement
avoir un seul point au sommet de sa boucle de traitement principale où il attend
la prochaine demande d'arriver. C'est un bon endroit pour s'assurer que la ressource
l'utilisation n'a pas augmenté depuis la dernière exécution de la boucle.
A un niveau inférieur, mais non moins utile, vous pouvez investir dans des outils qui (parmi
d'autres choses) vérifiez vos programmes en cours d'exécution pour les fuites de mémoire. Purifier
( http://www.rational.com ) et Insure++ ( http://www.parasoft.com ) sont
choix populaires.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
Des
Des exercices
exercices
22. C
22. e
après avoir libéré la mémoire à laquelle il fait référence. Pourquoi est-ce un bon
idée?
23.
23. Certains développeurs Java mettent un point d'honneur à définir une variable objet sur
NULL après avoir fini d'utiliser l'objet. Pourquoi est-ce une bonne idée ?
Le code que nous écrivons non plus. Afin de suivre l'actualité d'aujourd'hui
rythme de changement presque effréné, nous devons faire tout notre possible pour écrire du code
c'est aussi lâche—aussi flexible—que possible. Sinon, nous pourrions trouver notre code
devient rapidement obsolète ou trop fragile pour être réparé, et peut finalement être laissé
en retard dans la course folle vers l'avenir.
En Réversibilité , nous avons évoqué les périls des décisions irréversibles. Dans ce
chapitre, nous vous dirons comment prendre des décisions réversibles, afin que votre code puisse
rester flexible et adaptable face à un monde incertain.
Nous devons d'abord examiner le couplage, c'est-à-dire les dépendances entre les modules de code.
Dans Le découplage et la loi de Déméter, nous montrerons comment rester séparés
les concepts se séparent et diminuent le couplage.
Une bonne façon de rester flexible est d'écrire moins de code. Changer de code vous laisse
ouvert à la possibilité d'introduire de nouveaux bugs. La métaprogrammation va
expliquer comment déplacer complètement les détails du code, où ils peuvent être
changé plus facilement et en toute sécurité.
Dans Couplage
couplage. temporel, sur
Comptez-vous nousle examinerons
« tic » venant deux
avantaspects
le « tac du
» ? temps en relation avec
Pas si vous
veulent rester flexibles.
Un concept clé dans la création de code flexible est la séparation d'un modèle de données
à partir d'une vue ou d'une présentation de ce modèle. Nous découplerons les modèles de
vues dans C'est juste une vue.
Enfin, il existe une technique pour découpler encore plus les modules en
fournir un lieu de rencontre où les modules peuvent échanger des données de manière anonyme
et de manière asynchrone. C'est le sujet des tableaux noirs.
Armé de ces techniques, vous pouvez écrire du code qui "roulera avec le
coups de poing."
Le
Le découplage
découplage et
et la
la loi
loi de
de Déméter
Déméter
Robert
Robert Frost,
Frost, "Réparer
"Réparer le
le mur"
mur"
Les espions, les dissidents, les révolutionnaires, etc. sont souvent organisés en petits
groupes de personnes appelés cellules. Bien que les individus de chaque cellule puissent savoir
les uns des autres, ils n'ont aucune connaissance de ceux des autres cellules. Si une cellule est
découvert, aucune quantité de sérum de vérité ne révélera les noms des autres
à l'extérieur de la cellule. L'élimination des interactions entre les cellules protège tout le monde.
Nous pensons que c'est un bon principe à appliquer également au codage. Organiser
votre code dans des cellules (modules) et limitez l'interaction entre eux. Si
un module est alors compromis et doit être remplacé, l'autre
les modules devraient pouvoir continuer.
Minimiser
Minimiser le
le couplage
couplage
Qu'y a-t-il de mal à avoir des modules qui se connaissent les uns les autres ? Rien dans
principe - nous n'avons pas besoin d'être aussi paranoïaques que des espions ou des dissidents. Cependant,
vous devez faire attention au nombre d'autres modules avec lesquels vous interagissez
et, plus important encore, comment vous en êtes venu à interagir avec eux.
Supposons que vous rénoviez votre maison ou construisiez une maison à partir de zéro. UN
l'arrangement typique implique un "entrepreneur général". Vous embauchez le
l'entrepreneur pour faire le travail, mais l'entrepreneur peut ou non faire le
construction personnellement; le travail peut être offert à divers sous-traitants.
Mais en tant que client, vous n'êtes pas impliqué dans les relations avec les sous-traitants
directement - l'entrepreneur général suppose que cet ensemble de maux de tête sur votre
au nom de.
Nous aimerions suivre ce même modèle dans le logiciel. Lorsque nous demandons à un objet un
service particulier, nous aimerions que le service soit effectué en notre nom. Nous
ne voulons pas que l'objet nous donne un objet tiers que nous devons traiter
avec pour obtenir le service requis.
Par exemple, supposons que vous écriviez une classe qui génère un graphe de
données des enregistreurs scientifiques. Vous avez des enregistreurs de données répartis dans le monde entier ;
chaque objet enregistreur contient un objet de localisation donnant sa position et son heure
zone. Vous souhaitez permettre à vos utilisateurs de sélectionner un enregistreur et de tracer ses données, étiquetées
a ev
a
Plutôt que de creuser vous-même une hiérarchie, demandez simplement ce que vous
b e
Nous avons ajouté une méthode à Selection pour obtenir le fuseau horaire en notre nom : le
la routine de traçage ne se soucie pas de savoir si le fuseau horaire provient du
Recorder directement, à partir d'un objet contenu dans Recorder, ou si
La sélection constitue un fuseau horaire entièrement différent. La routine de sélection, en
tourner, devrait probablement juste demander à l'enregistreur son fuseau horaire, le laissant jusqu'à
l'enregistreur pour l'obtenir à partir de son objet Location contenu.
Traverser directement les relations entre les objets peut rapidement conduire à une
explosion combinatoire [1] des relations de dépendance. Tu peux voir
symptômes de ce phénomène de plusieurs façons :
[1] Si n objets se connaissent tous, alors un changement sur un seul objet peut avoir pour résultat que les n - 1 autres objets ont besoin
changements.
Les systèmes avec de nombreuses dépendances inutiles sont très difficiles (et
coûteux) à entretenir et ont tendance à être très instables. Afin de garder le
La
La loi
loi de
de Déméter
Déméter pour
pour les
les fonctions
fonctions
Figure
Figure 5.1.
5.1. Loi
Loi de
de Déméter
Déméter pour
pour les
les fonctions
fonctions
En écrivant du code "timide" qui respecte au maximum la Loi de Déméter,
nous pouvons atteindre notre objectif :
Astuce
Astuce 36
36
Cela
Cela fait-il
fait-il vraiment
vraiment une
une différence
différence ??
Bien que cela sonne bien en théorie, suivre la loi de Déméter est-il vraiment
aider à créer un code plus maintenable ?
Des études ont montré [ BBM96 ] que les classes en C++ avec des ensembles de réponses plus grands
sont plus sujettes aux erreurs que les classes avec des ensembles de réponses plus petits (une réponse
set est défini comme étant le nombre de fonctions directement invoquées par les méthodes de
la classe).
Comme pour toute technique, vous devez peser le pour et le contre pour votre
application particulière. Dans la conception de schéma de base de données, il est courant de
« dénormaliser » le schéma pour une amélioration des performances : violer le
règles de normalisation en échange de rapidité. Un compromis similaire peut être
fait ici aussi. En effet, en inversant la Loi de Déméter et en resserrant
en couplant plusieurs modules, vous pourrez réaliser un gain de performances important.
Tant qu'il est bien connu et acceptable que ces modules soient couplés,
ton dessin est bien.
Découplage physique
Dans cette section, nous nous intéressons en grande partie à la conception pour garder
choses logiquement découplées au sein des systèmes. Cependant, il y a
un autre type d'interdépendance qui devient très significatif à mesure que
les systèmes grandissent. Dans son livre Large-scale C++ software Design
[ Lak96 ], John Lakos aborde les questions entourant la
les relations entre les fichiers, les répertoires et les bibliothèques qui font
un système. Les grands projets qui ignorent ces conceptions physiques
les problèmes se terminent par des cycles de construction mesurés en jours et
des tests unitaires qui peuvent traîner dans tout le système en tant que code de support,
entre autres problèmes. M. Lakos soutient de manière convaincante que la logique
et la conception physique doivent aller de pair - que défaire le
les dommages causés à un grand corps de code par des dépendances cycliques sont
extrêmement difficile. Nous recommandons ce livre si vous êtes impliqué dans
Sinon, vous risquez de vous retrouver sur la voie d'un avenir fragile et inflexible.
Ou pas d'avenir du tout.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Orthogonalité
• • Réversibilité
• • Conception par contrat
• • Comment équilibrer les ressources
• • C'est juste une vue
• • Des équipes pragmatiques
• • Tests impitoyables
Défis
Défis
Des
Des exercices
exercices
24.
24. Nous avons discuté du concept de découplage physique dans l'encadré sur le
page en regard. Lequel des en-têtes C++ suivants vole le plus étroitement
couplé au reste du système ?
personne1.h
personne1.h personne2.h
personne2.h ::
#icn d ul
c c al
p p rivé :
p p u
25.
25. Pour l'exemple ci-dessous et pour ceux des Exercices 26 et 27, déterminez
si les appels de méthode indiqués sont autorisés conformément à la loi de
Déméter. Ce premier est en Java .
p u
26.
26. Cet exemple est également en Java.
p u
27.
27. Cet exemple est en C++ .
ov di
Métaprogrammation
Métaprogrammation
La
La huitième
huitième loi
loi de
de Levy
Levy
Les détails gâchent notre code vierge, surtout s'ils changent fréquemment.
Chaque fois que nous devons entrer et changer le code pour tenir compte de certains
changement dans la logique commerciale, ou dans la loi, ou dans les goûts personnels de la direction
du jour, nous courons le risque de casser le système, d'introduire un nouveau
bogue.
Alors on dit "fini les détails !" Sortez-les du code. Pendant qu'on y est,
nous pouvons rendre notre code hautement configurable et "soft", c'est-à-dire facilement
adaptable aux changements.
Configuration
Configuration dynamique
dynamique
Tout d'abord, nous voulons rendre nos systèmes hautement configurables. Pas seulement des choses
tels que les couleurs de l'écran et le texte d'invite, mais des éléments profondément enracinés tels que
le choix des algorithmes, des produits de base de données, de la technologie middleware et
style d'interface utilisateur. Ces éléments doivent être implémentés en tant que configuration
options, pas par l'intégration ou l'ingénierie.
Astuce
Astuce 37
37
Configurez, n'intégrez pas
Utiliser des métadonnées pour décrire les options de configuration d'une application : réglage
paramètres, les préférences de l'utilisateur, le répertoire d'installation, etc.
Qu'est-ce que les métadonnées exactement ? À proprement parler, les métadonnées sont des données sur des données.
L'exemple le plus courant est probablement un schéma de base de données ou des données
dictionnaire. Un schéma contient des données qui décrivent les champs (colonnes) en termes
des noms, des longueurs de stockage et d'autres attributs. Tu devrais être capable de
accéder à ces informations et les manipuler comme vous le feriez pour toute autre donnée
la base de données.
Nous utilisons le terme dans son sens le plus large. Les métadonnées sont toutes les données qui décrivent
l'application - comment elle doit s'exécuter, quelles ressources elle doit utiliser, etc.
En règle générale, les métadonnées sont consultées et utilisées au moment de l'exécution, et non au moment de la compilation.
Vous utilisez des métadonnées tout le temps, du moins vos programmes le font. Supposez que vous
cliquez sur une option pour masquer la barre d'outils de votre navigateur Web. Le navigateur va
stocker cette préférence, sous forme de métadonnées, dans une sorte de base de données interne.
Cette base de données peut être dans un format propriétaire ou utiliser une norme
mécanisme. Sous Windows, soit un fichier d'initialisation (utilisant le
suffixe.ini ) ou des entrées dans le registre du système sont typiques. Sous Unix, le X
Le système de fenêtres fournit des fonctionnalités similaires à l'aide de l'application par défaut
des dossiers. Java utilise des fichiers de propriétés. Dans tous ces environnements, vous spécifiez un
clé pour récupérer une valeur. Alternativement, plus puissant et flexible
les implémentations de métadonnées utilisent un langage de script intégré (voir
Langues du domaine, pour plus de détails).
uPl s
Applications
Applications basées
basées sur
sur les
les métadonnées
métadonnées
Mais nous voulons aller au-delà de l'utilisation de métadonnées pour de simples préférences. Nous voulons
pour configurer et piloter au maximum l'application via les métadonnées.
Notre objectif est de penser de manière déclarative (spécifiant ce qui doit être fait, pas comment)
et créer des programmes hautement dynamiques et adaptables. Nous le faisons en adoptant
une règle générale : programmer pour le cas général, et mettre les spécificités
ailleurs, en dehors de la base de code compilée.
Astuce
Astuce 38
38
Mettre des abstractions dans les détails du code dans les métadonnées
• • Cela vous oblige à découpler votre conception, ce qui se traduit par une
programme flexible et adaptable.
• • Cela vous oblige à créer une conception abstraite plus robuste en
différer les détails - les différer complètement du programme.
• • Vous
peut pouvez personnaliser
également l'application
utiliser ce niveau sans la recompiler.
de personnalisation pour Toi
fournir des solutions de contournement faciles
pour les bogues critiques dans les systèmes de production en direct.
• • Les métadonnées peuvent être exprimées d'une manière beaucoup plus proche du
domaine problématique qu'un langage de programmation à usage général
pourrait être (voir Langues du domaine
).
• • Vous pouvez même être en mesure de mettre en œuvre plusieurs projets différents
utilisant le même moteur d'application, mais avec des métadonnées différentes.
Nous voulons différer la définition de la plupart des détails jusqu'au dernier moment, et laisser
les détails aussi doux - aussi faciles à changer - que possible. En élaborant une solution
qui nous permet d'apporter des changements rapidement, nous avons de meilleures chances de faire face
avec le flot de changements de direction qui submergent de nombreux projets (voir
Réversibilité ).
Logique
Logique métier
métier
Vous avez donc fait du choix du moteur de base de données une option de configuration, et
fourni des métadonnées pour déterminer le style de l'interface utilisateur. Pouvons-nous faire plus?
Certainement.
Parce que la politique et les règles commerciales sont plus susceptibles de changer que tout autre
aspect du projet, il est logique de les maintenir dans un cadre très flexible
format.
Par exemple, votre application d'achat peut inclure diverses informations d'entreprise
Stratégies. Peut-être que vous payez les petits fournisseurs en 45 jours et les grands en 90
jours. Faire les définitions des types de fournisseurs, ainsi que les périodes de temps
eux-mêmes, configurables. Profitez-en pour généraliser.
Peut-être que vous écrivez un système avec des exigences de flux de travail épouvantables.
Les actions démarrent et s'arrêtent selon des règles métier complexes (et changeantes).
Envisagez de les encoder dans une sorte de système basé sur des règles (ou expert),
intégré dans votre application. De cette façon, vous le configurerez en écrivant
règles, pas couper le code.
Une logique moins complexe peut être exprimée à l'aide d'un mini-langage, supprimant
besoin de recompiler et de redéployer lorsque l'environnement change. Regarde
à la page 58 pour un exemple.
Quand configurer
Réfléchissez donc à la manière dont votre application sera utilisée : s'il s'agit d'une application de longue durée
processus serveur, vous voudrez fournir un moyen de relire et
appliquer les métadonnées pendant l'exécution du programme. Pour un petit client
Application graphique qui redémarre rapidement, vous n'en aurez peut-être pas besoin.
Ce phénomène n'est pas limité au code d'application. Nous avons tous été
ennuyé par les systèmes d'exploitation qui nous obligent à redémarrer lorsque nous
installer une application simple ou modifier un paramètre inoffensif.
Un
Un exemple
exemple :: Enterprise
Enterprise Java
Java Beans
Beans
La bonne nouvelle, c'est que vous n'avez pas à vous soucier de tout cela. Vous écrivez un
haricot—un objet autonome qui suit certaines conventions—et placez-le
dans un conteneur de grains qui gère une grande partie des détails de bas niveau sur votre
au nom de. Vous pouvez écrire le code d'un bean sans inclure aucune transaction
gestion des opérations ou des threads ; EJB utilise des métadonnées pour spécifier comment
les transactions doivent être traitées.
L'allocation de threads et l'équilibrage de charge sont spécifiés en tant que métadonnées pour le
service de transaction sous-jacent utilisé par le conteneur. Cette séparation
nous permet une grande flexibilité pour configurer dynamiquement l'environnement, à
Durée.
Le conteneur du bean peut gérer les transactions au nom du bean dans l'un des
plusieurs styles différents (y compris une option où vous contrôlez votre propre
commits et rollbacks). Tous les paramètres qui affectent le bean's
comportement sont spécifiés dans le descripteur de déploiement du bean, un
objet qui contient les métadonnées dont nous avons besoin.
Les systèmes distribués tels que les EJB ouvrent la voie à un nouveau monde de
systèmes configurables et dynamiques.
Configuration
Configuration coopérative
coopérative
Nous avons parlé des utilisateurs et des développeurs configurant des applications dynamiques.
Mais que se passe-t-il si vous laissez les applications se configurer mutuellement ?
qui s'adapte à son environnement ? Non planifié, impulsif
configuration de logiciels existants est un concept puissant.
Vos applications plus volumineuses ont probablement déjà des problèmes de gestion
différentes versions de données et différentes versions de bibliothèques et d'exploitation
systèmes. Peut-être qu'une approche plus dynamique aidera.
N'écrivez
N'écrivez pas
pas Dodo-Code
Dodo-Code
Sans métadonnées, votre code n'est pas aussi adaptable ou flexible qu'il pourrait l'être. Est
c'est une mauvaise chose? Eh bien, ici dans le monde réel, les espèces qui ne s'adaptent pas
mourir.
Le dodo ne s'est pas adapté à la présence des humains et de leur bétail sur le
l'île Maurice, et s'est rapidement éteinte. [2] C'était la première
l'extinction documentée d'une espèce par l'homme.
[2] Cela n'a pas aidé que les colons battent à mort les oiseaux placides (lire stupides) avec des clubs de sport.
Ne laissez pas votre projet (ou votre carrière) prendre le chemin du dodo.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Orthogonalité
• • Réversibilité
• • Langues du domaine
• • La puissance du texte brut
Défis
Défis
Des
Des exercices
exercices
28.
28. Laquelle des choses suivantes serait mieux représentée sous forme de code
au sein d'un programme, et lesquelles en externe comme métadonnées ?
Couplage
Couplage temporel
temporel
Le temps est un aspect souvent ignoré des architectures logicielles. La seule fois
qui nous préoccupe, c'est le temps sur l'horaire, le temps qu'il nous reste jusqu'à ce que nous
navire, mais ce n'est pas de cela dont nous parlons ici. Au lieu de cela, nous parlons
sur le rôle du temps en tant qu'élément de conception du logiciel lui-même. Il y a
deux aspects du temps qui sont importants pour nous : la simultanéité (les choses
qui se passe en même temps) et l'ordre (les positions relatives des choses
à l'heure).
Nous n'abordons généralement pas la programmation avec l'un ou l'autre de ces aspects dans
esprit. Lorsque les gens s'assoient pour la première fois pour concevoir une architecture ou écrire un
programme, les choses ont tendance à être linéaires. C'est ainsi que la plupart des gens pensent—font
ceci et ensuite toujours faire cela. Mais penser de cette façon conduit à
couplage : couplage dans le temps. La méthode A doit toujours être appelée avant la méthode
B; un seul rapport peut être exécuté à la fois ; vous devez attendre que l'écran
redessiner avant que le clic sur le bouton ne soit reçu. Le tic doit arriver avant le tac.
couvrir les bases, y compris la planification, l'impasse, la famine, l'exclusion mutuelle/les sémaphores, etc.
Flux
Flux de
de travail
travail
Sur de nombreux projets, nous devons modéliser et analyser les flux de travail des utilisateurs comme
partie de l'analyse des besoins. Nous aimerions savoir ce qui peut arriver au
en même temps, et ce qui doit se passer dans un ordre strict. Une façon de faire est de
capturer leur description du flux de travail en utilisant une notation telle que l'UML
Diagramme d'activité.
[4]
[4] Pour plus d'informations sur tous les types de diagrammes UML, voir [ FS97 ].
Un diagramme d'activités est constitué d'un ensemble d'actions dessinées sous forme de cases arrondies.
La flèche quittant une action mène soit à une autre action (qui peut commencer
une fois la première action terminée) ou à une ligne épaisse appelée une synchronisation
bar. Une fois que toutes les actions menant à une barre de synchronisation sont terminées,
vous pouvez ensuite suivre les flèches qui quittent la barre. Une action sans
les flèches qui y mènent peuvent être lancées à tout moment.
Vous pouvez utiliser des diagrammes d'activité pour maximiser le parallélisme en identifiant
activités qui pourraient être réalisées en parallèle, mais qui ne le sont pas.
Astuce
Astuce 39
39
Par exemple, dans notre projet blender (Exercice 17, page 119), les utilisateurs peuvent
décrivez d'abord leur flux de travail actuel comme suit.
1. 1. Ouvrir le mixeur
2. 2. Ouvrir le mélange de piña colada
3. 3. Mettre le mélange dans le mélangeur
4. 4. Mesurer 1/2 tasse de rhum blanc
5. 5. Verser le rhum
6. 6. Ajouter 2 tasses de glace
7. 7. Fermez le mélangeur
8. 8. Liquéfier pendant 2 minutes
9. 9. Ouvrir le mixeur
10. 10. Obtenez des lunettes
11. 11. Obtenez des parapluies roses
12. 12. Servir
Figure
Figure 5.2.
5.2. Diagramme
Diagramme d'activité
d'activité UML
UML :: faire
faire une
une piña
piña colada
colada
Il peut être révélateur de voir où les dépendances existent réellement. Dans ce
exemple, les tâches de niveau supérieur (1, 2, 4, 10 et 11) peuvent toutes se produire simultanément,
à l'avant. Les tâches 3, 5 et 6 peuvent se dérouler en parallèle plus tard.
Architecture
Architecture
Nous avons écrit un système de traitement des transactions en ligne (OLTP) en quelques années
il y a. Dans sa forme la plus simple, tout ce que le système avait à faire était de lire une demande et de traiter
la transaction par rapport à la base de données. Mais nous avons écrit un trois niveaux,
application distribuée multitraitement : chaque composant était un
entité indépendante qui fonctionnait en même temps que tous les autres composants. Alors que
cela ressemble à plus de travail, ce n'était pas : profiter du temps
le découplage a facilité l'écriture. Regardons de plus près ce projet.
Le système prend en charge les demandes d'un grand nombre de communications de données
lignes et traite les transactions par rapport à une base de données principale.
La solution qui nous a donné les meilleures performances et l'architecture la plus propre
ressemblait à quelque chose comme . la figure 5.3
Figure
Figure 5.3.
5.3. Présentation
Présentation de
de l'architecture
l'architecture OLTP
OLTP
Chaque case représente un processus distinct ; les processus communiquent via le travail
files d'attente. Chaque processus d'entrée surveille une ligne de communication entrante, et
fait des requêtes au serveur d'application. Toutes les requêtes sont asynchrones : comme
dès que le processus d'entrée fait sa demande en cours, il revient à
surveiller la ligne pour plus de trafic. De même, le serveur d'application effectue
requêtes du processus de base de[5] et est averti lorsque la personne
données,
la transaction est terminée.
[5] Même si nous montrons la base de données comme une seule entité monolithique, ce n'est pas le cas. Le logiciel de base de données est partitionné en
plusieurs processus et threads client, mais cela est géré en interne par le logiciel de base de données et ne fait pas partie de notre
exemple.
Cet exemple montre également un moyen d'obtenir un équilibrage de charge rapide et sale entre
processus de consommation multiples : le modèle du consommateur affamé.
Astuce
Astuce 40
40
Conception
Conception pour
pour la
la simultanéité
simultanéité
Avec le code linéaire, il est facile de faire des suppositions qui conduisent à des erreurs
la programmation. Mais la concurrence vous oblige à réfléchir un peu
plus attentivement, vous n'êtes plus seul à la fête. Parce que les choses peuvent
se produisent maintenant au "même moment", vous pouvez soudainement voir des
dépendances.
Pour commencer, toutes les variables globales ou statiques doivent être protégées contre
accès simultané. C'est peut-être le bon moment de vous demander pourquoi vous avez besoin d'un
variable globale en premier lieu. De plus, vous devez vous assurer que
vous présentez des informations d'état cohérentes, quel que soit l'ordre des appels.
Par exemple, quand est-il valide d'interroger l'état de votre objet ? Si votre objet
est dans un état invalide entre certains appels, vous pouvez compter sur un
coïncidence que personne ne puisse appeler votre objet à ce moment-là.
Supposons que vous ayez un sous-système de fenêtrage où les widgets sont les premiers
créé puis affiché à l'écran en deux étapes distinctes. Vous n'êtes pas
autorisé à définir l'état dans le widget jusqu'à ce qu'il soit affiché. Selon la façon dont le
code est configuré, vous pouvez compter sur le fait qu'aucun autre objet ne peut utiliser
le widget créé jusqu'à ce que vous l'ayez affiché à l'écran.
Mais cela peut ne pas être vrai dans un système concurrent. Les objets doivent toujours être dans
un état valide lorsqu'il est appelé, et ils peuvent être appelés aux moments les plus difficiles.
Vous devez vous assurer qu'un objet est dans un état valide chaque fois qu'il pourrait
être appelé. Souvent, ce problème apparaît avec des classes qui définissent des
constructeur et routines d'initialisation (où le constructeur ne quitte pas
l'objet dans un état initialisé). En utilisant des invariants de classe, discutés dans
Conception par contrat, vous aidera à éviter ce piège.
Interfaces
Interfaces plus
plus propres
propres
Penser à la concurrence et aux dépendances ordonnées dans le temps peut vous conduire à
c o
qui décompose une chaîne en jetons.
[6] Il utilise des données statiques pour maintenir la position actuelle dans le tampon. Les données statiques ne sont pas protégées contre les
accès, il n'est donc pas thread-safe. De plus, cela encombre le premier argument que vous transmettez, ce qui peut conduire à de mauvais
s u
eL c
entre les appels. Vous devez utiliser strtok sur un seul tampon à la fois.
Maintenant, en Java, la conception d'un analyseur de chaînes doit être différente. Ce doit être
t ehr
Astuce
Astuce 41
41
Déploiement
Déploiement
Une fois que vous avez conçu une architecture avec un élément de concurrence, il
devient plus facile de penser à gérer de nombreux services concurrents : le
modèle devient omniprésent.
Vous pouvez maintenant être flexible quant à la manière dont l'application est déployée : autonome,
client-serveur ou n-tiers. En concevant votre système comme des services indépendants,
vous pouvez également rendre la configuration dynamique. En planifiant pour
simultanéité et découplage des opérations dans le temps, vous avez toutes ces
options, y compris l'option autonome, où vous pouvez choisir de ne pas être
concurrent.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
C'est
C'est juste
juste une
une vue
vue
Et ignore le reste
La la la…
Simon
Simon et
et Garfunkel,
Garfunkel, "Le
"Le boxeur"
boxeur"
Dès le début, on nous apprend à ne pas écrire un programme en un seul gros morceau, mais
qu'il faut "diviser pour mieux régner" et séparer un programme en modules.
Chaque module a ses propres responsabilités ; en fait, une bonne définition d'un
module (ou classe) est qu'il a une seule responsabilité bien définie.
Mais une fois que vous séparez un programme en différents modules basés sur
responsabilité, vous avez un nouveau problème. A l'exécution, comment les objets parlent
l'un à l'autre ? Comment gérez-vous les dépendances logiques entre eux ?
Autrement dit, comment synchronisez-vous les changements d'état (ou les mises à jour des valeurs de données)
dans ces différents objets ? Cela doit être fait dans un environnement propre et flexible
manière - nous ne voulons pas qu'ils en sachent trop les uns sur les autres. Nous voulons
chaque module pour être comme l'homme dans la chanson et juste entendre ce qu'il veut
entendre.
Nous allons commencer par le concept d'événement. Un événement est tout simplement spécial
message qui dit "quelque chose d'intéressant vient de se passer" (intéressant, de
bien sûr, réside dans l'œil du spectateur). Nous pouvons utiliser des événements pour signaler des changements
dans un objet qui pourrait intéresser un autre objet.
Publier/S'abonner
Publier/S'abonner
Pourquoi est-il mauvais de pousser tous les événements à travers une seule routine ? Il viole
encapsulation d'objet - qu'une routine doit maintenant avoir intime
connaissance des interactions entre de nombreux objets. Il augmente également la
couplage—et nous essayons de réduire le couplage. Parce que les objets
eux-mêmes doivent également avoir connaissance de ces événements, vous êtes
va probablement violer le principe DRY, l'orthogonalité, et peut-être
même des sections de la Convention de Genève. Vous avez peut-être vu ce genre de
code - il est généralement dominé par un énorme
déclaration de cas ou multiway
si donc. Nous pouvons faire mieux.
Les objets doivent pouvoir s'enregistrer pour ne recevoir que les événements dont ils ont besoin, et
ne doivent jamais recevoir d'événements dont ils n'ont pas besoin. Nous ne voulons pas spammer nos
objets! Au lieu de cela, nous pouvons utiliser un protocole de publication/abonnement, illustré à l'aide de
le diagramme de séquence UML de la Figure 5.4 à la page suivante.
[7]
[7] Voir aussi le pattern Observer dans [ GHJV95 ] pour plus d'informations.
Figure
Figure 5.4.
5.4. Protocole
Protocole de
de publication/abonnement
publication/abonnement
Si nous sommes intéressés par certains événements générés par un Editeur, tout ce que nous avons
faire est de nous enregistrer. Le L'éditeur garde une trace de tous les intéressés
Objets abonnés ; lorsque l'Éditeur génère un événement d'intérêt, il
appellera tour à tour chaque Abonné et l'informera que l'événement a
s'est produit.
Modèle
Modèle Vue
Vue Contrôleur
Contrôleur
Bien que le service d'événements CORBA puisse être utilisé pour mettre en œuvre toutes les
les modèles d'événements abordés dans cette section, vous pouvez également les afficher comme un
animal différent. CORBA facilite la communication entre les objets
écrit dans différents langages de programmation fonctionnant sur
machines dispersées géographiquement avec des architectures différentes.
Assis au sommet de CORBA, le service événementiel vous offre une manière découplée
d'interagir avec des applications du monde entier, écrites par des personnes
vous n'avez jamais rencontré, en utilisant des langages de programmation que vous préférez ne pas
savoir a propos.
Évidemment, nous ne voulons pas avoir trois copies distinctes des données. Alors on
créer un modèle - les données elles-mêmes, avec des opérations courantes pour les manipuler.
Ensuite, nous pouvons créer des vues séparées qui affichent les données de différentes manières :
sous forme de feuille de calcul, de graphique ou de zone de totaux. Chacune de ces vues peut
avoir son propre contrôleur. La vue graphique peut avoir un contrôleur qui permet
vous permet d'effectuer un zoom avant ou arrière, ou de vous déplacer autour des données, par exemple. Rien de tout cela
affecte les données elles-mêmes, juste cette vue.
[8] La vue et le contrôleur sont étroitement couplés, et dans certaines implémentations de MVC, la vue et le contrôleur sont un seul
composant.
Astuce
Astuce 42
42
Arborescence
Arborescence Java
Java
Un bon exemple de conception MVC peut être trouvé dans le widget d'arborescence Java. Le
widget arbre (qui affiche un arbre cliquable et traversable) est en fait un ensemble de
plusieurs classes différentes organisées dans un modèle MVC.
Pour produire un widget arborescent entièrement fonctionnel, tout ce que vous avez à faire est de fournir un
source de données conforme à la Interface TreeModel. Votre code maintenant
devient le modèle de l'arbre.
Supposons que le vice-président vienne vers vous et veuille une candidature rapide
qui lui permet de naviguer dans l'organigramme de l'entreprise, qui se tient dans
une ancienne base de données sur le mainframe. Il suffit d'écrire un wrapper qui prend le
données mainframe, les présente comme
TreeModel,
un et voilà : vous disposez d'un
widget d'arborescence navigable.
Maintenant, vous pouvez devenir fantaisiste et commencer à utiliser les classes de visualisation ; vous pouvez changer
comment les nœuds sont rendus et utilisez des icônes, des polices ou des couleurs spéciales. Quand le
VP revient et dit que les nouvelles normes d'entreprise dictent l'utilisation d'un
Icône tête de mort et os croisés pour certains employés, vous pouvez apporter les modifications
pour
TreeCellRenderer sans toucher à aucun autre code.
Au-delà
Au-delà des
des interfaces
interfaces graphiques
graphiques
Bien que MVC soit généralement enseigné dans le contexte du développement d'interfaces graphiques, il est
vraiment une technique de programmation à usage général. La vue est un
interprétation du modèle (peut-être un sous-ensemble) - il n'est pas nécessaire
graphique. Le contrôleur est davantage un mécanisme de coordination et ne
doivent être liés à n'importe quel type de périphérique d'entrée.
De toute évidence, nous avons besoin d'informations sur le jeu en cours - les équipes qui jouent,
les conditions, le joueur au bâton, le score, etc. Ces faits forment notre
des modèles; ils seront mis à jour au fur et à mesure que de nouvelles informations arriveront (un lanceur est
changé, un joueur frappe, il commence à pleuvoir…).
Nous aurons alors un certain nombre d'objets de vue qui utilisent ces modèles. Une vue
peut rechercher des runs afin de pouvoir mettre à jour le score actuel. Un autre peut recevoir
notifications de nouveaux batteurs, et récupérer un bref résumé de leur
statistiques cumulées depuis le début de l'année. Un troisième spectateur peut regarder les données et vérifier
nouveaux records du monde. Nous pourrions même avoir un visualiseur de trivia, responsable de
venir avec ces faits étranges et inutiles qui ravissent le public.
Mais nous ne voulons pas inonder le pauvre présentateur avec toutes ces vues
directement. Au lieu de cela, chaque vue générera des notifications de
événements "intéressants", et laissez un objet de niveau supérieur planifier ce qui se passe
montré.[9]
[9] Le fait qu'un avion survole n'est probablement pas intéressant à moins que ce ne soit le 100e avion à survoler cette nuit-là.
Ces objets spectateurs sont soudainement devenus des modèles pour le niveau supérieur
objet, qui lui-même pourrait alors être un modèle pour différents visualiseurs de mise en forme.
Un visualiseur de mise en forme peut créer le script de téléprompteur pour le
annonceur, un autre pourrait générer des sous-titres vidéo directement sur le satellite
liaison montante, un autre peut mettre à jour les pages Web du réseau ou de l'équipe (voir
Figure 5.5 ).
Figure
Figure 5.5.
5.5. Reportage
Reportage de
de baseball,
baseball, les
les téléspectateurs
téléspectateurs s'abonnent
s'abonnent aux
aux modèles.
modèles.
Ce type de réseau de visionneuses de modèles est une conception courante (et précieuse)
technique. Chaque lien dissocie les données brutes des événements qui ont créé
it—chaque nouveau spectateur est une abstraction. Et parce que les relations sont un
réseau (pas seulement une chaîne linéaire), nous avons beaucoup de flexibilité. Chaque modèle
peut avoir plusieurs visualiseurs et un visualiseur peut fonctionner avec plusieurs modèles.
Dans les systèmes avancés tels que celui-ci, il peut être pratique d'avoir un débogage
vues—vues spécialisées qui vous montrent des détails détaillés du modèle.
L'ajout d'une installation pour tracer des événements individuels peut être un gain de temps important car
Bien.
Toujours
Toujours en
en couple
couple (après
(après toutes
toutes ces
ces années)
années)
Malgré la diminution du couplage que nous avons obtenue, les auditeurs et les événements
les générateurs (abonnés et éditeurs) ont encore une certaine connaissance de chacun
autre. En Java, par exemple, ils doivent se mettre d'accord sur une interface commune
définitions et conventions d'appel.
Dans la section suivante, nous examinerons les moyens de réduire encore plus le couplage en
en utilisant un formulaire de publication et d'abonnement où aucun des participants n'a besoin
se connaissent ou s'appellent directement.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Orthogonalité
• • Réversibilité
• • Le découplage et la loi de Déméter
• • Tableaux noirs
• • Tout est écrit
Des
Des exercices
exercices
29.
29. Supposons que vous disposiez d'un système de réservation de compagnie aérienne qui inclut le
c o
On aimerait avoir un peu plus de souplesse dans le traitement des listes d'attente
passagers, et nous devons faire quelque chose à propos de ce gros rapport—il
prend trop de temps à courir. Utilisez les idées de cette section pour reconcevoir ce
interface.
Tableaux
Tableaux noirs
noirs
Vous n'associez peut-être généralement pas l'élégance aux détectives de la police, imaginant
à la place une sorte de cliché de beignet et de café. Mais considérez comment
les détectives peuvent utiliser un tableau noir pour coordonner et résoudre un meurtre
enquête.
Supposons que l'inspecteur en chef commence par installer un grand tableau noir dans le
salle de conférence. Il écrit dessus une seule question :
Illustration
Illustration 5.6.
5.6. Quelqu'un
Quelqu'un aa trouvé
trouvé un
un lien
lien entre
entre le
le jeu
jeu d'Humpty
d'Humpty
les
les dettes
dettes et
et les
les journaux
journaux téléphoniques.
téléphoniques. Peut-être
Peut-être recevait-il
recevait-il un
un téléphone
téléphone menaçant
menaçant
appels.
appels.
Nous avons travaillé sur un certain nombre de projets qui impliquaient un flux de travail ou
processus de collecte de données distribuées. Avec chacun, concevoir une solution autour
un simple modèle de tableau noir nous a donné une métaphore solide avec laquelle travailler : tous les
les fonctionnalités énumérées ci-dessus utilisant des détectives sont tout aussi applicables aux objets et
module de codes.
Un système de tableau noir nous permet de découpler nos objets les uns des autres
complètement, offrant un forum où les consommateurs et les producteurs de connaissances
peut échanger des données de manière anonyme et asynchrone. Comme vous pouvez le deviner,
cela réduit également la quantité de code que nous devons écrire.
Implémentations
Implémentations du
du tableau
tableau noir
noir
Les systèmes de tableau noir informatisés ont été inventés à l'origine pour être utilisés dans
applications d'intelligence artificielle où les problèmes à résoudre étaient
vaste et complexe—reconnaissance de la parole, raisonnement basé sur les connaissances
systèmes, et ainsi de suite.
Avec ces systèmes, vous pouvez stocker des objets Java actifs, et pas seulement des données, sur
le tableau noir, et les récupérer par appariement partiel des champs (via
modèles et caractères génériques) ou par sous-types. Par exemple, supposons que vous ayez un
taperAuteur, qui est un sous-type de Personne. Vous pouvez rechercher un tableau noir
c o
valeur de "Shakespeare". Vous auriez Bill Shakespeare l'auteur, mais pas
Fred Shakespeare le jardinier.
Nom
Nom Fonction
Fonction
lire Rechercher et récupérer des données de l'espace.
écrire Mettre un élément dans l'espace.
take Semblable à read, mais supprime également l'élément de l'espace.
notifier Configurez une notification pour qu'elle se produise chaque fois qu'un objet correspondant au modèle est écrit.
T Spaces prend en charge un ensemble similaire d'opérations, mais avec des noms et des
sémantique légèrement différente. Les deux systèmes sont construits comme un produit de base de données ;
ils fournissent des opérations atomiques et des transactions distribuées pour garantir que les données
intégrité.
Puisque nous pouvons stocker des objets, nous pouvons utiliser un tableau noir pour concevoir des algorithmes
basé sur un flux d'objets, pas seulement de données. C'est comme si nos détectives pouvaient épingler
les gens au tableau noir - les témoins eux-mêmes, pas seulement leurs déclarations.
N'importe qui peut poser des questions à un témoin dans la poursuite de l'affaire, poster le
transcription, et déplacez ce témoin vers une autre zone du tableau noir, où
Un grand avantage de systèmes comme ceux-ci est que vous avez un seul,
interface cohérente avec le tableau noir. Lors de la construction d'un
application distribuée, vous pouvez passer beaucoup de temps à créer des
Appels d'API pour chaque transaction et interaction distribuée dans le système.
Avec l'explosion combinatoire des interfaces et des interactions, le projet
peut vite devenir un cauchemar.
Lorsque les détectives travaillent sur de grosses affaires, le tableau noir peut être-
deviennent encombrés et il peut devenir difficile de localiser les données sur le
conseil. La solution est de partitionner le tableau noir et de commencer à
organiser les données sur le tableau noir en quelque sorte.
Exemple
Exemple d'application
d'application
Supposons que nous écrivions un programme pour accepter et traiter une hypothèque ou un prêt
applications. Les lois qui régissent ce domaine sont odieusement complexes, avec
les gouvernements fédéral, étatiques et locaux ont tous leur mot à dire. Le prêteur doit
prouver qu'ils ont divulgué certaines choses et doivent demander certaines
informations - mais ne doit pas poser certaines autres questions, et ainsi de suite, et ainsi de suite
sur.
Au-delà des miasmes du droit applicable, nous avons également les problèmes suivants
à affronter.
• • Il n'y a aucune garantie sur l'ordre dans lequel les données arrivent. Pour
Par exemple, les requêtes pour une vérification de crédit ou une recherche de titre peuvent prendre un
beaucoup de temps, tandis que des éléments tels que le nom et l'adresse
peut être disponible immédiatement.
• • La collecte de données peut être effectuée par différentes personnes, distribuées
dans différents bureaux, dans différents fuseaux horaires.
Vous pouvez essayer de gérer toutes les combinaisons et circonstances possibles en utilisant un
système de flux de travail. De nombreux systèmes de ce type existent, mais ils peuvent être complexes et
programmeur intensif. Au fur et à mesure que les réglementations changent, le flux de travail doit être
réorganisé : les personnes peuvent être amenées à modifier leurs procédures et
le code devra peut-être être réécrit.
Astuce
Astuce 43
43
Nous pouvons utiliser le tableau noir pour coordonner des faits et des agents disparates, tandis que
tout en maintenant l'indépendance et même l'isolement des participants.
Vous pouvez obtenir les mêmes résultats avec plus de méthodes de force brute, de
bien sûr, mais vous aurez un système plus fragile. Quand ça casse, tout le roi
les chevaux et tous les hommes du roi pourraient ne plus faire fonctionner votre programme.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
• • Utilisez-vous des systèmes de tableau noir dans le monde réel—le message
tableau près du réfrigérateur, ou le grand tableau blanc au travail ? Quoi
les rend efficaces ? Les messages sont-ils déjà affichés avec un
format? Est-ce que ça importe?
Des
Des exercices
exercices
30.
30. Pour chacune des applications suivantes, un système de tableau noir serait-il
approprié ou non ? Pourquoi?
La sagesse conventionnelle dit qu'une fois qu'un projet est dans la phase de codage, le
le travail est majoritairement mécanique, transcrivant la conception en exécutable
déclarations. Nous pensons que cette attitude est la principale raison pour laquelle
de nombreux programmes sont laids, inefficaces, mal structurés, impossibles à maintenir,
et tout simplement faux.
Le codage n'est pas mécanique. Si c'était le cas, tous les outils CASE que les gens ont épinglés
leurs espoirs au début des années 1980 auraient longtemps remplacé les programmeurs
il y a. Il y a des décisions à prendre à chaque minute, des décisions qui exigent
une réflexion et un jugement minutieux si le programme qui en résulte doit profiter d'une longue,
une vie précise et productive.
Les programmeurs pragmatiques réfléchissent de manière critique à tout code, y compris le nôtre.
Nous voyons constamment des possibilités d'amélioration dans nos programmes et nos conceptions.
Dans Refactoring, nous examinons des techniques qui nous aident à réparer le code existant même
alors que nous sommes au milieu d'un projet.
Quelque chose qui devrait être à l'arrière de votre esprit chaque fois que vous êtes
produire du code est que vous devrez un jour le tester. Rendre le code facile à tester,
et vous augmenterez la probabilité qu'il soit réellement testé, une pensée
nous développons dans Code That's Easy to Test.
Enfin, dans Evil Wizards, nous vous suggérons de faire attention aux outils qui
écrire des tonnes de code en votre nom à moins que vous ne compreniez ce qu'ils sont
action.
La plupart d'entre nous peuvent conduire une voiture en grande partie sur pilote automatique - nous ne le faisons pas explicitement
ordonnons à notre pied d'appuyer sur une pédale ou à notre bras de tourner le volant.
pensez "ralentissez et tournez à droite". Cependant, de bons conducteurs prudents sont
en examinant constamment la situation, en vérifiant les problèmes potentiels et
se mettre en bonne position en cas d'imprévu. Le
il en va de même pour le codage - il peut s'agir en grande partie de routine, mais gardez votre esprit
à propos de vous pourrait bien empêcher une catastrophe.
Programmation
Programmation par
par coïncidence
coïncidence
Avez-vous déjà regardé de vieux films de guerre en noir et blanc ? Le soldat fatigué
avance prudemment hors des broussailles. Il y a une clairière devant : y a-t-il
des mines terrestres, ou est-il sécuritaire de traverser? Rien n'indique qu'il s'agit d'un
champ de mines - aucun signe, fil de fer barbelé ou cratères. Le soldat pique le sol
devant lui avec sa baïonnette et grimace, s'attendant à une explosion. Là
n'en est pas un. Alors il avance laborieusement à travers le champ pendant un certain temps,
poussant et poussant comme il va. Finalement, convaincu que le champ est sûr,
il se redresse et marche fièrement en avant, seulement pour être réduit en pièces.
Les premières sondes du soldat pour les mines n'ont rien révélé, mais c'était simplement
chanceux. Il a été conduit à une fausse conclusion, avec des résultats désastreux.
En tant que développeurs, nous travaillons également dans des champs de mines. Il y a des centaines de pièges juste
attendant de nous rattraper chaque jour. En nous souvenant de l'histoire du soldat, nous devrions être
méfiez-vous de tirer de fausses conclusions. Il faut éviter de programmer en
coïncidence - s'appuyant sur la chance et les succès accidentels - en faveur de
programmer délibérément.
Comment
Comment programmer
programmer par
par coïncidence
coïncidence
Supposons que Fred reçoive une tâche de programmation. Fred tape du code,
essaie, et ça a l'air de marcher. Fred tape un peu plus de code, l'essaie, et il
semble toujours fonctionner. Après plusieurs semaines de codage de cette façon, le programme
cesse soudainement de fonctionner, et après des heures à essayer de le réparer, il ne fonctionne toujours pas
savoir pourquoi. Fred pourrait bien passer beaucoup de temps à poursuivre cette
morceau de code autour sans jamais pouvoir le réparer. Peu importe ce qu'il
fait, ça ne semble jamais fonctionner correctement.
Fred ne sait pas pourquoi le code échoue parce qu'il ne savait pas pourquoi
travaillé en premier lieu. Cela a semblé fonctionner, compte tenu des "tests" limités que
Fred l'a fait, mais ce n'était qu'une coïncidence. Porté par une fausse confiance, Fred
chargé en avant dans l'oubli. Maintenant, la plupart des gens intelligents savent peut-être
quelqu'un comme Fred, mais nous savons mieux. Nous ne nous fions pas aux coïncidences—faites
nous?
Parfois, nous pourrions. Parfois, il peut être assez facile de confondre un heureux
coïncidence avec un plan déterminé. Regardons quelques exemples.
Accidents
Accidents de
de mise
mise en
en œuvre
œuvre
Les accidents de mise en œuvre sont des choses qui se produisent simplement parce que c'est
la façon dont le code est actuellement écrit. Vous finissez par compter sur des sans-papiers
erreur ou conditions aux limites.
Supposons que vous appeliez une routine avec de mauvaises données. La routine répond dans un
manière particulière, et vous codez en fonction de cette réponse. Mais l'auteur n'a pas
l'intention que la routine fonctionne de cette façon - cela n'a même jamais été envisagé.
Lorsque la routine est "réparée", votre code peut se casser. Au plus extrême
cas, la routine que vous avez appelée peut même ne pas être conçue pour faire ce que vous voulez,
mais ça a l'air de bien fonctionner. Appeler les choses dans le mauvais ordre, ou dans le
am u
Ici, on dirait que Fred essaie désespérément de sortir quelque chose sur le
filtrer. Mais ces routines n'ont jamais été conçues pour être appelées ainsi ;
bien qu'ils semblent fonctionner, ce n'est vraiment qu'une coïncidence.
Pour ajouter l'insulte à l'injure, lorsque le composant est enfin dessiné, Fred
n'essaiera pas de revenir en arrière et de retirer les faux appels. "Ça marche maintenant, mieux
laisser assez bien seul…"
Il est facile de se laisser berner par cette ligne de pensée. Pourquoi prendre le risque de
jouer avec quelque chose qui fonctionne? Eh bien, nous pouvons penser à plusieurs
les raisons:
Pour le code que vous écrivez que d'autres appelleront, les principes de base du bon
modularisation et de dissimulation de la mise en œuvre derrière de petites
des interfaces bien documentées peuvent toutes aider. Un contrat bien défini (voir
Conception par contrat
) peut aider à éliminer les malentendus.
Pour les routines que vous appelez, ne vous fiez qu'au comportement documenté. Si vous ne pouvez pas, pour
quelle que soit la raison, alors documentez bien votre hypothèse.
Accidents
Accidents de
de contexte
contexte
Vous pouvez également avoir des "accidents de contexte". Supposons que vous écriviez un
module utilitaire. Juste parce que vous codez actuellement pour une interface graphique
environnement, le module doit-il s'appuyer sur la présence d'une interface graphique ? Es-tu
s'appuyer sur des utilisateurs anglophones ? Utilisateurs lettrés ? Qu'est-ce que tu es d'autre
compter là-dessus n'est pas garanti?
Hypothèses
Hypothèses implicites
implicites
Les coïncidences peuvent induire en erreur à tous les niveaux, de la génération des exigences
jusqu'aux tests. Les tests sont particulièrement chargés de fausses causalités et
résultats fortuits. Il est facile de supposer que X cause Y, mais comme nous l'avons dit
dans Debugging : ne le supposez pas, prouvez-le.
À tous les niveaux, les gens opèrent avec de nombreuses hypothèses à l'esprit, mais celles-ci
les hypothèses sont rarement documentées et sont souvent en conflit entre
différents développeurs. Des hypothèses qui ne reposent pas sur des données bien établies
les faits sont le fléau de tous les projets.
Astuce
Astuce 44
44
Comment
Comment programmer
programmer délibérément
délibérément
Nous voulons passer moins de temps à produire du code, détecter et corriger les erreurs le plus tôt possible
dans le cycle de développement que possible, et créer moins d'erreurs pour commencer.
Cela aide si nous pouvons programmer délibérément :
• • Soyez toujours conscient de ce que vous faites. Fred a laissé les choses aller
lentement hors de contrôle, jusqu'à ce qu'il finisse par bouillir, comme la grenouille dans Stone
Soupe et grenouilles bouillies.
• • Ne codez pas les yeux bandés. Tenter de créer une application que vous
ne comprends pas bien ou d'utiliser une technologie qui ne m'est pas familière
avec, est une invitation à se laisser tromper par les coïncidences.
• • Procédez à partir d'un plan, que ce plan soit dans votre tête, sur le
dos d'une serviette à cocktail, ou sur une impression murale à partir d'un CASE
outil.
• • Ne comptez que sur des choses fiables. Ne comptez pas sur les accidents ou
hypothèses. Si vous ne pouvez pas faire la différence en particulier
circonstances, imaginez le pire.
• • Documentez vos hypothèses. Conception par contrat, peut aider
clarifier vos hypothèses dans votre propre esprit, ainsi que vous aider
les communiquer aux autres.
• • Ne vous contentez pas de tester votre code, mais testez également vos hypothèses.
Ne devinez pas; essayez-le en fait. Rédigez une assertion pour tester votre
hypothèses (voir Programmation Assertive ). Si votre affirmation est juste,
vous avez amélioré la documentation dans votre code. Si vous découvrez
votre hypothèse est fausse, alors comptez-vous chanceux.
• • Priorisez vos efforts. Passez du temps sur les aspects importants; plus
que probablement, ce sont les parties difficiles. Si vous n'avez pas les bases
ou infrastructure correcte, des cloches et des sifflets brillants seront
non pertinent.
• • Ne soyez pas esclave de l'histoire. Ne laissez pas le code existant dicter l'avenir
code. Tout code peut être remplacé s'il n'est plus approprié. Même
dans un programme, ne laissez pas ce que vous avez déjà fait vous limiter
ce que vous faites ensuite - soyez prêt à refactoriser (voir Refactoring ). Ce
décision peut avoir une incidence sur le calendrier du projet. L'hypothèse est que le
l'impact sera inférieur au coût de ne pas effectuer le changement.
[1]
[ ]
[1] Vous pouvez aussi aller trop loin ici. Nous avons connu un développeur qui réécrivait toutes les sources qu'on lui donnait parce qu'il avait
ses propres conventions de nommage.
Alors la prochaine fois que quelque chose semble fonctionner, mais que vous ne savez pas pourquoi, assurez-vous
ce n'est pas juste une coïncidence.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Des
Des exercices
exercices
31.
31. Pouvez-vous identifier des coïncidences dans le fragment de code C suivant ?
S u
32.
32. Ce morceau de code C peut fonctionner de temps en temps, sur certaines machines.
L e
à cn
33.
33. Ce code provient d'une suite de traçage Java à usage général. Le
La fonction écrit une chaîne dans un fichier journal. Il réussit son test unitaire, mais échoue
lorsqu'un des développeurs Web l'utilise. Sur quelle coïncidence repose-t-il
s u
Vitesse
Vitesse de
de l'algorithme
l'algorithme
Dans Estimation, nous avons parlé d'estimer des choses telles que le temps qu'il faut
marcher à travers la ville, ou combien de temps un projet prendra pour se terminer. Cependant,
il existe un autre type d'estimation que les programmeurs pragmatiques utilisent
presque quotidiennement : estimer les ressources utilisées par les algorithmes : temps,
processeur, mémoire, etc.
Ce type d'estimation est souvent crucial. Étant donné le choix entre deux façons de
faire quelque chose, que choisissez-vous ? Vous savez combien de temps dure votre programme
avec 1 000 enregistrements, mais comment passera-t-il à 1 000 000 ? Quelles parties du
le code a besoin d'être optimisé ?
Il s'avère qu'il est souvent possible de répondre à ces questions en utilisant des
sens, quelques analyses et une façon d'écrire des approximations appelées les "grandes
Notation O".
Qu'entendons-nous
Qu'entendons-nous par
par estimation
estimation d'algorithmes
d'algorithmes ??
La plupart des algorithmes non triviaux gèrent une sorte d'entrée de variable - trier n
chaînes, en inversant une matrice m × n ou en déchiffrant un message avec un n-bit
clé. Normalement, la taille de cette entrée affectera l'algorithme : plus le
entrée, plus le temps d'exécution est long ou plus la mémoire utilisée est importante.
Nous constatons que chaque fois que nous écrivons quelque chose contenant des boucles ou récursif
appels, nous vérifions inconsciemment les exigences d'exécution et de mémoire. Ce
est rarement un processus formel, mais plutôt une confirmation rapide que ce que nous sommes
faire est raisonnable dans les circonstances. Cependant, nous trouvons parfois
procédons nous-mêmes à une analyse plus détaillée. C'est alors que le O()
la notation est utile.
La
La notation
notation O()
O()
nous disons simplement que le temps pris dans le pire des cas variera comme le carré
de n. Doublez le nombre d'enregistrements, et le temps augmentera approximativement
quadruple. Pensez au O comme signifiant de l'ordre de. La notation O() met
une limite supérieure sur la valeur de la chose que nous mesurons (temps, mémoire,
et ainsi de suite). Si on dit qu'une fonction prend O(n alors nous savons que le
2) temps,
la limite supérieure du temps nécessaire ne croîtra pas plus vite que n nous
2. Parfois
proposer des fonctions O () assez complexes, mais parce que l'ordre le plus élevé
terme dominera la valeur à mesure que n augmente, la convention est de supprimer tous
termes d'ordre inférieur, et de ne pas s'embêter à montrer une multiplication constante
facteurs. Sur2/2+ 3n) est identique à O(n 2/2), ce qui équivaut à O(n 2).
être 1 000 fois plus rapide qu'un autre O(n2) algorithme, mais vous ne le saurez pas
de la notation.
La figure 6.1 montre plusieurs notations O() courantes que vous rencontrerez, ainsi que
avec un graphique comparant les temps d'exécution des algorithmes dans chaque catégorie.
De toute évidence, les choses commencent rapidement à devenir incontrôlables
2). une fois que nous avons dépassé O(n
Figure
Figure 6.1.
6.1. Exécutions
Exécutions de
de divers
divers algorithmes
algorithmes
Par exemple, supposons que vous ayez une routine qui prend 1 s pour traiter 100
enregistrements. Combien de temps faudra-t-il pour traiter 1 000 ? Si votre code est O(1), alors il
prendra encore 1 s. Si c'est O(lg(n)), alors vous attendrez probablement environ 3 s.
O(n) montrera une augmentation linéaire à 10 s, tandis qu'un O(n lg(n)) prendra quelques
33 s. Si vous avez la malchance d'avoir un O(n 2) routine, puis asseyez-vous pour
100 s pendant qu'il fait son travail. Et si vous utilisez un algorithme exponentiel
O(2 n ), vous voudrez peut-être vous préparer une tasse de café. Votre routine devrait se terminer dans
environ 10 263 ans. Faites-nous savoir comment l'univers se termine.
La notation O() ne s'applique pas uniquement au temps ; vous pouvez l'utiliser pour représenter n'importe quel
autres ressources utilisées par un algorithme. Par exemple, il est souvent utile d'être
capable de modéliser la consommation mémoire (voir Exercice 35).
Estimation
Estimation de
de bon
bon sens
sens
Vous pouvez estimer l'ordre de nombreux algorithmes de base en utilisant votre bon sens.
Vitesse
Vitesse d'algorithme
d'algorithme en
en pratique
pratique
Il est peu probable que vous passiez beaucoup de temps au cours de votre carrière à écrire
routines. Ceux des bibliothèques à votre disposition seront probablement plus performants
tout ce que vous pouvez écrire sans effort substantiel. Cependant, la base
les types d'algorithmes que nous avons décrits précédemment apparaissent maintes et maintes fois.
Chaque fois que vous vous retrouvez à écrire une boucle simple, vous savez que vous avez
un algorithme O(n). Si cette boucle contient une boucle interne, alors vous regardez
O(m × n). Vous devriez vous demander quelle peut être l'ampleur de ces valeurs. Si
les nombres sont bornés, alors vous saurez combien de temps le code prendra pour
courir. Si les chiffres dépendent de facteurs externes (tels que le nombre de
enregistrements dans une exécution par lots pendant la nuit, ou le nombre de noms dans une liste de
personnes), alors vous voudrez peut-être vous arrêter et considérer l'effet que de grandes
les valeurs peuvent avoir sur votre temps d'exécution ou votre consommation de mémoire.
Astuce
Astuce 45
45
Il existe certaines approches que vous pouvez adopter pour résoudre les problèmes potentiels. Si
tu as un algorithme qui est O(n 2), essayez de trouver un diviser pour mieux régner
Si vous n'êtes pas sûr de la durée de votre code ou de la quantité de mémoire qu'il faudra
utiliser, essayez de l'exécuter, en faisant varier le nombre d'enregistrements d'entrée ou tout ce qui est susceptible de
impact sur le temps d'exécution. Tracez ensuite les résultats. Vous devriez bientôt avoir une bonne idée
de la forme de la courbe. S'agit-il d'une courbe vers le haut, d'une ligne droite ou d'un aplatissement ?
désactivé à mesure que la taille d'entrée augmente ? Trois ou quatre points devraient vous donner une idée.
Considérez également ce que vous faites dans le code lui-même. Un simple O(n
2) boucle
pourrait bien mieux fonctionner qu'un complexe, O(n lg(n)) un pour des valeurs plus petites de
n, en particulier si l'algorithme O(n lg(n)) a une boucle interne coûteuse.
jeux d'entrée. Mais nourrir le code des millions d'enregistrements et du coup le temps
se dégrade lorsque le système commence à s'effondrer. Si vous testez une routine de tri avec
touches d'entrée aléatoires, vous pourriez être surpris la première fois qu'il rencontre
entrée ordonnée. Les programmeurs pragmatiques essaient de couvrir à la fois les aspects théoriques
et bases pratiques. Après toutes ces estimations, le seul moment qui compte est
la vitesse de votre code, s'exécutant dans l'environnement de production, avec de vrais
[2] Cela nous amène à notre prochain conseil.
données.
[2] En fait, en testant les algorithmes de tri utilisés comme exercice pour cette section sur un Pentium 64 Mo, les auteurs ont manqué de
mémoire réelle lors de l'exécution du tri par base avec plus de sept millions de nombres. Le tri a commencé à utiliser l'espace d'échange, et
Astuce
Astuce 46
46
S'il est difficile d'obtenir des minutages précis, utilisez des profileurs de code pour compter les
nombre de fois que les différentes étapes de votre algorithme sont exécutées et tracez
ces chiffres par rapport à la taille de l'entrée.
Le
Le meilleur
meilleur n'est
n'est pas
pas toujours
toujours le
le meilleur
meilleur
Vous devez également être pragmatique quant au choix des algorithmes appropriés—le
le plus rapide n'est pas toujours le meilleur pour le travail. Étant donné un petit ensemble d'entrées, un
le tri par insertion simple fonctionnera aussi bien qu'un tri rapide, et
vous prendra moins de temps pour écrire et déboguer. Vous devez également faire attention si le
l'algorithme que vous choisissez a un coût d'installation élevé. Pour les petits ensembles d'entrées, cette configuration
peut éclipser le temps d'exécution et rendre l'algorithme inapproprié.
Méfiez-vous également des optimisations prématurées. C'est toujours une bonne idée de faire
assurez-vous qu'un algorithme est vraiment un goulot d'étranglement avant d'investir votre temps précieux
essayer de l'améliorer.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Estimation
Défis
Défis
• • Chaque développeur devrait avoir une idée de la façon dont les algorithmes sont
conçu et analysé. Robert Sedgewick a écrit une série de
Des
Des exercices
exercices
34.
34. Nous avons codé un ensemble de routines de tri simples, qui peuvent être téléchargées
sur notre site Web (http://www.pragmaticprogrammer.com ). Exécutez-les
sur les différentes machines mises à votre disposition. Vos chiffres suivent-ils
courbes attendues ? Que pouvez-vous en déduire des vitesses relatives de
vos engins ? Quels sont les effets de diverses optimisations du compilateur
paramètres? Le tri par base est-il bien linéaire ?
35.
35. La routine ci-dessous imprime le contenu d'un arbre binaire. En supposant
l'arbre est équilibré, à peu près combien d'espace de pile la routine aura-t-elle
utiliser lors de l'impression d'un arbre de 1 000 000 d'éléments ? (Suppose que
el s
36.
36. Pouvez-vous voir un moyen de réduire les exigences de pile de la routine
dans l'exercice 35 (en plus de réduire la taille du tampon) ?
37.
37. nous avons affirmé qu'un hachage binaire est O(lg(n)). Pouvez-vous prouver cela?
Refactoring
Refactoring
HF
HF Lyte,
Lyte, "Reste
"Reste avec
avec moi"
moi"
À mesure qu'un programme évolue, il deviendra nécessaire de repenser les décisions antérieures
et retravailler des parties du code. Ce processus est parfaitement naturel. Code
doit évoluer; ce n'est pas quelque chose de statique.
Eh bien, le logiciel ne fonctionne pas tout à fait de cette façon. Plutôt que de construire,
le logiciel ressemble plus à du jardinage - il est plus organique que concret. Toi
planter beaucoup de choses dans un jardin selon un plan et des conditions initiaux.
Certains prospèrent, d'autres sont destinés à finir en compost. Vous pouvez déplacer
plantations les unes par rapport aux autres pour profiter des jeux de lumière
et l'ombre, le vent et la pluie. Les plantes envahies sont fendues ou taillées, et
les couleurs qui s'opposent peuvent être déplacées vers des endroits plus esthétiques.
Vous arrachez les mauvaises herbes et vous fertilisez les plantations qui ont besoin d'un peu plus
aider. Vous surveillez en permanence la santé du jardin et faites
ajustements (au sol, aux plantes, à l'aménagement) selon les besoins.
Lorsque vous rencontrez une pierre d'achoppement parce que le code ne correspond pas tout à fait
plus, ou vous remarquez deux choses qui devraient vraiment être fusionnées, ou
tout le reste vous semble "faux", n'hésitez pas à le changer
Il n'y a d'autre instant que le présent. Un certain nombre de choses peuvent entraîner le code à
qualifier pour le refactoring :
Refactorisation de votre code : déplacement des fonctionnalités et mise à jour plus tôt
décisions - est vraiment un exercice de gestion de la douleur. Avouons-le, changer
autour du code source peut être assez pénible : cela fonctionnait presque, et maintenant
c'est vraiment déchiré. De nombreux développeurs hésitent à commencer à déchirer le code
juste parce que ce n'est pas tout à fait correct.
Complications
Complications du
du monde
monde réel
réel
Donc, vous allez voir votre patron ou votre client et lui dites : « Ce code fonctionne, mais j'ai besoin
encore une semaine pour le refactoriser."
La pression du temps est souvent utilisée comme excuse pour ne pas refactoriser. Mais cette excuse
ne tient tout simplement pas le coup : échouez à refactoriser maintenant, et il y aura beaucoup plus de temps
investissement pour résoudre le problème plus tard - quand il y a plus
dépendances à prendre en compte. Y aura-t-il plus de temps disponible alors? Pas dedans
notre expérience.
Astuce
Astuce 47
47
Gardez une trace des choses qui doivent être refactorisées. Si vous ne pouvez pas refactoriser
quelque chose immédiatement, assurez-vous qu'il est placé sur le calendrier.
Assurez-vous que les utilisateurs du code concerné savent qu'il doit être
refactorisés et comment cela pourrait les affecter.
Comment
Comment refactoriser
refactoriser ??
Le refactoring a commencé dans la communauté Smalltalk et, avec d'autres
tendances (telles que les modèles de conception), a commencé à gagner un public plus large. Mais
en tant que sujet, c'est encore assez nouveau; il n'y a pas beaucoup de publications dessus. La première
+ 99 ], ainsi que [ URL 47 ]) est en cours de publication
livre majeur sur le refactoring ([ FBB
à peu près à la même époque que ce livre.
Au fond, le refactoring est une refonte. Tout ce que vous ou d'autres sur votre
conçu par l'équipe peut être repensé à la lumière de nouveaux faits, plus profond
compréhensions, exigences changeantes, etc. Mais si vous procédez à
déchirer de grandes quantités de code avec un abandon sauvage, vous pouvez vous retrouver dans un
pire position que lorsque vous avez commencé.
De toute évidence, le refactoring est une activité qui doit être entreprise lentement,
délibérément et soigneusement. Martin Fowler propose les conseils simples suivants
comment refactoriser sans faire plus de mal que de bien (voir l'encadré sur
[ FS97 ]):
Refactorisation automatique
Généralement, les navigateurs de classes vous permettent d'éditer du code, de créer de nouvelles méthodes
Au moment où nous écrivons ce livre, cette technologie n'est pas encore apparue en dehors de
le monde Smalltalk, mais cela est susceptible de changer à la même vitesse
que Java change—rapidement. En attendant, le pionnier
Le navigateur de refactorisation Small Talk est disponible en ligne].à l'adresse [ URL 20
Nous parlerons plus en détail des tests à ce niveau dans Code facile à tester , et
tests à plus grande échelle dans Ruthless Testing , mais le point de M. Fowler
maintenir de bons tests de régression est la clé d'un refactoring en toute confiance.
Il peut également être utile de s'assurer que les changements drastiques apportés à un module, tels que
comme altérant son interface ou sa fonctionnalité de manière incompatible
manière-casser la construction. C'est-à-dire que les anciens clients de ce code devraient tomber dans
compiler. Vous pouvez alors retrouver rapidement les anciens clients et faire le nécessaire
changements pour les mettre à jour.
Donc, la prochaine fois que vous voyez un morceau de code qui n'est pas tout à fait comme il se doit, corrigez les deux
elle et tout ce qui en dépend. Gérer la douleur : si ça fait mal maintenant, mais
va faire encore plus mal plus tard, autant en finir avec ça.
Rappelez-vous
les fenêtres. les leçons de l'entropie logicielle
, ne pas vivre avec cassé
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Des
Des exercices
exercices
38.
38. Le code suivant a évidemment été mis à jour plusieurs fois au cours de la
a sn
39.
39. La classe Java suivante doit prendre en charge quelques formes supplémentaires. Refactoriser
al c
}
40.
40. Ce code Java fait partie d'un framework qui sera utilisé tout au long
votre projet. Refactorisez-le pour qu'il soit plus général et plus facile à étendre dans le
a ve
Code
Code facile
facile àà tester
tester
Le logiciel IC est une métaphore que les gens aiment lancer quand
[3]composants.
discuter de la réutilisabilité et du développement basé sur des L'idée est que
les composants logiciels doivent être combinés comme des puces de circuits intégrés
sont combinés. Cela ne fonctionne que si les composants que vous utilisez sont connus
être fiable.
[3] Le terme "Software IC" (Integrated Circuit) semble avoir été inventé en 1986 par Cox et Novobilski dans leur
Les puces sont conçues pour être testées, pas seulement en usine, pas seulement lorsqu'elles
sont installés, mais aussi sur le terrain lorsqu'ils sont déployés. Plus complexe
les puces et les systèmes peuvent avoir une fonction d'auto-test intégrée (BIST) complète qui
exécute en interne des diagnostics de base ou un mécanisme d'accès aux tests
(TAM) qui fournit un harnais de test qui permet à l'environnement externe de
fournir des stimuli et recueillir les réponses de la puce.
Nous pouvons faire la même chose dans le logiciel. Comme nos collègues quincailliers, nous
besoin d'intégrer la testabilité dans le logiciel dès le début et de tester
soigneusement chaque pièce avant d'essayer de les assembler.
Tests
Tests unitaires
unitaires
Les tests au niveau de la puce pour le matériel sont à peu près équivalents aux tests unitaires dans
logiciel—tests effectués sur chaque module, isolément, pour vérifier son comportement.
Nous pouvons avoir une meilleure idée de la façon dont un module réagira dans le vaste monde
une fois que nous l'avons testé à fond sous contrôle (même artificiel)
conditions.
Un test unitaire logiciel est un code qui teste un module. Généralement, le test unitaire
établira une sorte d'environnement artificiel, puis invoquera des routines dans
le module testé. Il vérifie ensuite les résultats renvoyés, soit
par rapport à des valeurs connues ou par rapport aux résultats d'exécutions précédentes du même
test (test de régression).
Plus tard, lorsque nous assemblons nos "CI logiciels" dans un système complet, nous allons
avoir confiance que les pièces individuelles fonctionnent comme prévu, puis nous
peut utiliser les mêmes installations de test unitaire pour tester le système dans son ensemble. On parle
à propos de cette vérification à grande échelle du système dans Ruthless. Testing
Avant d'aller aussi loin, cependant, nous devons décider quoi tester à l'unité
niveau. En règle générale, les programmeurs jettent quelques bits de données aléatoires sur le code
et appelez-le testé. Nous pouvons faire beaucoup mieux, en utilisant les idées derrière le design by
contracter.
Test
Test contre
contre contrat
contrat
Nous aimons considérer les tests unitaires comme des tests contre contrat (voir Design by
Contracter ). Nous voulons écrire des cas de test qui garantissent qu'une unité donnée honore
son contrat. Cela nous dira deux choses : si le code respecte le contrat,
et si le contrat signifie ce que nous pensons qu'il signifie. Nous voulons tester
que le module offre les fonctionnalités qu'il promet, sur une large gamme de
cas de test et conditions aux limites.
Qu'est-ce que cela signifie en pratique ? Regardons la routine racine carrée que nous
er cn
a s
sEn u
C'est un test assez simple; dans le monde réel, tout module non trivial est
susceptibles de dépendre d'un certain nombre d'autres modules, alors comment allons-nous
tester la combinaison?
Ce style de test nécessite que vous testiez d'abord les sous-composants d'un module.
Une fois les sous-composants vérifiés, le module lui-même peut être
testé.
Si les tests de LinkedList et Sort ont réussi, mais que le test de A a échoué, nous pouvons être assez
assurez-vous que le problème est dans A, ou dans l'utilisation par A d'un de ces sous-composants.
Cette technique est un excellent moyen de réduire l'effort de débogage : nous pouvons rapidement
se concentrer sur la source probable du problème dans le module A, et non
perdre du temps à réexaminer ses sous-composantes.
Pourquoi se donne-t-on tout ce mal ? Avant tout, nous voulons éviter de créer un
"bombe à retardement" - quelque chose qui reste inaperçu et explose à un
moment gênant plus tard dans le projet. En mettant l'accent sur les tests contre
contrat, nous pouvons essayer d'éviter autant de ces catastrophes en aval que possible
possible.
Astuce
Astuce 48
48
Lorsque vous concevez un module, ou même une seule routine, vous devez concevoir les deux
son contrat et le code pour tester ce contrat. En concevant du code pour passer un
tester et remplir son contrat, vous pouvez très bien envisager des conditions aux limites et
d'autres problèmes qui ne se poseraient pas autrement. Il n'y a pas de meilleur moyen de
corriger les erreurs qu'en les évitant en premier lieu. En effet, en construisant le
tests avant d'implémenter le code, vous pouvez essayer l'interface avant
vous vous y engagez.
Rédaction
Rédaction de
de tests
tests unitaires
unitaires
Les tests unitaires d'un module ne doivent pas être poussés dans un coin éloigné de
l'arborescence des sources. Ils doivent être idéalement situés. Pour les petits projets,
vous pouvez intégrer le test unitaire d'un module dans le module lui-même. Pour les plus grands
projets, nous suggérons de déplacer chaque test dans un sous-répertoire. Dans les deux cas,
rappelez-vous que s'il n'est pas facile à trouver, il ne sera pas utilisé.
En rendant le code de test facilement accessible, vous fournissez aux développeurs
qui peut utiliser votre code avec deux ressources inestimables :
C'est pratique, mais pas toujours pratique, que chaque classe ou module contienne
son propre test unitaire. En Java, par exemple, chaque classe peut avoir principal.
sa propre Dans
tout sauf le fichier de classe principal de l'application,
la routineleprincipale peut être utilisée pour exécuter
tests unitaires ; il sera ignoré lors de l'exécution de l'application elle-même. Cela a le
avantage que le code que vous expédiez contient toujours les tests, qui peuvent être utilisés pour
diagnostiquer les problèmes sur le terrain.
En C++, vous pouvez obtenir le même effet (au moment de la compilation) en utilisant #ifdef pour
compiler le code de test unitaire de manière sélective. Par exemple, voici une unité très simple
test en C++, intégré dans notre module, qui vérifie notre fonction racine carrée
en utilisant une routine testValue similaire à celle Java définie précédemment :
# dif e
un
Ce test unitaire exécutera un ensemble minimal de tests ou, si des arguments lui sont donnés,
vous permettent de transmettre des données depuis le monde extérieur. Un script shell pourrait utiliser
cette capacité à exécuter un ensemble de tests beaucoup plus complet.
Que faites-vous si la réponse correcte pour un test unitaire est de quitter ou d'abandonner le
programme? Dans ce cas, vous devez pouvoir sélectionner le test à exécuter, peut-être
en spécifiant un argument sur la ligne de commande. Vous devrez également passer
paramètres si vous devez spécifier différentes conditions de démarrage pour votre
essais.
Mais fournir des tests unitaires ne suffit pas. Vous devez les exécuter, et les exécuter
souvent. Cela aide également si la classe réussit ses tests de temps en temps.
Utilisation
Utilisation des
des harnais
harnais de
de test
test
Parce que nous écrivons généralement beaucoup de code de test et faisons beaucoup de tests, nous allons
se faciliter la vie et développer un harnais de test standard pour le
projet. Le principal montré dans la section précédente est un harnais de test très simple,
mais généralement nous aurons besoin de plus de fonctionnalités que cela.
Un harnais de test peut gérer des opérations courantes telles que l'état de la journalisation,
analyser la sortie pour les résultats attendus, et sélectionner et exécuter les tests.
Les faisceaux peuvent être pilotés par une interface graphique, peuvent être écrits dans le même langage cible
comme le reste du projet, ou peut être mis en œuvre comme une combinaison de
makefiles et scripts Perl. Un simple harnais de test est montré dans la réponse à
Exercice 41 à la page 305.
Dans les langages et environnements orientés objet, vous pouvez créer une base
classe qui fournit ces opérations courantes. Les tests individuels peuvent sous-classer
à partir de là et ajoutez un code de test spécifique. Vous pouvez utiliser une dénomination standard
convention et réflexion en Java pour construire dynamiquement une liste de tests. Ce
technique est une belle façon d'honorer le principe DRY - vous n'avez pas à
maintenir une liste des tests disponibles. Mais avant de partir et de commencer à écrire
votre propre harnais, vous voudrez peut-être enquêter sur Kent Beck et Erich
xUnit de Gamma à [ URL 22 ]. Ils ont déjà fait le gros du travail.
Quelle que soit la technologie que vous décidez d'utiliser, les harnais de test doivent
inclure les fonctionnalités suivantes :
Les tests doivent être composables ; c'est-à-dire qu'un test peut être composé de sous-tests de
sous-composants à n'importe quelle profondeur. Nous pouvons utiliser cette fonctionnalité pour tester des pièces sélectionnées
du système ou de l'ensemble du système tout aussi facilement, avec les mêmes outils.
Tests ad hoc
Lors du débogage, nous pouvons finir par créer des tests particuliers
à la volée. Ceux-ci peuvent être aussi simples qu'une déclaration imprimée ou un morceau
de code entré de manière interactive dans un environnement de débogage ou IDE.
Par exemple, en utilisant JUnit (le membre Java de la famille xUnit), nous pourrions
éc eriv
p u
JUnit est conçu pour être composable : nous pourrions ajouter autant de tests que nous
voulait cette suite, et chacun de ces tests pourrait à son tour être une suite. Dans
De plus, vous avez le choix entre une interface graphique ou batch pour piloter le
essais.
Construire
Construire une
une fenêtre
fenêtre de
de test
test
Même les meilleurs ensembles de tests ont peu de chances de trouver tous les bogues ; il y a
quelque chose sur les conditions humides et chaudes d'un environnement de production
qui semble les faire sortir du bois.
Cela signifie que vous devrez souvent tester un logiciel une fois qu'il a été
déployé, avec des données du monde réel circulant dans ses veines. Contrairement à un circuit
carte ou puce, nous n'avons pas de broches de test dans le logiciel, mais nous pouvons fournir
différentes vues de l'état interne d'un module, sans utiliser le
débogueur (ce qui peut être gênant ou impossible dans une production
application).
Les fichiers journaux contenant des messages de trace sont l'un de ces mécanismes. Messages du journal
doit être dans un format régulier et cohérent ; vous voudrez peut-être les analyser
automatiquement pour déduire le temps de traitement ou les chemins logiques que le programme
a pris. Les diagnostics mal formatés ou incohérents sont tellement
"vomir" - ils sont difficiles à lire et peu pratiques à analyser.
Un autre mécanisme pour entrer dans le code en cours d'exécution est la "touche de raccourci"
séquence. Lorsque cette combinaison particulière de touches est enfoncée, un diagnostic
fenêtre de contrôle apparaît avec des messages d'état et ainsi de suite. Ce n'est pas
quelque chose que vous révéleriez normalement aux utilisateurs finaux, mais cela peut être très pratique
pour le service d'assistance.
Pour un code serveur plus volumineux et plus complexe, une technique astucieuse pour fournir une vue
dans son fonctionnement est d'inclure un serveur Web intégré. N'importe qui peut pointer un
navigateur Web au port HTTP de l'application (qui se trouve généralement sur un
numéro non standard, tel que 8080) et voir l'état interne, les entrées de journal,
et peut-être même une sorte de panneau de contrôle de débogage. Cela peut sonner
difficile à mettre en œuvre, mais ce n'est pas le cas. HTTP librement disponible et intégrable
Les serveurs Web sont disponibles dans une variété de langues modernes. Un bon endroit pour
commencer à chercher est]. [ URL 58
Une
Une culture
culture de
de test
test
Tous les logiciels que vous écrivez seront testés, sinon par vous et votre équipe, du moins par
les utilisateurs éventuels, alors autant prévoir de le tester à fond. UN
peu de prévoyance peut grandement contribuer à minimiser les coûts de maintenance
et les appels au service d'assistance.
Il n'y a rien de magique dans Perl lui-même à cet égard. Perl facilite les choses
pour rassembler et analyser les résultats des tests pour assurer la conformité, mais le gros
l'avantage est simplement qu'il s'agit d'une norme : les tests ont lieu à un endroit particulier, et
avoir une certaine sortie attendue. Les tests sont plus culturels que techniques ; nous
peut insuffler cette culture de test dans un projet quelle que soit la langue utilisée
utilisé.
Astuce
Astuce 49
49
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Des
Des exercices
exercices
41.
41. Concevez un gabarit de test pour l'interface du mélangeur décrit dans la réponse à
Exercice 17, page 289. Écrivez un script shell qui effectuera une
test de régression pour le mélangeur. Vous devez tester les fonctionnalités de base,
les conditions d'erreur et limites, ainsi que toutes les obligations contractuelles. Quoi
des restrictions sont placées sur le changement de vitesse ? Sont-ils
honoré?
Sorciers
Sorciers maléfiques
maléfiques
Il est indéniable que les applications deviennent de plus en plus difficiles à écrire.
Les interfaces utilisateur, en particulier, deviennent de plus en plus sophistiquées.
Il y a vingt ans, l'application moyenne aurait un télétype en verre
interface (si elle avait une interface du tout). Les terminaux asynchrones
fournissent généralement un affichage interactif de caractères, tandis que les dispositifs interrogeables
(comme l'omniprésent IBM 3270) vous permettrait de remplir un écran entier
avant de frapper . Désormais, les utilisateurs s'attendent à des interfaces utilisateur graphiques, avec
aide contextuelle, couper-coller, glisser-déposer, intégration OLE et
MDI ou SDI. Les utilisateurs recherchent une intégration de navigateur Web et un client léger
soutien.
Ainsi, les fabricants d'outils et les fournisseurs d'infrastructures ont trouvé une solution magique
balle, l'assistant. Les sorciers sont super. Avez-vous besoin d'une application MDI avec
Prise en charge du conteneur OLE ? Cliquez simplement sur un seul bouton, répondez à quelques
Mais utiliser un assistant conçu par un gourou ne rend pas automatiquement Joe
développeur tout aussi expert. Joe peut se sentir plutôt bien—il vient de produire un
une masse de code et un programme plutôt stylé. Il ajoute simplement dans le
fonctionnalité d'application spécifique et il est prêt à être expédié. Mais à moins que Joe
comprend réellement le code qui a été produit en son nom, il est
se tromper. Il programme par hasard. Les sorciers sont à sens unique
rue - ils coupent le code pour vous, puis passent à autre chose. Si le code qu'ils
le produit n'est pas tout à fait correct, ou si les circonstances changent et que vous devez vous adapter
le code, vous êtes seul.
Nous ne sommes pas contre les sorciers. Au contraire, nous consacrons une section entière
) pour écrire le vôtre. Mais si vous utilisez un assistant et que vous
( Générateurs de codes
ne comprenez pas tout le code qu'il produit, vous ne contrôlerez pas
votre propre application. Vous ne pourrez pas l'entretenir, et vous serez
en difficulté quand vient le temps de déboguer.
Astuce
Astuce 50
50
Certaines personnes pensent que c'est une position extrême. Ils disent que les développeurs
s'appuient régulièrement sur des choses qu'ils ne comprennent pas entièrement - le quantum
la mécanique des circuits intégrés, la structure d'interruption du processeur,
les algorithmes utilisés pour planifier les processus, le code dans les bibliothèques fournies,
et ainsi de suite. Nous sommes d'accord. Et nous ressentirions la même chose pour les sorciers s'ils l'étaient
simplement un ensemble d'appels de bibliothèque ou de services de système d'exploitation standard qui
les développeurs pourraient compter. Mais ils ne le sont pas. Les assistants génèrent du code qui
devient partie intégrante de la candidature de Joe. Le code de l'assistant n'est pas
pris en compte derrière une interface soignée - il est entrelacé ligne par ligne avec
fonctionnalité que Joe écrit. [4] Finalement, il cesse d'être le code de l'assistant
et commence à appartenir à Joe. Et personne ne devrait produire de code qu'il ne produit pas entièrement
comprendre.
[4] Cependant, il existe d'autres techniques qui aident à gérer la complexité. Nous en discutons deux, beans et AOP, dans Orthogoality .
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Orthogonalité
• • Générateurs de codes
Défis
Défis
• • Si vous disposez d'un assistant de création d'interface graphique, utilisez-le pour générer un
demande de squelette. Parcourez chaque ligne de code qu'il produit. Faire
tu as tout compris ? Auriez-vous pu le fabriquer vous-même ? Serait
vous l'avez produit vous-même, ou fait-il des choses dont vous n'avez pas besoin ?
Avez-vous parfois le sentiment que votre projet est voué à l'échec, avant même qu'il ne démarre ?
Parfois, cela peut l'être, à moins que vous n'établissiez d'abord quelques règles de base de base.
Sinon, autant suggérer qu'il soit fermé maintenant et enregistrer
le parrain de l'argent.
Lorsque vous pensez avoir résolu les problèmes, vous ne vous sentez peut-être toujours pas
à l'aise avec le saut et le démarrage. Est-ce une simple procrastination ou est-ce
c'est quelque chose de plus? Pas jusqu'à ce que vous soyez prêt offre des conseils sur le moment où cela peut être
prudent d'écouter cette voix d'avertissement à l'intérieur de votre tête.
Commencer trop tôt est un problème, mais attendre trop longtemps peut être encore pire. Dans
Le piège de la spécification, nous discuterons des avantages de la spécification en
exemple.
Enfin,
et nous examinerons
méthodologies certains
dans les cerclesdes pièges
et les des Peu
flèches. processus
importedeà développement
quel point c'est formels
bien pensé
c'est le cas, et quelles que soient les "meilleures pratiques" qu'elle inclut, aucune méthode ne peut
remplacer la pensée.
Une fois ces problèmes critiques réglés avant le début du projet, vous
peut être mieux placé pour éviter la "paralysie de l'analyse" et commencer réellement
votre projet réussi.
La
La fosse
fosse aux
aux exigences
exigences
La perfection est atteinte, non pas lorsqu'il n'y a plus rien à ajouter, mais lorsqu'il
il n'y a plus rien à enlever....
Antoine
Antoine de
de Saint-Exupéry,
Saint-Exupéry, Vent,
Vent, sable
sable et
et étoiles,
étoiles, 1939
1939
Cela ne fonctionne pas tout à fait de cette façon. Les exigences se situent rarement à la surface.
Normalement, ils sont enterrés profondément sous des couches d'hypothèses,
les idées fausses et la politique.
Astuce
Astuce 51
51
Creuser
Creuser pour
pour les
les besoins
besoins
Comment pouvez-vous reconnaître une véritable exigence alors que vous creusez à travers tous
la saleté environnante? La réponse est à la fois simple et complexe.
La réponse simple est qu'une exigence est une déclaration de quelque chose qui
doit être accompli. Les bonnes exigences peuvent inclure les éléments suivants :
Cependant, très peu d'exigences sont aussi claires, et c'est ce qui fait que
complexe d'analyse des besoins.
La première déclaration de la liste ci-dessus peut avoir été déclarée par les utilisateurs comme
"Seuls les superviseurs d'un employé et le service du personnel peuvent voir
les dossiers de cet employé. » Cette déclaration est-elle vraiment une exigence ? Peut-être
aujourd'hui, mais il inscrit la politique commerciale dans un énoncé absolu. Stratégies
changer régulièrement, donc nous ne voulons probablement pas les lier à notre
exigences. Notre recommandation est de documenter ces politiques
séparément de l'exigence, et créez un lien hypertexte entre les deux. Faire le
exigence la déclaration générale, et donner aux développeurs la politique
informations comme exemple du type de chose qu'ils devront prendre en charge dans le
mise en œuvre. Finalement, la politique peut se retrouver sous forme de métadonnées dans le
application.
Il s'agit d'une distinction relativement subtile, mais qui aura de profondes répercussions
conséquences pour les développeurs. Si l'exigence est indiquée comme "uniquement
le personnel peut voir un dossier d'employé", le développeur peut finir par coder
un test explicite à chaque fois que l'application accède à ces fichiers. Toutefois, si
la déclaration est "Seuls les utilisateurs autorisés peuvent accéder au dossier d'un employé",
le développeur concevra et implémentera probablement une sorte d'accès
Système de contrôle. Lorsque la politique change (et ce sera le cas), seules les métadonnées de
ce système devra être mis à jour. En fait, la collecte des exigences dans ce
chemin vous mène naturellement à un système bien conçu pour prendre en charge
métadonnées.
Il est important de découvrir la raison sous-jacente pour laquelle les utilisateurs font une action particulière
chose, plutôt que simplement la façon dont ils le font actuellement. À la fin de la journée,
votre développement doit résoudre leur problème commercial, pas seulement répondre à leur
exigences énoncées. Documenter les raisons qui sous-tendent les exigences
donnez à votre équipe des informations précieuses lors de la mise en œuvre quotidienne
les décisions.
Il existe une technique simple pour entrer dans les exigences de vos utilisateurs qui
n'est pas assez utilisé : devenez utilisateur. Êtes-vous en train d'écrire un système pour
bureau d'aide? Passez quelques jours à surveiller les téléphones avec un
personne de soutien expérimentée. Automatisez-vous un contrôle manuel des stocks
système? Travail dans l'entrepôt pendant une [1] En plus de vous donner un aperçu
semaine.
comment le système sera réellement utilisé, vous seriez étonné de voir comment la demande
"Puis-je m'asseoir pendant une semaine pendant que vous faites votre travail?" contribue à instaurer la confiance et
établit une base de communication avec vos utilisateurs. Rappelez-vous juste que non
se mettre en travers !
[1] Est-ce qu'une semaine vous semble longue ? Ce n'est vraiment pas le cas, en particulier lorsqu'il s'agit de processus dans lesquels la direction
et les travailleurs occupent des mondes différents. La direction vous donnera une vue d'ensemble de la façon dont les choses fonctionnent, mais lorsque vous descendez
sur le sol, vous trouverez une réalité très différente, une réalité qui prendra du temps à assimiler.
Astuce
Astuce 52
52
Le processus d'exploration des exigences est également le moment de commencer à établir un rapport
avec votre base d'utilisateurs, en apprenant leurs attentes et leurs espoirs pour le système
vous construisez. Voir de grandes attentes, pour plus.
Exigences
Exigences de
de documentation
documentation
Donc, vous vous asseyez avec les utilisateurs et vous vous interrogez sur les véritables exigences
d'eux. Vous rencontrez quelques scénarios probables qui décrivent ce que
l'application doit faire. Toujours le professionnel, vous voulez les écrire
et publier un document que chacun pourra utiliser comme base pour
discussions - les développeurs, les utilisateurs finaux et les sponsors du projet.
C'est un public assez large.
Pour comprendre pourquoi, il faut regarder comment travaillent les ingénieurs du son. Ils
équilibrer les sons intuitivement. Au fil des ans, ils développent un sens inné
boucle de rétroaction entre leurs doigts—faders coulissants, rotation
boutons, etc. Cependant, l'interface de la nouvelle table de mixage n'a pas
tirer parti de ces capacités. Au lieu de cela, il forçait ses utilisateurs à taper sur un
clavier ou cliquez sur une souris. Les fonctions qu'il offrait étaient
complets, mais ils ont été emballés dans des termes inconnus et exotiques
façons. Les fonctions dont les ingénieurs avaient besoin étaient parfois cachées
derrière des noms obscurs, ou ont été obtenus avec des
Par exemple, les ingénieurs du son auraient peut-être été mieux servis
par une sorte d'interface à écran tactile - toujours tactile, toujours montée comme
une table de mixage traditionnelle pourrait être, tout en permettant au logiciel d'aller
au-delà du domaine des boutons et interrupteurs fixes. Fournir un
transition confortable à travers des métaphores familières est une façon de
aider à obtenir l'adhésion.
Cet exemple illustre également notre conviction que les outils performants s'adaptent
aux mains qui les utilisent. Dans ce cas, ce sont les outils que vous construisez
pour d'autres qui doivent être adaptables.
Une façon d'examiner les cas d'utilisation consiste à souligner leur nature axée sur les objectifs.
Alistair Cockburn a un article qui décrit cette approche, ainsi que
modèles pouvant être utilisés (strictement ou non) comme point de départ],([ Coc97a
également en ligne sur [ URL 46 ]). La figure 7.1 sur la page suivante montre un
exemple abrégé de son modèle, tandis que la figure 7.2 montre son exemple d'utilisation
cas.
Illustration
Illustration 7.1.
7.1. Modèle
Modèle de
de cas
cas d'utilisation
d'utilisation de
de Cockburn
Cockburn
Illustration
Illustration 7.2.
7.2. Un
Un exemple
exemple de
de cas
cas d'utilisation
d'utilisation
En utilisant un modèle formel comme aide-mémoire, vous pouvez être sûr que vous
inclure toutes les informations dont vous avez besoin dans un cas d'utilisation : performances
caractéristiques, autres parties impliquées, priorité, fréquence et divers
erreurs et exceptions qui peuvent survenir ("exigences non fonctionnelles"). Ce
est également un endroit idéal pour enregistrer les commentaires des utilisateurs tels que "oh, sauf si nous obtenons un
condition xxx, alors nous devons faire yyy à la place." Le modèle sert également de
un agenda prêt à l'emploi pour les réunions avec vos utilisateurs.
Diagrammes
Diagrammes de
de cas
cas d'utilisation
d'utilisation
Le flux de travail peut être capturé avec des diagrammes d'activité UML, et
les diagrammes de classes au niveau conceptuel peuvent parfois être utiles pour modéliser
affaire à portée de main. Mais les vrais cas d'utilisation sont des descriptions textuelles, avec un
hiérarchie et liens croisés. Les cas d'utilisation peuvent contenir des hyperliens vers d'autres utilisations
cas, et ils peuvent être imbriqués les uns dans les autres.
Illustration
Illustration 7.3.
7.3. Cas
Cas d'utilisation
d'utilisation UML
UML -- si
si simple
simple qu'un
qu'un enfant
enfant pourrait
pourrait le
le faire
faire !!
Surspécification
Surspécification
Un grand danger dans la production d'un document d'exigences est d'être trop spécifique.
Les bons documents d'exigences restent abstraits. Où les exigences sont
concerné, la déclaration la plus simple qui reflète fidèlement l'entreprise
le besoin est le meilleur. Cela ne veut pas dire que vous pouvez être vague—vous devez capturer le
invariants sémantiques sous-jacents en tant qu'exigences, et documenter les
ou les pratiques de travail actuelles comme politique.
Les exigences ne sont pas l'architecture. Les exigences ne sont pas de conception, ni
ils l'interface utilisateur. Les exigences sont nécessaires.
Voir
Voir plus
plus loin
loin
Le problème de l'an 2000 est souvent imputé aux programmeurs à courte vue,
désespéré d'économiser quelques octets à l'époque où les mainframes avaient moins
mémoire qu'une télécommande de télévision moderne.
Mais ce n'était pas le fait des programmeurs, et ce n'était pas vraiment une utilisation de la mémoire
problème. Au contraire, c'était la faute des analystes et des concepteurs du système. L'an 2000
problème est survenu à partir de deux causes principales : une incapacité à voir au-delà du courant
pratique commerciale et une violation du principe DRY.
Les entreprises utilisaient le raccourci à deux chiffres bien avant l'arrivée des ordinateurs
sur la scène. C'était une pratique courante. Le premier traitement de données
applications n'ont fait qu'automatiser les processus métier existants, et simplement
répété l'erreur. Même si l'architecture nécessitait des années à deux chiffres pour
saisie de données, rapport et stockage, il aurait dû y avoir une abstraction de
unDATE qui "savait" que les deux chiffres étaient une forme abrégée de la date réelle.
Astuce
Astuce 53
53
Est-ce que « voir plus loin » vous oblige à prédire l'avenir ? Non. Cela signifie
générer des déclarations telles que
Les exigences préciseront seulement que les dates sont utilisées. Cela peut laisser entendre que
certains calculs peuvent être effectués sur les dates. Il peut vous dire que les dates seront stockées
sur diverses formes de stockage secondaire. Ce sont de véritables exigences pour
unModule ou classe DATE.
Juste
Juste une
une autre
autre menthe
menthe ultra-mince…
ultra-mince…
De nombreux échecs de projets sont imputés à une augmentation de la portée, également appelée
fonctionnalité gonflement, featurism rampant, ou fluage des exigences. C'est un aspect
du syndrome de la grenouille bouillie de Stone Soup et Boiled Frogs
. Ce qui peut
faisons-nous pour éviter que les exigences ne nous envahissent ?
Dans la littérature, vous trouverez des descriptions de nombreuses métriques, telles que les bugs
rapportés et corrigés, densité de défauts, cohésion, couplage, points de fonction, lignes
de code, etc. Ces métriques peuvent être suivies manuellement ou avec un logiciel.
un an de retard par rapport aux estimations initiales et les accusations commencent à voler, il peut être
utile d'avoir une image précise et complète de comment et quand,
la croissance des besoins s'est produite.
Il est facile de se laisser entraîner dans le maelström "juste une fonctionnalité de plus", mais en
exigences de suivi, vous pouvez obtenir une image plus claire que "juste un de plus
feature" est vraiment la quinzième nouvelle fonctionnalité ajoutée ce mois-ci.
Maintenir
Maintenir un
un glossaire
glossaire
Dès que vous commencez à discuter des exigences, les utilisateurs et les experts du domaine
utiliseront certains termes qui ont une signification particulière pour eux. Ils peuvent
faire la différence entre un « client » et un « client », par exemple. Ce serait
alors être inapproprié d'utiliser l'un ou l'autre mot avec désinvolture dans le système.
Astuce
Astuce 54
54
Il est très difficile de réussir un projet où les utilisateurs et les développeurs se réfèrent
à la même chose par des noms différents ou, pire encore, faire référence à différents
choses du même nom.
Faire
Faire passer
passer le
le mot
mot
Dans It's All Writing , nous discutons de la publication de documents de projet en interne
Sites Web pour un accès facile par tous les participants. Ce mode de distribution est
particulièrement utile pour les documents d'exigences.
En présentant les exigences sous forme de document hypertexte, nous pouvons mieux
répondre aux besoins d'un public diversifié - nous pouvons donner à chaque lecteur ce
Ils veulent. Les sponsors du projet peuvent naviguer à un niveau élevé d'abstraction pour
s'assurer que les objectifs commerciaux sont atteints. Les programmeurs peuvent utiliser des hyperliens
pour "explorer" à des niveaux de détail croissants (même en référençant
définitions ou spécifications techniques).
La distribution sur le Web évite également le classeur typique de deux pouces d'épaisseur
intitulé Analyse des besoins que personne ne lit jamais et qui devient
obsolète l'encre instantanée frappe le papier.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
Des
Des exercices
exercices
42.
42. Parmi les exigences suivantes, lesquelles sont probablement de véritables exigences ? Reformuler
ceux qui ne le sont pas pour les rendre plus utiles (si possible) .
Résoudre
Résoudre des
des énigmes
énigmes impossibles
impossibles
Gordius, le roi de Phrygie, a un jour noué un nœud que personne ne pouvait dénouer. Il
On disait que celui qui résoudrait l'énigme du nœud gordien régnerait sur tout
Asie. Ainsi arrive Alexandre le Grand, qui coupe le nœud en morceaux avec
son épée. Juste une interprétation un peu différente des exigences, c'est
tout… et il a fini par diriger la majeure partie de l'Asie.
Considérez les puzzles du monde réel - ces petits morceaux de bois sournois, le fer forgé,
ou du plastique qui semblent se présenter comme cadeaux de Noël ou dans les vide-greniers. Tous
il suffit de retirer l'anneau, ou de mettre les pièces en forme de T dans la boîte, ou
peu importe.
Alors vous tirez sur l'anneau, ou essayez de mettre les T dans la boîte, et découvrez rapidement
que les solutions évidentes ne fonctionnent tout simplement pas. Le puzzle ne peut être résolu que
chemin. Mais même si c'est évident, cela n'empêche pas les gens d'essayer le
la même chose - encore et encore - en pensant qu'il doit y avoir un moyen.
Bien sûr, il n'y en a pas. La solution est ailleurs. Le secret pour résoudre le
puzzle est d'identifier les contraintes réelles (non imaginées) et de trouver une solution
la bride. Certaines contraintes sont absolues ; d'autres sont simplement préconçus
notions. Les contraintes absolues doivent être honorées, même si elles sont désagréables ou
stupides qu'ils peuvent sembler être. D'autre part, certains apparents
les contraintes peuvent ne pas être du tout de vraies contraintes. Par exemple, il y a ce vieux
truc de bar où vous prenez une bouteille de champagne neuve et non ouverte et pariez
que vous pouvez en boire de la bière. L'astuce consiste à retourner la bouteille,
et versez une petite quantité de bière dans le creux au fond de la bouteille.
De nombreux problèmes logiciels peuvent être tout aussi sournois.
Degrés
Degrés de
de liberté
liberté
L'expression à la mode populaire "sortir des sentiers battus" nous encourage à
reconnaître les contraintes qui pourraient ne pas s'appliquer et les ignorer.
Mais cette phrase n'est pas tout à fait exacte. Si la "boîte" est la limite de
contraintes et conditions, alors l'astuce consiste à trouver la boîte, qui peut être
considérablement plus grand que vous ne le pensez.
La clé pour résoudre des énigmes est à la fois de reconnaître les contraintes qui vous sont imposées
et de reconnaître les degrés de liberté que vous avez, car dans ceux-ci vous trouverez
votre résolution. C'est pourquoi certains puzzles sont si efficaces ; vous pouvez renvoyer
solutions potentielles trop facilement.
Vous devez remettre en question toute idée préconçue et évaluer si oui ou non
ce sont de vraies contraintes dures et rapides.
Astuce
Astuce 55
55
Soit dit en passant, une solution au puzzle des quatre poteaux est présentée à la page 307.
IlIl doit
doit yy avoir
avoir un
un moyen
moyen plus
plus simple
simple !!
Parfois, vous vous retrouverez à travailler sur un problème qui semble beaucoup
plus difficile que vous ne le pensiez. Peut-être que tu as l'impression de tomber
le mauvais chemin - qu'il doit y avoir un chemin plus facile que celui-ci ! Peut-être toi
sont en retard sur le calendrier maintenant, ou même désespèrent d'obtenir un jour le
système fonctionne parce que ce problème particulier est "impossible".
C'est alors que vous reculez d'un pas et que vous vous posez ces questions :
Plusieurs fois, une révélation surprenante viendra à vous alors que vous essayez de répondre
une de ces questions. Plusieurs fois une réinterprétation des exigences
peut faire disparaître toute une série de problèmes, tout comme le nœud gordien.
Tout ce dont vous avez besoin, ce sont les contraintes réelles, les contraintes trompeuses et les
la sagesse de connaître la différence.
Défis
Défis
Pas
Pas tant
tant que
que vous
vous n'êtes
n'êtes pas
pas prêt
prêt
James
James Thurber,
Thurber, Le
Le verre
verre dans
dans le
le champ
champ
Les grands artistes partagent un trait : ils savent quand commencer et quand attendre.
Le plongeur se tient debout sur la planche haute, attendant le moment idéal pour sauter.
La chef d'orchestre se tient devant l'orchestre, les bras levés, jusqu'à ce qu'elle perçoive
que le moment est venu de commencer la pièce.
Vous êtes un grand interprète. Toi aussi tu dois écouter la voix qui chuchote
"attendez." Si vous vous asseyez pour commencer à taper et qu'il y a un doute persistant dans
votre esprit, tenez-en compte.
Astuce
Astuce 56
56
Il y avait autrefois un style d'entraînement de tennis appelé "tennis intérieur". Vous feriez
passer des heures à frapper des balles par-dessus le filet, sans chercher particulièrement à être précis,
mais plutôt verbaliser juste où la balle a frappé par rapport à une cible (souvent
une chaise). L'idée était que la rétroaction formerait votre subconscient et
réflexes, de sorte que vous vous êtes amélioré sans savoir consciemment comment ni pourquoi.
En tant que développeur, vous avez fait le même genre de choses pendant toute votre
carrière. Vous avez essayé des choses et vu lesquelles fonctionnaient et lesquelles
n'a pas. Vous avez accumulé de l'expérience et de la sagesse. Quand tu ressens un
un doute lancinant ou une certaine réticence face à une tâche, tenez compte
il. Vous ne pourrez peut-être pas mettre le doigt sur exactement ce qui ne va pas, mais donnez
il est temps et vos doutes se cristalliseront probablement en quelque chose de plus solide,
quelque chose que vous pouvez aborder. Le développement logiciel n'est toujours pas une science. Laisser
votre instinct contribue à votre performance.
Bon
Bon jugement
jugement ou
ou procrastination
procrastination ??
Tout le monde a peur de la feuille blanche. Commencer un nouveau projet (ou même un
nouveau module dans un projet existant) peut être une expérience déconcertante. Un grand nombre de
nous préférerions remettre à plus tard l'engagement initial de commencer. Donc
comment pouvez-vous savoir quand vous procrastinez simplement, plutôt que
attendre de manière responsable que toutes les pièces se mettent en place ?
Une technique qui a fonctionné pour nous dans ces circonstances est de commencer
prototypage. Choisissez un domaine qui, selon vous, sera difficile et commencez
produisant une sorte de preuve de concept. L'une des deux choses sera généralement
arriver. Peu de temps après le démarrage, vous pouvez avoir l'impression de perdre votre temps.
Cet ennui est probablement une bonne indication que votre réticence initiale était
juste un désir de reporter l'engagement de commencer. Abandonner le prototype,
et pirater le développement réel.
D'un autre côté, au fur et à mesure que le prototype progresse, vous pouvez avoir l'un de ces
des moments de révélation où vous réalisez soudainement que certaines prémisses de base
avait tort. Non seulement cela, mais vous verrez clairement comment vous pouvez y remédier.
Vous vous sentirez à l'aise d'abandonner le prototype et de vous lancer dans la
projet proprement dit. Vos instincts étaient bons, et vous venez de vous sauver et
votre équipe une quantité considérable d'efforts inutiles.
Un peu cyniquement, commencer à travailler sur un prototype pourrait aussi être plus
politiquement acceptable que d'annoncer simplement que "je ne me sens pas bien
démarrage" et allumage s
Défis
Défis
Le
Le piège
piège des
des spécifications
spécifications
Mémorandum
Mémorandum de
de British
British Airways,
Airways, cité
cité dans
dans Pilot
Pilot Magazine,
Magazine, décembre
décembre 1996
1996
La spécification du programme est le processus qui consiste à prendre une exigence et à réduire
jusqu'au point où les compétences d'un programmeur peuvent prendre le dessus. C'est un acte de
communication, expliquant et clarifiant le monde de manière à
lever les principales ambiguïtés. En plus de parler au développeur qui sera
effectuant la mise en œuvre initiale, la spécification est un record pour
les futures générations de programmeurs qui maintiendront et amélioreront
le code. La spécification est également un accord avec l'utilisateur—un
codification de leurs besoins et un contrat implicite que le système final
être conforme à cette exigence.
Le problème est que de nombreux designers ont du mal à s'arrêter. Ils sentent que
à moins que chaque petit détail ne soit épinglé dans des détails atroces, ils ne l'ont pas fait
gagné leur dollar quotidien.
C'est une erreur pour plusieurs raisons. Premièrement, il est naïf de supposer qu'un
spécification capturera jamais chaque détail et nuance d'un système ou de ses
exigence. Dans des domaines de problèmes restreints, il existe des méthodes formelles qui
peuvent décrire un système, mais ils nécessitent toujours que le concepteur explique le
signification de la notation pour les utilisateurs finaux - il y a toujours un humain
[2] Il existe des techniques formelles qui tentent d'exprimer les opérations de manière algébrique, mais ces techniques sont rarement
utilisé dans la pratique. Ils exigent toujours que les analystes expliquent le sens aux utilisateurs finaux.
Voici un défi pour vous. Rédigez une courte description qui indique à quelqu'un comment
faire des nœuds à leurs lacets. Allez-y, essayez-le!
Si vous êtes comme nous, vous avez probablement abandonné quelque part autour de "maintenant
rouler le pouce et l'index de manière à ce que l'extrémité libre passe sous et à l'intérieur
le lacet gauche..." C'est une chose incroyablement difficile à faire. Et pourtant la plupart d'entre nous
peut attacher nos chaussures sans pensée consciente.
Astuce
Astuce 57
57
Enfin, il y a l'effet camisole de force. Une conception qui ne laisse pas le codeur
place à l'interprétation prive l'effort de programmation de toute compétence et de tout art.
Certains diront que c'est pour le mieux, mais ils se trompent. Souvent, ce n'est que
lors du codage que certaines options deviennent apparentes. Pendant le codage, vous pouvez
pensez "Regardez ça. En raison de la façon particulière dont j'ai codé cette routine, je
pourrait ajouter cette fonctionnalité supplémentaire sans presque aucun effort" ou "Le
la spécification dit de le faire, mais je pourrais obtenir un résultat presque identique
en le faisant d'une manière différente, et je pourrais le faire en deux fois moins de temps." De toute évidence, vous
ne devrait pas simplement pirater et apporter les modifications, mais vous n'auriez même pas
repéré l'opportunité si vous étiez contraint par un trop prescriptif
conception.
En tant que programmeur pragmatique, vous devriez avoir tendance à afficher les exigences
la collecte, la conception et la mise en œuvre comme différentes facettes de la même
Juste pour être clair, nous ne sommes pas contre la génération de spécifications. En effet, nous
reconnaître qu'il y a des moments où des spécifications incroyablement détaillées sont
exigé - pour des raisons contractuelles, en raison de l'environnement dans lequel vous
travail, ou en raison de la nature du produit que vous développez. [3] Sois juste
conscient que vous atteignez un point de rendements décroissants, voire négatifs,
les spécifications deviennent de plus en plus détaillées. Faites également attention à
spécifications de construction superposées aux spécifications, sans aucune
soutenir la mise en œuvre ou le prototypage ; c'est trop facile à préciser
quelque chose qui ne peut pas être construit.
[3] Les spécifications détaillées sont clairement appropriées pour les systèmes vitaux. Nous estimons qu'ils devraient également être produits pour
interfaces et bibliothèques utilisées par d'autres. Lorsque toute votre sortie est considérée comme un ensemble d'appels de routine, vous feriez mieux de vous assurer
Plus longtemps vous permettez aux spécifications d'être des couvertures de sécurité, protégeant
développeurs du monde effrayant de l'écriture de code, plus il sera difficile de
passer au piratage de code. Ne tombez pas dans cette spirale de spécifications : à certains
point, vous devez commencer à coder ! Si vous trouvez votre équipe complètement enveloppée dans
spécifications chaleureuses et confortables, sortez-les. Regardez le prototypage, ou
envisager le développement d'une balle traçante.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Balles traçantes
Défis
Défis
Parfois, une image vaut plus que n'importe quel nombre de mots.
Parfois ça ne vaut rien. Si vous vous surprenez à trop spécifier, est-ce que
des images ou des notations spéciales aident? À quel point doivent-ils être détaillés ?
Quand un outil de dessin est-il meilleur qu'un tableau blanc ?
Cercles
Cercles et
et flèches
flèches
Arlo
Arlo Guthrie,
Guthrie, "Le
"Le restaurant
restaurant d'Alice"
d'Alice"
Pourtant, certains développeurs, à la dérive dans une mer de projets en perdition, continuent de s'accrocher au
dernière mode au moment où les naufragés s'accrochent au bois flotté qui passe. Comme chacun
une nouvelle pièce flotte, ils nagent péniblement, espérant que ce sera mieux. Au
fin de la journée, cependant, peu importe la qualité de l'épave, le
les développeurs sont toujours à la dérive sans but.
Ne vous méprenez pas. Nous aimons (certaines) techniques et méthodes formelles. Mais nous
croire qu'adopter aveuglément n'importe quelle technique sans la mettre dans le
contexte de vos pratiques et capacités de développement est une recette pour
déception.
Astuce
Astuce 58
58
• • La plupart des méthodes formelles capturent les exigences en utilisant une combinaison
de schémas et quelques mots d'appui. Ces images représentent
la compréhension des exigences par les concepteurs. Cependant dans de nombreux
cas, ces diagrammes n'ont aucun sens pour les utilisateurs finaux, de sorte que le
les concepteurs doivent les interpréter. Il n'y a donc pas vraiment de formalité
vérification des exigences par l'utilisateur effectif du
système - tout est basé sur les explications des concepteurs, tout comme
dans les exigences écrites démodées. Nous voyons un certain avantage dans
capturer les besoins de cette façon, mais nous préférons, dans la mesure du possible,
montrez à l'utilisateur un prototype et laissez-le jouer avec.
• • Les méthodes formelles semblent encourager la spécialisation. Un groupe de
une personne travaille sur un modèle de données, une autre regarde l'architecture,
tandis que les collecteurs d'exigences collectent les cas d'utilisation (ou leur équivalent).
Nous avons vu cela conduire à une mauvaise communication et à des efforts inutiles. Là
est aussi une tendance à retomber dans la mentalité nous contre eux de
concepteurs contre codeurs. Nous préférons comprendre l'ensemble de la
système sur lequel nous travaillons. Il n'est peut-être pas possible d'avoir une analyse approfondie
comprendre tous les aspects d'un système, mais vous devez savoir comment le
les composants interagissent, où les données vivent, et ce que le
les exigences sont.
• • Nous aimons écrire des systèmes adaptables et dynamiques, en utilisant des métadonnées pour
nous permettent de changer le caractère des applications lors de l'exécution. La plupart
les méthodes formelles actuelles combinent un objet statique ou un modèle de données avec
une sorte de mécanisme de cartographie des événements ou des activités. Nous n'avons pas encore
tomber sur celui qui nous permet d'illustrer le genre de dynamisme que nous
sentir que les systèmes devraient présenter. En fait, la plupart des méthodes formelles conduiront
vous égarer, vous incitant à établir des relations statiques entre
objets qui devraient vraiment être tricotés ensemble dynamiquement.
Les
Les méthodes
méthodes sont-elles
sont-elles payantes
payantes ??
Dans un article du CACM de 1999 [ Gla99b ], Robert Glass passe en revue les recherches sur
les gains de productivité et de qualité obtenus grâce à sept
technologies de développement logiciel (4GLs, techniques structurées, CASE
outils, méthodes formelles, méthodologie de salle blanche, modèles de processus et objet
orientation). Il rapporte que le battage médiatique initial entourant tous ces
les méthodes étaient exagérées. Bien qu'il y ait une indication que certaines méthodes
avoir des avantages, ces avantages ne commencent à se manifester qu'après une
baisse significative de la productivité et de la qualité lors de l'adoption de la technique
et ses utilisateurs se forment. Ne sous-estimez jamais le coût de l'adoption
de nouveaux outils et méthodes. Soyez prêt à traiter les premiers projets en utilisant ces
techniques comme une expérience d'apprentissage.
Doit-on
Doit-on utiliser
utiliser des
des méthodes
méthodes formelles
formelles ??
Absolument. Mais souvenez-vous toujours que les méthodes de développement formelles sont
juste un outil de plus dans la boîte à outils. Si, après une analyse minutieuse, vous sentez que vous avez besoin
utiliser une méthode formelle, puis l'adopter, mais rappelez-vous qui est responsable.
Ne devenez jamais esclave d'une méthodologie : les cercles et les flèches rendent pauvres
maîtrise. Les programmeurs pragmatiques examinent les méthodologies de manière critique, puis
extraire le meilleur de chacun et les fondre dans un ensemble de pratiques de travail
qui s'améliore chaque mois. C'est crucial. Vous devez travailler constamment pour
affiner et améliorer vos processus. N'acceptez jamais les limites rigides d'un
méthodologie comme les limites de votre monde.
Ne cédez pas à la fausse autorité d'une méthode. Les gens peuvent entrer dans
réunions avec un acre de diagrammes de classes et 150 cas d'utilisation, mais tout ça
le papier n'est encore que leur interprétation faillible des exigences et de la conception.
Essayez de ne pas penser au coût d'un outil lorsque vous regardez sa sortie.
Astuce
Astuce 59
59
Les méthodes formelles ont certainement leur place dans le développement. Cependant, si vous
tomber sur un projet dont la philosophie est "le diagramme de classes est le
application, le reste est du codage mécanique", vous savez que vous avez affaire à un
équipe de projet gorgée d'eau et une longue maison de pagaie.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
Au fur et à mesure que votre projet démarre, nous devons nous éloigner des questions de
philosophie et codage individuels pour parler de problèmes plus vastes et de la taille d'un projet.
Nous n'entrerons pas dans les détails de la gestion de projet, mais nous parlerons
sur une poignée de domaines critiques qui peuvent faire ou défaire n'importe quel projet.
Dès que vous avez plus d'une personne travaillant sur un projet, vous devez
établir des règles de base et déléguer des parties du projet en conséquence.
Dans Pragmatic Teams, nous montrerons comment faire cela tout en respectant les
philosophie pragmatique.
Le facteur le plus important pour faire fonctionner les activités au niveau du projet
de manière cohérente et fiable consiste à automatiser vos procédures. Nous allons vous expliquer pourquoi,
et montrer quelques exemples concrets dans Ubiquitous Automation.
Plus tôt, nous avons parlé de tester pendant que vous codez. Dans Ruthless Testing, nous allons à
la prochaine étape de la philosophie et des outils de test à l'échelle du projet, surtout si vous
n'ayez pas un grand personnel d'assurance qualité à votre entière disposition.
La seule chose que les développeurs n'aiment pas plus que les tests, c'est la documentation.
Que vous ayez des rédacteurs techniques qui vous aident ou que vous le fassiez vous-même,
nous vous montrerons comment rendre la corvée moins pénible et plus productive dans
Tout est écrit.
Le dernier conseil du livre est une conséquence directe de tout le reste. Dans la fierté et
Préjugé, nous vous encourageons à signer votre travail, et à être fier de ce que
tu fais.
Des
Des équipes
équipes pragmatiques
pragmatiques
The
The Washington
Washington Post
Post Magazine,
Magazine, 99 juin
juin 1985
1985
Jusqu'à présent, dans ce livre, nous avons examiné des techniques pragmatiques qui aident un
individu être un meilleur programmeur. Ces méthodes peuvent-elles fonctionner pour les équipes
Bien?
Dans cette section, nous verrons brièvement comment les techniques pragmatiques peuvent être appliquées
aux équipes dans leur ensemble. Ces notes ne sont qu'un début. Une fois que vous avez un groupe de
développeurs pragmatiques travaillant dans un environnement favorable, ils vont rapidement
développer et affiner leur propre dynamique d'équipe qui fonctionne pour eux.
Pas
Pas de
de fenêtres
fenêtres cassées
cassées
La qualité est une question d'équipe. Le développeur le plus diligent placé dans une équipe qui
s'en fiche aura du mal à maintenir l'enthousiasme nécessaire pour
régler les problèmes agaçants. Le problème est encore aggravé si l'équipe
décourage activement le développeur de passer du temps sur ces correctifs.
Les équipes dans leur ensemble ne devraient pas tolérer les fenêtres brisées, ces petites
imperfections que personne ne corrige. L'équipe doit assumer la responsabilité de
qualité du produit, en soutenant les développeurs qui comprennent le non
la philosophie des fenêtres brisées que nous décrivons dans Software Entropy , et
encourageant ceux qui ne l'ont pas encore découvert.
Grenouilles
Grenouilles bouillies
bouillies
Rappelez-vous la pauvre grenouille dans la casserole d'eau, de retour dans Stone Soup and Boiled
Grenouilles? Il ne remarque pas le changement progressif de son environnement et finit par
cuit. La même chose peut arriver aux personnes qui ne sont pas vigilantes. Ça peut être
difficile de garder un oeil sur son environnement global dans le feu du projet
développement.
C'est encore plus facile pour les équipes dans leur ensemble de se faire bouillir. Les gens supposent que
quelqu'un d'autre s'occupe d'un problème, ou que le chef d'équipe doit avoir l'accord
une modification demandée par votre utilisateur. Même les équipes les mieux intentionnées peuvent
être inconscients des changements importants dans leurs projets.
Combattez ça. Assurez-vous que tout le monde surveille activement l'environnement pour
changements. Peut-être nommer un testeur d'eau en chef. Faites vérifier par cette personne
constamment pour une portée accrue, des échelles de temps réduites, des fonctionnalités supplémentaires,
de nouveaux environnements—tout ce qui ne figurait pas dans l'accord d'origine. Donjon
métriques sur les nouvelles exigences (voir page 209). L'équipe n'a pas à rejeter
changements incontrôlables - vous devez simplement être conscient qu'ils se produisent.
Sinon, ce sera toi dans l'eau chaude.
Communiquer
Communiquer
Il est évident que les développeurs d'une équipe doivent se parler. Nous avons donné
quelques suggestions pour faciliter cela dans Communicate! . Cependant, il est facile de
oublier que l'équipe elle-même est présente au sein de l'organisation. L'équipe
en tant qu'entité doit communiquer clairement avec le reste du monde.
Pour les étrangers, les pires équipes de projet sont celles qui semblent maussades et
réticent. Ils tiennent des réunions sans structure, où personne ne veut parler.
Leurs documents sont en désordre : il n'y en a pas deux qui se ressemblent et chacun utilise des
terminologie.
Les grandes équipes de projet ont une personnalité distincte. Les gens attendent avec impatience
rencontres avec eux, parce qu'ils savent qu'ils verront une rencontre bien préparée
des performances qui font que tout le monde se sent bien. La documentation qu'ils
les produits sont nets, précis et cohérents. L'équipe parle d'une seule voix. [1]
[1] L'équipe parle d'une seule voix à l'extérieur. En interne, nous encourageons fortement un débat animé et vigoureux. Bons développeurs
Il existe une astuce marketing simple qui aide les équipes à communiquer comme une seule :
générer une marque. Lorsque vous démarrez un projet, donnez-lui un nom,
idéalement quelque chose de décalé. (Par le passé, nous nommions les projets d'après
des choses telles que des perroquets tueurs qui se nourrissent de moutons, des illusions d'optique et
villes mythiques.) Passez 30 minutes à créer un logo loufoque et utilisez-le
sur vos mémos et rapports. Utilisez généreusement le nom de votre équipe lorsque vous parlez
avec des gens. Cela semble idiot, mais cela donne à votre équipe une identité sur laquelle s'appuyer,
et le monde quelque chose de mémorable à associer à votre travail.
Ne
Ne vous
vous répétez
répétez pas
pas
Dans Les maux de la duplication, nous avons parlé des difficultés d'éliminer
travail en double entre les membres d'une équipe. Ce dédoublement conduit à
Lorsque le projet est trop important pour un seul bibliothécaire (ou lorsque personne ne veut jouer
le rôle), nommer des personnes comme points focaux pour divers aspects fonctionnels du
travail. Si les gens veulent parler de la gestion des rendez-vous, ils doivent savoir parler
avec Marie. S'il y a un problème de schéma de base de données, consultez Fred.
Orthogonalité
Orthogonalité
[2] Dans The Rational Unified Process : An Introduction, l'auteur identifie 27 rôles distincts au sein d'une équipe de projet !
[ Kru98 ]
C'est une erreur de penser que les activités d'un projet - analyse, conception,
le codage et les tests peuvent se produire isolément. Ils ne peuvent pas. Ceux-ci sont
différentes vues d'un même problème, et les séparer artificiellement peut
causer un tas de problèmes. Programmeurs à deux ou trois niveaux
retirés des utilisateurs réels de leur code sont peu susceptibles d'être conscients de la
contexte dans lequel leur travail est utilisé. Ils ne pourront pas informer
les décisions.
Astuce
Astuce 60
60
Nous privilégions le fractionnement fonctionnel des équipes. Divisez votre personnel en petites équipes,
chacun étant responsable d'un aspect fonctionnel particulier du système final. Laisser
les équipes s'organisent en interne en s'appuyant sur les forces de chacun
comme ils peuvent. Chaque équipe a des responsabilités envers les autres dans le projet, comme
définis par leurs engagements convenus. L'ensemble exact des engagements
change à chaque projet, tout comme la répartition des personnes en équipes.
La fonctionnalité ici ne signifie pas nécessairement des cas d'utilisation d'utilisateurs finaux. Le
la couche d'accès à la base de données compte, tout comme le sous-système d'aide. Nous recherchons
des équipes de personnes cohésives et largement autonomes - exactement les mêmes critères
nous devrions utiliser lorsque nous modularisons le code. Il y a des signes avant-coureurs qui
l'organisation de l'équipe est mauvaise - un exemple classique est d'avoir deux sous-équipes
travailler sur le même module ou la même classe de programme.
Les équipes sur des projets plus importants ont besoin de ressources supplémentaires : un bibliothécaire qui indexe
et stocke le code et la documentation, un constructeur d'outils qui fournit des
outils et environnements, support opérationnel, etc.
Automatisation
Automatisation
Savoir
Savoir quand
quand arrêter
arrêter d'ajouter
d'ajouter de
de la
la peinture
peinture
Rappelez-vous que les équipes sont composées d'individus. Donnez à chaque membre le
capacité à briller à sa manière. Donnez-leur juste assez de structure pour
les soutenir et s'assurer que le projet respecte ses
exigences. Alors, comme le peintre de Good-Enough Software, résistez aux
tentation d'ajouter plus de peinture.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
• • Entropie logicielle
• • Soupe aux cailloux et grenouilles bouillies
• • Logiciel suffisamment bon
• • Communiquer!
• • Les maux de la duplication
• • Orthogonalité
• • Conception par contrat
• • Le découplage et la loi de Déméter
• • Automatisation omniprésente
Défis
Défis
Automatisation
Automatisation omniprésente
omniprésente
Alfred
Alfred North
North Whitehead
Whitehead
Bien que l'informatique soit encore une industrie au stade du Modèle-T, nous ne pouvons pas
se permettre de parcourir deux pages d'instructions encore et encore pour certains
opération commune. Qu'il s'agisse de la procédure de construction et de publication, du code
revoir la paperasserie, ou toute autre tâche récurrente sur le projet, il doit être
automatique. Nous devrons peut-être construire le démarreur et l'injecteur de carburant à partir de zéro,
mais une fois que c'est fait, on peut juste tourner la clé à partir de là.
Tout
Tout en
en automatique
automatique
Nous étions une fois sur un site client où tous les développeurs utilisaient le même
IDE. Leur administrateur système a donné à chaque développeur un ensemble d'instructions
sur l'installation de packages complémentaires dans l'IDE. Ces instructions ont rempli de nombreuses
pages - pages pleines de cliquez ici, faites défiler là-bas, faites glisser ceci, double-cliquez sur cela et
refais-le.
Astuce
Astuce 61
61
Les gens ne sont tout simplement pas aussi reproductibles que les ordinateurs. Il ne faut pas non plus s'attendre
qu'ils soient. Un script shell ou un fichier batch exécutera les mêmes instructions, dans
le même ordre, à chaque fois. Il peut être placé sous contrôle de source, de sorte que vous
peut également examiner les modifications apportées à la procédure au fil du temps ("mais
travailler…").
Un autre outil d'automatisation favori est cron (ou "at" sous Windows NT). Il
nous permet de programmer des tâches sans surveillance pour qu'elles s'exécutent périodiquement, généralement dans le
au milieu de la nuit. Par exemple, ce qui suit crontab spécifie qu'un
projets la commande nocturne doit être exécutée à minuit cinq minutes tous les jours,
q u
êt er
En utilisant cron, nous pouvons planifier des sauvegardes, la construction nocturne, le site Web
l'entretien et tout ce qui doit être fait - sans surveillance,
automatiquement.
Compilation
Compilation du
du projet
projet
Compiler le projet est une corvée qui doit être fiable et reproductible. Nous
compilent généralement des projets avec des makefiles, même lors de l'utilisation d'un IDE
environnement. Il y a plusieurs avantages à utiliser les makefiles. C'est un
procédure scriptée et automatique. Nous pouvons ajouter des crochets pour générer du code pour nous,
et exécutez des tests de régression automatiquement. Les IDE ont leurs avantages, mais
avec les IDE seuls, il peut être difficile d'atteindre le niveau d'automatisation que nous sommes
à la recherche de. Nous voulons vérifier, construire, tester et expédier avec un seul
commande.
Génération
Génération de
de code
code
Dans The Evils of Duplication , nous avons préconisé de générer du code pour dériver
connaissances provenant de sources communes. Nous pouvons exploiter la dépendance de make
mécanisme d'analyse pour faciliter ce processus. C'est une question assez simple
pour ajouter des règles à un makefile pour générer un fichier à partir d'une autre source
automatiquement. Par exemple, supposons que nous voulions prendre un fichier XML,
g énéer
Tests
Tests de
de régression
régression
Vous pouvez également utiliser le makefile pour exécuter des tests de régression pour vous, soit pour un
module individuel ou pour un sous-système entier. Vous pouvez facilement tester l'ensemble
projet avec une seule commande en haut de l'arborescence source, ou vous pouvez tester
un module individuel en utilisant la même commande dans un seul répertoire. Voir
Ruthless Testing , pour en savoir plus sur les tests de régression.
Make récursif
make calcule les dépendances entre les différentes cibles qu'il doit
construire. Mais il ne peut analyser que les dépendances qui existent au sein
un seul faire l'invocation. En particulier, un make récursif n'a pas
connaissance des dépendances que d'autres invocations de make peuvent avoir.
Si vous êtes prudent et précis, vous pouvez obtenir les bons résultats, mais c'est
facile de causer du travail supplémentaire inutilement - ou de manquer une dépendance et
pas recompiler quand c'est nécessaire.
De plus, les dépendances de construction peuvent ne pas être les mêmes que celles de test
dépendances, et vous aurez peut-être besoin de hiérarchies distinctes.
Construire
Construire l'automatisation
l'automatisation
[3] Si vous produisez un CD-ROM au format ISO9660, par exemple, vous exécuterez le programme qui produit un
image bit à bit du système de fichiers 9660. Pourquoi attendre la nuit avant d'expédier pour vous assurer que cela fonctionne ?
Pour la plupart des projets, ce niveau de build est exécuté automatiquement chaque nuit. Dans
cette version nocturne, vous exécuterez généralement des tests plus complets qu'un
l'individu peut s'exécuter lors de la construction d'une partie spécifique du projet.
Le point important est que la version complète exécute tous les tests disponibles. Toi
vous voulez savoir si un test de régression a échoué à cause de l'un des codes d'aujourd'hui
changements. En identifiant le problème près de la source, vous vous portez mieux
chance de le trouver et de le réparer.
Lorsque vous n'exécutez pas de tests régulièrement, vous pouvez découvrir que l'application
cassé en raison d'un changement de code effectué il y a trois mois. Bonne chance pour trouver ça
un.
Versions
Versions finales
finales
Les versions finales, que vous avez l'intention d'expédier en tant que produits, peuvent avoir des
exigences de la construction nocturne régulière. Une version finale peut nécessiter que
le référentiel soit verrouillé, ou étiqueté avec le numéro de version, qui
les indicateurs d'optimisation et de débogage doivent être définis différemment, et ainsi de suite. Nous aimons utiliser un
séparé make target (comme make final ) qui définit tous ces paramètres
immediatement.
N'oubliez pas que si le produit est compilé différemment des versions antérieures,
alors vous devez tester à nouveau cette version.
Administration
Administration automatique
automatique
Ne serait-il pas agréable que les programmeurs puissent réellement consacrer tout leur temps à
la programmation? Malheureusement, c'est rarement le cas. Il y a un e-mail à être
réponses, des papiers à remplir, des documents à publier sur le Web,
et ainsi de suite. Vous pouvez décider de créer un script shell pour faire une partie du sale
fonctionnent, mais vous devez toujours vous rappeler d'exécuter le script si nécessaire.
Parce que la mémoire est la deuxième chose que vous perdez [4] nous ne voulons pas
en vieillissant,
compter trop dessus. Nous pouvons exécuter des scripts pour effectuer des procédures pour nous
automatiquement, en fonction du contenu du code source et des documents. Notre objectif
est de maintenir un flux de travail automatique, sans surveillance et axé sur le contenu.
Génération
Génération de
de site
site Web
Web
deviennent obsolètes ou obsolètes. Une information trompeuse est pire que non
informations du tout.
Quoi qu'il en soit, le contenu Web doit être généré automatiquement à partir de
informations dans le référentiel et publiées sans intervention humaine.
C'est vraiment une autre application du principe DRY : l'information existe
sous une seule forme sous forme de code d'enregistrement et de documents. La vue depuis le Web
navigateur est simplement cela, juste une vue. Tu ne devrais pas avoir à maintenir ça
voir à la main.
Toutes les informations générées par la construction nocturne doivent être accessibles sur le
site Web de développement : résultats de la construction elle-même (par exemple, la construction
les résultats peuvent être présentés sous la forme d'un résumé d'une page qui inclut le compilateur
avertissements, erreurs et état actuel), tests de régression, performances
statistiques, métriques de codage et toute autre analyse statique, etc.
Procédures
Procédures d'approbation
d'approbation
Certains projets ont divers workflows administratifs qui doivent être suivis.
Par exemple, les revues de code ou de conception doivent être programmées et suivies
à travers, des approbations peuvent devoir être accordées, et ainsi de suite. On peut utiliser
l'automatisation, et en particulier le site Web, pour faciliter la paperasserie
fardeau.
Supposons que vous vouliez automatiser la planification et l'approbation de la révision du code. Toi
p o
Un simple script pourrait parcourir tout le code source et rechercher tous les fichiers
qui avaient le statut d'examen_des_besoins, indiquant qu'ils étaient prêts à être
revu. Vous pouvez ensuite publier une liste de ces fichiers sous forme de page Web,
envoyer automatiquement un e-mail aux personnes appropriées, ou même programmer un
réunion automatiquement à l'aide d'un logiciel de calendrier.
Vous pouvez configurer un formulaire sur une page Web pour que les réviseurs enregistrent l'approbation
ou désapprobation. Après l'examen, le statut peut être automatiquement changé en
revu. Que vous ayez une revue de code avec tous les participants
C'est à toi de voir; vous pouvez toujours faire la paperasse automatiquement. (Dans un article de
CACM d'avril 1999, Robert Glass résume des recherches qui semblent
indiquent que, bien que l'inspection du code soit efficace, la réalisation d'examens dans
réunions n'est pas [ Gla99a].)
Les
Les enfants
enfants du
du cordonnier
cordonnier
Les enfants du cordonnier n'ont pas de chaussures. Souvent, les personnes qui développent des logiciels
utiliser les outils les plus pauvres pour faire le travail.
Mais nous avons toutes les matières premières dont nous avons besoin pour fabriquer de meilleurs outils. Nous avons
cron. Nous avons make, sur les plateformes Windows et Unix. Et nous avons
Perl et d'autres langages de script de haut niveau pour développer rapidement des
outils, générateurs de pages Web, générateurs de code, harnais de test, etc.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
Essayez d'écrire quelques scripts shell pour automatiser le processus. Est-ce que tu
cliquez toujours sur la même séquence d'icônes à plusieurs reprises ? Peux-tu
créer une macro pour faire tout cela pour vous ?
[5] À des fins d'estimation, vous pouvez calculer une moyenne de l'industrie d'environ 100 000 USD par tête - c'est le salaire
ainsi que les avantages sociaux, la formation, l'espace de bureau et les frais généraux, etc.
Tests
Tests impitoyables
impitoyables
La plupart des développeurs détestent les tests. Ils ont tendance à tester doucement, inconsciemment
savoir où le code va casser et éviter les points faibles. Pragmatique
Les programmeurs sont différents. Nous sommes poussés à trouver nos bogues maintenant, donc nous ne
avoir à endurer la honte que d'autres découvrent nos bogues plus tard.
Trouver des insectes, c'est un peu comme pêcher avec un filet. Nous utilisons de petits filets fins
(tests unitaires) pour attraper les vairons, et de grands filets grossiers (tests d'intégration) pour
attraper les requins tueurs. Parfois les poissons réussissent à s'échapper, alors on rafistole
tous les trous que nous trouvons, dans l'espoir d'attraper de plus en plus de défauts glissants
qui nagent dans notre pool de projets.
Astuce
Astuce 62
62
Nous voulons commencer les tests dès que nous aurons du code. Ces petits vairons ont
une mauvaise habitude de devenir assez rapidement des requins géants mangeurs d'hommes, et
attraper un requin est un peu plus difficile. Mais nous ne voulons pas avoir à tout faire
ce test à la main.
De nombreuses équipes développent des plans de test élaborés pour leurs projets. Parfois ils
les utilisera même. Mais nous avons constaté que les équipes qui utilisent des tests automatisés
ont de bien meilleures chances de succès. Les tests qui s'exécutent avec chaque build sont
beaucoup plus efficace que les plans de test qui reposent sur une étagère.
Plus un bogue est détecté tôt, moins il est coûteux d'y remédier. "Codez un peu, testez un
[6] et nous pouvons adopter que
peu" est un dicton populaire dans le monde Smalltalk,
mantra comme le nôtre en écrivant du code de test en même temps (ou même avant) que nous
écrire le code de fabrication.
[6] eXtreme Programming [ URL 45 ] appelle ce concept "Intégration continue, tests implacables".
En fait, un bon projet peut très bien avoir plus de code de test que de code de production.
Le temps qu'il faut pour produire ce code de test en vaut la chandelle. Ça finit
étant beaucoup moins cher à long terme, et vous avez en fait une chance de
produire un produit avec presque zéro défaut.
De plus, savoir que vous avez réussi le test vous donne un degré élevé de
confiance qu'un morceau de code est "fait".
Astuce
Astuce 63
63
Le codage n'est pas terminé jusqu'à ce que tous les tests soient exécutés
Ce n'est pas parce que vous avez fini de pirater un morceau de code que vous
pouvez aller dire à votre patron ou à votre client que c'est fait. Ce n'est pas. Tout d'abord, le code est
jamais vraiment fait. Plus important encore, vous ne pouvez pas prétendre qu'il est utilisable par
n'importe qui jusqu'à ce qu'il réussisse tous les tests disponibles.
Nous devons examiner trois aspects principaux des tests à l'échelle du projet : que tester,
comment tester et quand tester.
Quoi
Quoi tester
tester
Il existe plusieurs types majeurs de tests logiciels que vous devez effectuer :
• • Tests unitaires
• • Tests d'intégration
• • Validation et vérification
• • Épuisement des ressources, erreurs et récupération
• • Test de performance
• • Tests d'utilisation
Cette liste n'est en aucun cas exhaustive et certains projets spécialisés nécessiteront
divers autres types de tests également. Mais cela nous donne un bon point de départ.
Tests
Tests unitaires
unitaires
Un test unitaire est un code qui teste un module. Nous avons traité ce sujet seul dans
Code facile à tester. Les tests unitaires sont la base de tous les autres
formes de test dont nous parlerons dans cette section. Si les pièces ne fonctionnent pas par
eux-mêmes, ils ne fonctionneront probablement pas bien ensemble. Tous les modules que vous
que vous utilisez doivent passer leurs propres tests unitaires avant de pouvoir continuer.
Une fois que tous les modules pertinents ont réussi leurs tests individuels, vous êtes
prêt pour la prochaine étape. Vous devez tester comment tous les modules utilisent et
interagissent les uns avec les autres dans tout le système.
Tests
Tests d'intégration
d'intégration
Les tests d'intégration montrent que les principaux sous-systèmes qui composent le
travail de projet et bien jouer les uns avec les autres. Avec de bons contrats en place
et bien testé, tout problème d'intégration peut être détecté facilement. Sinon,
l'intégration devient un terreau fertile pour les bogues. En fait, c'est souvent
la plus grande source de bogues du système.
Les tests d'intégration ne sont en fait qu'une extension des tests unitaires que nous avons
décrit - seulement maintenant vous testez comment des sous-systèmes entiers honorent leur
contrats.
Validation
Validation et
et vérification
vérification
Dès que vous disposez d'une interface utilisateur exécutable ou d'un prototype, vous devez
répondre à une question primordiale : les utilisateurs vous ont dit ce qu'ils voulaient, mais
est-ce ce dont ils ont besoin ?
Maintenant que vous avez une assez bonne idée que le système se comportera correctement
dans des conditions idéales, vous devez découvrir comment il se comportera sous
conditions du monde réel. Dans le monde réel, vos programmes n'ont pas de limites
ressources; ils manquent de choses. Quelques limites que votre code peut rencontrer
inclure:
• • Mémoire
• • Espace disque
• • Bande passante du processeur
• • Heure de l'horloge murale
• • Bande passante disque
• • Bande passante réseau
• • Palette de couleurs
• • Résolution vidéo
Vous pouvez en fait vérifier les échecs d'espace disque ou d'allocation de mémoire, mais
à quelle fréquence testez-vous les autres? Votre application tiendra-t-elle sur un 640 × 480
écran avec 256 couleurs? Fonctionnera-t-il sur un écran 1600 × 1280 avec des couleurs 24 bits
sans ressembler à un timbre-poste ? Le traitement par lots se terminera-t-il avant le
l'archive commence ?
Vous pouvez détecter les limitations environnementales, telles que les spécifications vidéo,
et adapter le cas échéant. Cependant, toutes les pannes ne sont pas récupérables. Si ton
code détecte que la mémoire est épuisée, vos options sont limitées : vous
peut ne pas avoir assez de ressources pour faire autre chose qu'échouer.
Test
Test de
de performance
performance
Les tests de performance, les tests de résistance ou les tests sous charge peuvent être un
également un aspect important du projet.
Pour certaines applications, vous aurez peut-être besoin de matériel de test spécialisé ou
logiciel pour simuler la charge de manière réaliste.
Tests
Tests d'utilisation
d'utilisation
Les tests d'utilisabilité sont différents des types de tests discutés jusqu'à présent. C'est
réalisés avec de vrais utilisateurs, dans des conditions environnementales réelles.
Regardez
Regardez la
la convivialité
convivialité en
en termes
termes de
de facteurs
facteurs humains.
humains. YY avait-il
avait-il des
des miC'est
miC'est tout
tout
En
En écrivant
écrivant
Proverbe
Proverbe chinois
chinois
En règle générale, les développeurs ne prêtent pas beaucoup d'attention à la documentation. Au mieux ça
est une nécessité malheureuse; au pire, elle est traitée comme une tâche peu prioritaire dans
l'espoir que la direction l'oubliera à la fin du projet.
Ce ne sont pas exactement des pensées originales ou nouvelles ; l'idée du code du mariage
et la documentation apparaît dans le travail de Donald Knuth sur l'alphabétisation
programmation et dans l'utilitaire JavaDoc de Sun, entre autres. Nous voulons
minimiser la dichotomie entre le code et la documentation, et à la place
traitez-les comme deux vues du même modèle (voir Ce n'est qu'une ). En
vuefait, nous
voulons aller un peu plus loin et appliquer tous nos principes pragmatiques pour
documentation ainsi qu'au code.
Astuce
Astuce 67
67
Astuce
Astuce 68
68
Commentaires
Commentaires dans
dans le
le code
code
Produire des documents formatés à partir des commentaires et des déclarations dans
code source est assez simple, mais nous devons d'abord nous assurer que nous
ont en fait des commentaires dans le code. Le code devrait avoir des commentaires, mais aussi
de nombreux commentaires peuvent être tout aussi mauvais que trop peu.
En général, les commentaires doivent expliquer pourquoi quelque chose est fait, son but
et son objectif. Le code montre déjà comment cela se fait, donc commenter ceci
est redondant et constitue une violation du principe DRY.
Nous aimons voir un simple commentaire d'en-tête au niveau du module, des commentaires pour
données significatives et déclarations de type, et un bref par classe et par méthode
en-tête, décrivant comment la fonction est utilisée et tout ce qu'elle fait
n'est pas évident.
Les noms de variables, bien sûr, doivent être bien choisis et significatifs.
fou, pour
instance, n'a pas de sens, tout comme doit ou manager ou stuff. hongrois
notation (où vous encodez les informations de type de la variable dans le nom
lui-même) est tout à fait inapproprié dans les systèmes orientés objet. Rappelez-vous que
vous (et d'autres après vous) lirez le code plusieurs centaines de fois,
am si
a u
Pire encore que les noms dénués de sens sont les noms trompeurs. As-tu déjà
quelqu'un a expliqué les incohérences dans le code hérité telles que "La routine
appelégetData écrit vraiment des données sur le disque" ? Le cerveau humain
cela s'encrasse - c'est ce qu'on appelle l'effet Stroop [ Str35 ]. Vous pouvez essayer ce qui suit
expérimentez vous-même pour voir les effets de telles interférences. Obtenez de la couleur
stylos et utilisez-les pour écrire les noms des couleurs. Cependant, jamais
écrivez un nom de couleur à l'aide de ce stylo de couleur. Vous pourriez écrire le mot "bleu" dans
vert, le mot "marron" en rouge, etc. (Alternativement, nous avons un échantillon
ensemble de couleurs déjà dessiné sur notre site Web à
http://www.pragmaticprogrammer.com .) Une fois que vous avez les noms de couleurs
dessiné, essayez de dire à haute voix la couleur avec laquelle chaque mot est dessiné, aussi vite que
tu peux. À un moment donné, vous trébucherez et commencerez à lire les noms des
couleurs, et non les couleurs elles-mêmes. Les noms sont profondément significatifs pour votre
cerveau, et les noms trompeurs ajoutent du chaos à votre code.
Vous pouvez documenter des paramètres, mais demandez-vous si c'est vraiment nécessaire dans
tous les cas. Le niveau de commentaire suggéré par l'outil JavaDoc semble
a p
* * @
Voici une liste de choses qui ne devraient pas apparaître dans les commentaires source.
[9] Ce type d'information, ainsi que le nom du fichier, est fourni par la balise RCS $Id$.
• • Une liste des autres fichiers utilisés par ce fichier. Cela peut être déterminé plus
avec précision à l'aide d'outils automatiques.
• • Le nom du fichier. S'il doit apparaître dans le fichier, ne
l'entretenir à la main. Le RCS et les systèmes similaires peuvent conserver cette
informations mises à jour automatiquement. Si vous déplacez ou renommez le fichier,
vous ne voulez pas avoir à vous rappeler de modifier l'en-tête.
L'un des éléments d'information les plus importants qui devraient apparaître dans le
le fichier source est le nom de l'auteur, pas nécessairement celui qui a modifié le fichier en dernier,
mais le propriétaire. Attacher la responsabilité et l'imputabilité au code source
fait des merveilles pour garder les gens honnêtes (voir Pride and Prejudice ).
Le projet peut également exiger certains avis de droit d'auteur ou d'autres mentions légales.
passe-partout à apparaître dans chaque fichier source. Demandez à votre éditeur de les insérer pour
vous automatiquement.
Avec des commentaires significatifs en place, des outils tels que JavaDoc [ URL 7 ] et
DOC++ [ URL 21 ] peut les extraire et les formater pour produire automatiquement
Documentation au niveau de l'API. Ceci est un exemple spécifique d'un plus général
technique que nous utilisons : les documents exécutables.
Documents
Documents exécutables
exécutables
Supposons que nous ayons une spécification qui répertorie les colonnes d'une table de base de données.
Nous aurons alors un ensemble séparé de commandes SQL pour créer la table réelle
[10] Voir It's Just a View , pour en savoir plus sur les modèles et les vues.
Si votre document est stocké en texte brut avec des commandes de balisage (à l'aide
HTML, LaTeX ou troff, par exemple), vous pouvez utiliser des outils tels que Perl pour
extraire le schéma et le reformater automatiquement. Si votre document est dans un
format binaire du traitement de texte, puis consultez l'encadré de la page suivante pour
certaines options.
• • Ecrire des macros. Les traitements de texte les plus sophistiqués actuellement
avoir un macro-langage. Avec un peu d'effort, vous pouvez programmer
leur permet d'exporter les sections balisées de vos documents vers le
formes alternatives dont vous avez besoin. Si la programmation à ce niveau est
trop pénible, vous pouvez toujours exporter la section appropriée
dans un fichier texte brut au format standard, puis utilisez un outil
comme Perl pour convertir cela dans les formes finales.
• • Rendre le document subordonné. Plutôt que d'avoir le
document comme source définitive, utilisez un autre
Nous pouvons générer une documentation au niveau de l'API à partir du code source à l'aide d'outils
tels que JavaDoc et DOC++ de la même manière. Le modèle est la source
code : une vue du modèle peut être compilée ; d'autres vues sont censées être
imprimés ou consultés sur le Web. Notre objectif est toujours de travailler sur
modèle - que le modèle soit le code lui-même ou un autre document - et
avoir toutes les vues mises à jour automatiquement (voir Ubiquitous ,Automation
pour plus
sur les processus automatiques).
Rédacteurs
Rédacteurs techniques
techniques
Jusqu'à présent, nous n'avons parlé que de documentation interne, rédigée par
les programmeurs eux-mêmes. Mais que se passe-t-il lorsque vous avez
des rédacteurs techniques professionnels impliqués dans le projet ? Trop souvent,
les programmeurs jettent simplement du matériel "par-dessus le mur" aux rédacteurs techniques et
laissez-les se débrouiller seuls pour produire des manuels d'utilisation, des pièces promotionnelles,
et ainsi de suite.
C'est une erreur. Ce n'est pas parce que les programmeurs n'écrivent pas ces
documents ne signifie pas que nous pouvons renoncer aux principes pragmatiques. Nous
veulent que les écrivains adoptent les mêmes principes de base qu'un pragmatique
Le programmeur le fait, en particulier en respectant le principe DRY, l'orthogonalité,
le concept de vue modèle et l'utilisation de l'automatisation et des scripts.
Imprimez-le
Imprimez-le ou
ou tissez-le
tissez-le
Nous essayons donc de produire toute la documentation sous une forme qui peut être publiée
en ligne, sur le Web, complété par des hyperliens. Il est plus facile de garder cette vue de
la documentation à jour que de retrouver tous les exemplaires papier existants,
brûlez-le, et réimprimez et redistribuez de nouvelles copies. C'est aussi une meilleure façon de
répondre aux besoins d'un large public. N'oubliez pas cependant de mettre une date
cachet ou numéro de version sur chaque page Web. De cette façon, le lecteur peut obtenir un
bonne idée de ce qui est à jour, de ce qui a changé récemment et de ce qui ne l'a pas été.
Si vous utilisez un système de balisage, vous avez la possibilité d'implémenter au fur et à mesure
d e
[11] eXtensible Style Language et Cascading Style Sheets, deux technologies conçues pour aider à séparer la présentation de
contenu.
Si vous utilisez un traitement de texte, vous aurez probablement des capacités similaires.
Si vous avez pensé à utiliser des styles pour identifier les différents éléments du document,
puis en appliquant différentes feuilles de style, vous pouvez modifier radicalement l'apparence de
la sortie finale. La plupart des traitements de texte vous permettent maintenant de convertir vos
document vers des formats tels que HTML pour la publication Web.
Langages
Langages de
de balisage
balisage
Enfin, pour les projets de documentation à grande échelle, nous recommandons de consulter
certains des schémas les plus modernes de balisage de la documentation.
De nombreux auteurs techniques utilisent désormais DocBook pour définir leurs documents.
DocBook est une norme de balisage basée sur SGML qui identifie soigneusement
chaque composant d'un document. Le document peut passer par un
Processeur DSSSL pour le restituer dans n'importe quel nombre de formats différents. Le
Le projet de documentation Linux utilise DocBook pour publier des informations en RTF,
Tant que votre balisage d'origine est suffisamment riche pour exprimer tous les concepts
dont vous avez besoin (y compris les hyperliens), traduction vers toute autre forme pouvant être publiée
peut être à la fois facile et automatique. Vous pouvez produire une aide en ligne, publiée
des manuels, des produits phares pour le site Web et même un calendrier de conseils par jour,
tous de la même source, qui est bien sûr sous contrôle de source et est
construit avec la construction nocturne (voir Ubiquitous Automation
).
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
des malentendus lors de l'analyse des exigences qui doivent être résolus ?
Le logiciel s'adapte-t-il à l'utilisateur comme une extension de la main ? (Non seulement nous
voulons que nos propres outils tiennent dans nos mains, mais nous voulons les outils que nous créons pour
utilisateurs de s'adapter également à leurs mains.)
Comme pour la validation et la vérification, vous devez effectuer des tests d'utilisabilité comme
le plus tôt possible, tant qu'il est encore temps d'apporter des corrections. Pour les plus grands
projets, vous voudrez peut-être faire appel à des spécialistes des facteurs humains. (Si rien
sinon, c'est amusant de jouer avec les rétroviseurs sans tain).
Le non-respect des critères d'utilisabilité est un bogue aussi important que la division par zéro.
Comment
Comment tester
tester
Nous avons regardé quoi tester. Maintenant, nous allons porter notre attention sur la façon de tester,
y compris:
Test de conception/méthodologie
Pouvez-vous tester la conception du code lui-même et la méthodologie que vous
utilisé pour créer le logiciel ? Après une mode, oui vous pouvez. Tu fais cela
en analysant les métriques - mesures de divers aspects du code.
La métrique la plus simple (et souvent la moins intéressante) est celle des lignes de
code—quelle est la taille du code lui-même ?
Il existe une grande variété d'autres mesures que vous pouvez utiliser pour examiner
codes, y compris :
Certaines mesures sont conçues pour vous donner une « note de passage », tandis que
d'autres ne sont utiles que par comparaison. Autrement dit, vous calculez ces
métriques pour chaque module du système et voir comment un particulier
module se rapporte à ses frères. Techniques statistiques standard
(comme la moyenne et l'écart type) sont généralement utilisés ici.
Si vous trouvez un module dont les métriques sont sensiblement différentes de toutes
le reste, vous devez vous demander si cela est approprié. Pour certains
modules, il peut être acceptable de "faire exploser la courbe". Mais pour ceux qui ne le font pas
avoir une bonne excuse, cela peut indiquer des problèmes.
Les
Les tests
tests de
de régression
régression
Un test de régression compare la sortie du test actuel avec le test précédent (ou
valeurs connues). Nous pouvons nous assurer que les bogues que nous avons corrigés aujourd'hui n'ont rien cassé
qui fonctionnaient hier. Il s'agit d'un filet de sécurité important, et il coupe
à l'abri des mauvaises surprises.
Tous les tests que nous avons mentionnés jusqu'à présent peuvent être exécutés comme des tests de régression,
s'assurer que nous n'avons pas perdu de terrain à mesure que nous développons un nouveau code. Nous pouvons
exécuter des régressions pour vérifier les performances, les contrats, la validité, etc.
Données
Données de
de test
test
Où obtenons-nous les données pour exécuter tous ces tests ? Il n'y a que deux sortes de
données : données du monde réel et données synthétiques. En fait, nous devons utiliser les deux,
parce que les différentes natures de ces types de données exposeront différents
bogues dans notre logiciel.
Les données du monde réel proviennent d'une source réelle. Peut-être a-t-il été
collectées à partir d'un système existant, d'un système concurrent ou d'un prototype de
une sorte. Il représente les données utilisateur typiques. Les grandes surprises arrivent lorsque vous
découvrez ce que signifie typique. Ceci est le plus susceptible de révéler des défauts et
malentendus dans l'analyse des besoins.
Les données synthétiques sont générées artificiellement, peut-être sous certaines conditions statistiques.
contraintes. Vous devrez peut-être utiliser des données synthétiques pour l'un des éléments suivants
les raisons.
• • Vous avez besoin de beaucoup de données, peut-être plus que n'importe quel échantillon du monde réel
pourrait fournir. Vous pourrez peut-être utiliser les données du monde réel comme graine
pour générer un ensemble d'échantillons plus large et modifier certains champs qui doivent
être unique.
• • Vous avez besoin de données pour souligner les conditions aux limites. Ces données peuvent
être complètement synthétique : champs de date contenant le 29 février 1999,
des tailles d'enregistrement énormes ou des adresses avec des codes postaux étrangers.
• • Vous avez besoin de données présentant certaines propriétés statistiques. Vouloir
pour voir ce qui se passe si une transaction sur trois échoue ? Se souvenir du
algorithme de tri qui ralentit en rampant lorsqu'il reçoit des données pré-triées ?
Vous pouvez présenter les données dans un ordre aléatoire ou trié pour exposer ce type de
faiblesse.
Exercer
Exercer des
des systèmes
systèmes GUI
GUI
Tester des systèmes gourmands en interfaces graphiques nécessite souvent des outils de test spécialisés.
Ces outils peuvent être basés sur un simple modèle de capture/lecture d'événements, ou ils
peut nécessiter des scripts spécialement écrits pour piloter l'interface graphique. Certains systèmes
combiner des éléments des deux.
Des outils moins sophistiqués imposent un degré élevé de couplage entre les
version du logiciel testé et le script de test lui-même : si vous déplacez un
boîte de dialogue ou réduisez la taille d'un bouton, le test risque de ne pas le trouver, et
peut tomber. La plupart des outils de test GUI modernes utilisent un certain nombre de
techniques pour contourner ce problème et essayer de s'adapter à une mise en page mineure
différences.
Cependant, vous ne pouvez pas tout automatiser. Andy a travaillé sur un graphisme
système permettant à l'utilisateur de créer et d'afficher un visuel non déterministe
effets simulant divers phénomènes naturels. Malheureusement, pendant
test, vous ne pouviez pas simplement saisir un bitmap et comparer la sortie avec un
précédent, car il a été conçu pour être différent à chaque fois. Pour
situations comme celle-ci, vous n'aurez peut-être pas d'autre choix que de vous fier au manuel
interprétation des résultats des tests.
Parce que nous ne pouvons pas écrire un logiciel parfait, il s'ensuit que nous ne pouvons pas écrire
logiciel de test parfait non plus. Nous devons tester les tests.
Considérez notre ensemble de suites de tests comme un système de sécurité élaboré, conçu pour
sonner l'alarme lorsqu'un bug apparaît. Comment mieux tester un système de sécurité
que d'essayer de s'introduire ?
Après avoir écrit un test pour détecter un bogue particulier, provoquez le bogue
délibérément et assurez-vous que le test se plaint. Cela garantit que le test
attrapera le bogue si cela se produit pour de vrai.
Astuce
Astuce 64
64
Si vous êtes vraiment sérieux au sujet des tests, vous voudrez peut-être nommer un projet
saboteur. Le rôle du saboteur est de prendre une copie séparée de l'arbre source,
introduisez des bogues exprès et vérifiez que les tests les détecteront.
Lors de l'écriture des tests, assurez-vous que les alarmes sonnent quand elles le devraient.
Tester
Tester soigneusement
soigneusement
Une fois que vous êtes sûr que vos tests sont corrects et que vous trouvez des bogues, vous
créer, comment savez-vous si vous avez testé la base de code à fond
assez?
La réponse courte est "vous ne le faites pas", et vous ne le ferez jamais. Mais il existe des produits
sur le marché qui peut aider. Ces outils d'analyse de couverture surveillent votre code
pendant les tests et garder une trace des lignes de code qui ont été exécutées et
qui n'ont pas. Ces outils vous donnent une idée générale de la façon dont
vos tests sont complets, mais ne vous attendez pas à une couverture à 100 %.
En théorie, cette fonction à trois lignes possède 1 000 000 d'états logiques, 999 999 de
qui fonctionnera correctement et une qui ne fonctionnera pas (lorsque a + b est égal à zéro).
Le simple fait de savoir que vous avez exécuté cette ligne de code ne vous dit pas
cela - vous auriez besoin d'identifier tous les états possibles du programme.
Malheureusement, en général, c'est un problème très difficile. Dur comme dans "Le
le soleil sera une masse froide et dure avant que vous ne puissiez le résoudre."
Astuce
Astuce 65
65
Même avec une bonne couverture de code, les données que vous utilisez pour les tests ont toujours un énorme
impact, et, plus important encore, l'ordre dans lequel vous parcourez le code peut
ont le plus grand impact de tous.
Quand
Quand tester
tester
De nombreux projets ont tendance à laisser les tests à la dernière minute, là où ils seront
être coupé contre le tranchant d'un délai. [8] Nous devons commencer beaucoup plus tôt
que ça. Dès qu'un code de production existe, il doit être testé.
[8]
[8] morts
morts
......ligne \ded-lîn\ n (1864) une ligne tracée à l'intérieur ou autour d'une prison qu'un prisonnier passe au risque d'être
La plupart des tests doivent être effectués automatiquement. Il est important de noter que par
"automatiquement" signifie que les résultats du test sont interprétés automatiquement
aussi. Voir Ubiquitous Automation , pour plus d'informations à ce sujet.
Nous aimons tester aussi souvent que possible, et toujours avant de vérifier le code
dans le référentiel source. Certains systèmes de contrôle de code source, comme Aegis,
p e
Habituellement, ce n'est pas un problème d'exécuter des régressions sur l'ensemble de l'unité individuelle
tests et tests d'intégration aussi souvent que nécessaire.
Mais certains tests peuvent ne pas être facilement exécutés aussi fréquemment. Stress
les tests, par exemple, peuvent nécessiter une configuration ou un équipement spécial, et une certaine main
holding. Ces tests peuvent être exécutés moins souvent - hebdomadairement ou mensuellement, peut-être.
Mais il est important qu'ils soient exécutés sur une base régulière et planifiée. Si ça ne peut pas
être fait automatiquement, puis assurez-vous qu'il apparaît sur le calendrier, avec tous
les ressources nécessaires allouées à la tâche.
Resserrer
Resserrer le
le filet
filet
Enfin, nous aimerions révéler le concept le plus important dans les tests. Il
est une évidence, et pratiquement tous les manuels disent de le faire de cette façon. Mais
pour une raison quelconque, la plupart des projets ne le font toujours pas.
Si un bogue se glisse dans le filet des tests existants, vous devez ajouter un nouveau test à
attrapez-le la prochaine fois.
Astuce
Astuce 66
66
Une fois qu'un testeur humain trouve un bogue, ce devrait être la dernière fois qu'un testeur humain
trouve ce bogue. Les tests automatisés doivent être modifiés pour vérifier que
bogue particulier à partir de là, à chaque fois, sans exception, peu importe comment
trivial, et peu importe à quel point le développeur se plaint et dit : "Oh,
Cela n'arrivera plus jamais."
Parce des
après que bugs
cela se
quereproduira. Et nous n'avons
les tests automatisés tout simplement
auraient pas leNous
pu nous trouver. temps d'aller chasser
devons
passons notre temps à écrire du nouveau code et de nouveaux bugs.
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
De
De grandes
grandes attentes
attentes
Jérémie
Jérémie 2:12
2:12
Une entreprise annonce des bénéfices records et le cours de son action chute de 20 %. Le
des nouvelles financières ce soir-là expliquent que l'entreprise n'a pas réussi à se réunir
attentes des analystes. Un enfant ouvre un cadeau de Noël coûteux et
éclate en sanglots - ce n'était pas la poupée bon marché que l'enfant espérait. UN
l'équipe du projet fait des miracles pour mettre en œuvre une solution d'une complexité phénoménale
application, seulement pour la voir boudée par ses utilisateurs parce qu'elle n'a pas de
système d'aide.
Dans un sens abstrait, une application est réussie si elle implémente correctement
ses spécifications. Malheureusement, cela ne paie que des factures abstraites.
Astuce
Astuce 69
69
Communiquer
Communiquer les
les attentes
attentes
Les utilisateurs viennent d'abord vers vous avec une vision de ce qu'ils veulent. C'est possible
incomplet, incohérent ou techniquement impossible, mais c'est le leur, et, comme
l'enfant à Noël, ils y investissent une certaine émotion. Vous ne pouvez pas
n'y faites pas attention.
Au fur et à mesure que votre compréhension de leurs besoins se développera, vous découvrirez des domaines où leurs
attentes ne peuvent être satisfaites, ou lorsque leurs attentes sont peut-être trop
conservateur. Une partie de votre rôle est de communiquer cela. Travaillez avec votre
utilisateurs afin que leur compréhension de ce que vous allez fournir soit exacte.
Et faites-le tout au long du processus de développement. Ne perdez jamais de vue la
les problèmes métier que votre application est censée résoudre.
Le
Le mille
mille supplémentaire
supplémentaire
Si vous travaillez en étroite collaboration avec vos utilisateurs, partagez leurs attentes et
communiquer ce que vous faites, il y aura peu de surprises lorsque
le projet est livré.
C'est une mauvaise chose. Essayez de surprendre vos utilisateurs. Ne pas leur faire peur, attention,
mais ravis-les.
Écoutez vos utilisateurs au fur et à mesure que le projet progresse pour obtenir des indices sur les fonctionnalités
les ravirait vraiment. Certaines choses que vous pouvez ajouter assez facilement
sembler bon à l'utilisateur moyen comprennent :
Les
Les sections
sections connexes
connexes comprennent
comprennent ::
Défis
Défis
• • Parfois, les critiques les plus sévères d'un projet sont les personnes qui
travaillé dessus. Avez-vous déjà été déçu que votre
vos propres attentes n'ont pas été satisfaites par quelque chose que vous avez produit ? Comment
cela pourrait-il être? Peut-être y a-t-il plus que de la logique à l'œuvre ici.
• • Que commentent vos utilisateurs lorsque vous fournissez un logiciel ? Est
leur attention aux différents domaines de l'application proportionnelle à
l'effort que vous avez investi dans chacun ? Qu'est-ce qui les ravit ?
Orgueil
Orgueil et
et préjugés
préjugés
Jane
Jane Austen,
Austen, Orgueil
Orgueil et
et préjugés
préjugés
Les programmeurs pragmatiques ne se dérobent pas à la responsabilité. Au lieu de cela, nous nous réjouissons
à relever des défis et à faire connaître notre expertise. Si nous sommes
responsables d'un design ou d'un morceau de code, nous faisons un travail dont nous pouvons être fiers.
Astuce
Astuce 70
70
Les artisans d'autrefois étaient fiers de signer leur travail. Tu devrais être,
aussi.
Cependant, les équipes de projet sont toujours composées de personnes et cette règle peut entraîner
inquiéter. Sur certains projets, l'idée de propriété du code peut provoquer une coopération
problèmes. Les gens peuvent devenir territoriaux ou ne pas vouloir travailler sur des projets communs
éléments de fondation. Le projet peut finir comme un tas de petits insulaires
fiefs. Vous développez des préjugés en faveur de votre code et contre votre
collègues de travail.
Ce n'est pas ce que nous voulons. Vous ne devriez pas défendre jalousement votre code contre
intrus ; de la même manière, vous devez traiter le code des autres avec
respect. La règle d'or ("Fais aux autres ce que tu voudrais qu'ils fassent
vous") et une base de respect mutuel entre les développeurs est essentielle pour
faire fonctionner cette astuce.
L'anonymat, en particulier sur les grands projets, peut constituer un terreau fertile pour
négligence, erreurs, paresse et mauvais code. Il devient trop facile de voir
vous-même comme un simple rouage dans la roue, produisant des excuses boiteuses dans un statut sans fin
des rapports au lieu d'un bon code.
Bien que le code doive appartenir à un individu, il n'est pas nécessaire qu'il appartienne à un individu. Dans
En fait, la méthode de programmation eXtreme réussie de Kent Beck [ URL ] 45
recommande la propriété commune du code (mais cela nécessite également des
pratiques, telles que la programmation en binôme, pour se prémunir contre les dangers de
anonymat).
Nous voulons voir la fierté de la propriété. "J'ai écrit ceci, et je me tiens derrière mon
travail." Votre signature devrait être reconnue comme un indicateur de
qualité. Les gens devraient voir votre nom sur un morceau de code et s'attendre à ce qu'il soit
solide, bien écrit, testé et documenté. Un travail vraiment professionnel.
Ecrit par un vrai professionnel.
Un programmeur pragmatique.
Annexe A. Ressources
La seule raison pour laquelle nous avons pu couvrir autant de terrain dans ce livre est que
nous avons vu beaucoup de nos sujets d'une haute altitude. Si nous leur avions donné le
couverture approfondie qu'ils méritaient, le livre aurait été dix fois
plus long.
Nous avons commencé le livre avec la suggestion que les programmeurs pragmatiques
devrait toujours apprendre. Dans cette annexe, nous avons répertorié les ressources qui peuvent
vous aider dans cette démarche.
Dans la section Sociétés professionnelles, nous donnons des détails sur l'IEEE et les
ACM. Nous recommandons aux programmeurs pragmatiques de rejoindre l'un (ou les deux) de
ces sociétés. Ensuite, dans Construire une bibliothèque, nous mettons en évidence des périodiques, des livres,
et les sites Web qui, selon nous, contiennent des informations pertinentes et de haute qualité
(ou qui sont tout simplement amusants).
Tout au long du livre, nous avons fait référence à de nombreuses ressources logicielles accessibles via
l'Internet. Dans la section Ressources Internet, nous listons les URL de ces
ressources, accompagnées d'une brève description de chacune. Cependant, la nature de
le Web signifie que bon nombre de ces liens pourraient bien être obsolètes au moment où vous
lis ce livre. Vous pouvez essayer l'un des nombreux moteurs de recherche pour en savoir plus.
lien à jour ou visitez notre site Web à l'adresse www.pragmaticprogrammer.com
et consultez notre section de liens.
Sociétés
Sociétés professionnelles
professionnelles
[1] Services aux membres ACM, PO Box 11414, New York, NY 10286, États-Unis.
www.acm.org
www.ordinateur.org
Construire
Construire une
une bibliothèque
bibliothèque
Nous sommes grands sur la lecture. Comme nous l'avons noté dans Votre portefeuille de connaissances , une bonne
programmeur est toujours en train d'apprendre. Se tenir au courant des livres et
les périodiques peuvent aider. En voici quelques-uns que nous aimons.
Périodiques
Périodiques
Si vous êtes comme nous, vous conserverez de vieux magazines et périodiques jusqu'à ce qu'ils soient
empilés assez haut pour transformer ceux du bas en feuilles plates de diamant. Ce
signifie qu'il vaut la peine d'être assez sélectif. Voici quelques périodiques que nous lisons.
Documents
Documents commerciaux
commerciaux hebdomadaires
hebdomadaires
Livres
Livres
Les livres d'informatique peuvent être coûteux, mais choisissez-les avec soin et ils sont un
investissement qui en vaut la peine. Voici une poignée des nombreux que nous aimons.
Analyse
Analyse et
et conception
conception
•• •• Construction
Construction de de logiciels
logiciels orientés
orientés objet,
objet, 2ème
2ème
Édition. Le livre épique de Bertrand Meyer sur les fondamentaux de
développement orienté objet, le tout en 1300 pages environ [ Mey97b ].
• • Modèles de conception. Un modèle de conception décrit une façon de résoudre un
classe particulière de problèmes à un niveau plus élevé qu'une programmation
idiome de la langue. Ce livre désormais classique [] GHJV95
par le Gang de
Quatre décrit 23 modèles de conception de base, y compris Proxy, Visitor,
et Singleton.
• • Modèles d'analyse. Un trésor d'architecture de haut niveau
modèles tirés d'une grande variété de projets réels et
distillé sous forme de livre. Un moyen relativement rapide d'avoir un aperçu de
de nombreuses années d'expérience en modélisation]. [ Fow96
Equipes
Equipes et
et Projets
Projets
Environnements
Environnements spécifiques
spécifiques
La
La toile
toile
Trouver du bon contenu sur le Web est difficile. Voici plusieurs liens que nous
vérifier au moins une fois par semaine.
• • Slashdot. Présenté comme "Des nouvelles pour les nerds. Des trucs qui comptent",
Slashdot est l'un des foyers Internet de la communauté Linux. Ainsi que
mises à jour régulières sur l'actualité Linux, le site propose des informations sur
des technologies cool et des problèmes qui affectent les développeurs.
www.slashdot.org
• • Liens Cetus. Des milliers de liens sur des sujets orientés objet.
www.cetus-links.org
• • WikiWikiWeb. Le référentiel de modèles de Portland et les modèles
discussion. Non seulement une excellente ressource, le site WikiWikiWeb est un
expérience intéressante d'édition collective d'idées.
www.c2.com
Ressources
Ressources Internet
Internet
Les liens ci-dessous renvoient à des ressources disponibles sur Internet. Ils étaient valides
au moment de la rédaction, mais (le Net étant ce qu'il est) ils pourraient bien être hors de
date au moment où vous lisez ceci. Si oui, vous pouvez essayer une recherche générale pour le
noms de fichiers ou rendez-vous sur le site Web de Pragmatic Programmer
( www.pragmaticprogrammer.com ) et suivez nos liens.
Éditeurs
Éditeurs
Emacs et vi ne sont pas les seuls éditeurs multiplateformes, mais ils sont librement
disponible et largement utilisé. Un rapide tour d'horizon d'un magazine tel que Dr.
Dobbs proposera plusieurs alternatives commerciales.
Emacs
Emacs
[URL
[URL l]l] L'éditeur
L'éditeur Emacs
Emacs
www.gnu.org
Le nec plus ultra des grands éditeurs, contenant toutes les fonctionnalités dont dispose n'importe quel éditeur
jamais eu, Emacs a une courbe d'apprentissage presque verticale, mais rembourse généreusement
une fois que vous l'avez maîtrisé. Il fait également un excellent centre commercial et un lecteur de nouvelles,
carnet d'adresses, calendrier et agenda, jeu d'aventure, ….
[URL
[URL 2]
2] L'éditeur
L'éditeur XEmacs
XEmacs
www.xemacs.org
vi
vi
Il existe au moins 15 clones vi différents disponibles. Parmi ceux-ci, vim est probablement
porté sur la plupart des plates-formes, et serait donc un bon choix d'éditeur si vous
se retrouver à travailler dans de nombreux environnements différents.
[URL
[URL 3]
3] L'éditeur
L'éditeur Vim
Vim
ftp://ftp.fu-berlin.de/misc/editors/vim
[URL
[URL 4]
4] L'éditeur
L'éditeur elvis
elvis
www.fh-wedel.de/elvis
[URL
[URL 5]
5] Mode
Mode Emacs
Emacs Vipère
Vipère
http://www.cs.sunysb.edu/~kifer/emacs.html
Viper est un ensemble de macros qui font ressembler Emacs à vi. Certains peuvent douter de
la sagesse de prendre le plus grand éditeur du monde et de l'étendre pour imiter un
éditeur dont la force est sa compacité. D'autres prétendent qu'il combine le meilleur
des deux mondes.
Compilateurs,
Compilateurs, langages
langages et
et outils
outils de
de développement
développement
[URL
[URL 6]
6] Le
Le compilateur
compilateur GNU
GNU C/C++
C/C++
www.fsf.org/software/gcc/gcc.html
L'un des compilateurs C et C++ les plus populaires de la planète. Cela fait aussi
Objectif c. (Au moment de la rédaction, le projet egcs, qui
séparé de gcc, est en train de se fondre dans le giron.)
[URL
[URL 7]
7] Le
Le langage
langage Java
Java de
de Sun
Sun
java.sun.com
[URL
[URL 8]
8] Page
Page d'accueil
d'accueil du
du langage
langage Perl
Perl
www.perl.com
[URL
[URL 9]
9] Le
Le langage
langage Python
Python
www.python.org
[URL
[URL 10]
10] PetitEiffel
PetitEiffel
PetitEiffel.loria.fr
Le compilateur GNU Eiffel s'exécute sur n'importe quelle machine disposant d'un compilateur ANSI C
et un environnement d'exécution Posix.
[URL
[URL 11]
11] ISE
ISE Eiffel
Eiffel
www.eiffel.com
Interactive Software Engineering est à l'origine de Design by Contract,
et vend un compilateur Eiffel commercial et les outils associés.
[URL
[URL 12]
12] Sather
Sather
www.icsi.berkeley.edu/~sather
[URL
[URL 13]
13] Visual
Visual Works
Works
www.objectshare.com
[URL
[URL 14]
14] L'environnement
L'environnement du
du langage
langage Squeak
Squeak
squeak.cs.uiuc.edu
[URL
[URL 15]
15] Le
Le langage
langage de
de programmation
programmation TOM
TOM
www.gerbil.org/tom
[URL
[URL 16]
16] Le
Le projet
projet Beowulf
Beowulf
www.beowulf.org
Un projet qui construit des ordinateurs hautes performances à partir de clusters en réseau
de boîtes Linux bon marché.
[URL
[URL 17]
17] iContract—Outil
iContract—Outil de
de conception
conception par
par contrat
contrat pour
pour Java
Java
www.reliable-systems.com
[URL
[URL 18]
18] Nana
Nana :: journalisation
journalisation et
et assertions
assertions pour
pour C
C et
et C++
C++
www.cs.ntu.edu.au/homepages/pjm/nana-home/index.html
[URL
[URL 19]
19] DDD–Débogueur
DDD–Débogueur d'affichage
d'affichage de
de données
données
www.cs.tu-bs.de/softech/ddd
[URL
[URL 20]
20] Navigateur
Navigateur de
de refactorisation
refactorisation de
de John
John Brant
Brant
st-www.cs.uiuc.edu/users/brant/Refactory
[URL
[URL 21
21 ]] Générateur
Générateur de
de documentation
documentation DOC++
DOC++
www.zib.de/Visual/software/doc++/index.html
DOC++ est un système de documentation pour C/C++ et Java qui génère à la fois
[URL
[URL 22]
22] Cadre
Cadre de
de test
test xUnit–Unit
xUnit–Unit
www.XProgranming.com
[URL
[URL 23]
23] Le
Le langage
langage Tcl
Tcl
www.scriptics.com
Tcl ("Tool Command Language") est un langage de script conçu pour être facile
à intégrer dans une application.
[URL
[URL 24]
24] Attendre—Automatiser
Attendre—Automatiser l'interaction
l'interaction avec
avec les
les programmes
programmes
expect.nist.gov
Une extension basée sur Tcl [ URL 23 ], expect vous permet de scripter l'interaction
avec des programmes. En plus de vous aider à écrire des mouches de commande (pour
exemple) récupérer des fichiers sur des serveurs distants ou étendre la puissance de votre shell,
expect peut être utile lors de l'exécution de tests de régression. Un graphique
version, expectk, vous permet d'envelopper des applications non graphiques avec un fenêtrage
l'extrémité avant.
[URL
[URL 25]
25] Espaces
Espaces TT
www.almaden.ibm.com/cs/TSpaces
De leur page Web : "T Spaces est un tampon de communication réseau avec
capacités de la base de données. Il permet la communication entre les applications et
périphériques dans un réseau d'ordinateurs et de systèmes d'exploitation hétérogènes. J
Spaces fournit des services de communication de groupe, des services de base de données,
Services de transfert de fichiers basés sur URL et services de notification d'événements."
[[ ]]
[URL
[URL 26]
26] javaCC—Compilateur-compilateur
javaCC—Compilateur-compilateur Java
Java
www.metamata.com/javacc
[URL
[URL 27]
27] Le
Le générateur
générateur d'analyseur
d'analyseur bison
bison
www.gnu.org/software/bison/bison.html
[URL
[URL 28]
28] SWIG
SWIG :: wrapper
wrapper simplifié
simplifié et
et générateur
générateur d'interface
d'interface
www.swig.org
SWIG est un outil de développement logiciel qui connecte des programmes écrits en C,
C++ et Objective-C avec une variété de langages de programmation de haut niveau
tels que Perl, Python et Tcl/Tk, ainsi que Java, Eiffel et Guile.
[URL
[URL 29]
29] Le
Le groupe
groupe de
de gestion
gestion d'objets,
d'objets, Inc.
Inc.
www.omg.org
Outils
Outils Unix
Unix sous
sous DOS
DOS
[URL
[URL 30]
30] Les
Les outils
outils de
de développement
développement UWIN
UWIN
www.gtlinc.com/Products/Uwin/uwin.html
Le package UWIN fournit des bibliothèques de liens dynamiques Windows (DLL) qui
émuler une grande partie de l'interface de la bibliothèque de niveau Unix C. En utilisant ceci
interface, GTL a porté un grand nombre d'outils de ligne de commande Unix vers
Les fenêtres. Voir aussi [ URL 31 ].
[URL
[URL 31
31 ]] Les
Les outils
outils Cygnus
Cygnus Cygwin
Cygwin
sourceware.cygnus.com/cygwin/
[URL
[URL 32]
32] Outils
Outils électriques
électriques Perl
Perl
www.perl.com/pub/language/ppt/
Outils
Outils de
de contrôle
contrôle du
du code
code source
source
[URL
[URL 33]
33] RCS—Système
RCS—Système de
de contrôle
contrôle de
de révision
révision
prep.ai.mit.edu
[URL
[URL 34]
34] CVS—Système
CVS—Système de
de versions
versions simultanées
simultanées
www.cvshome.com
Système de contrôle de code source disponible gratuitement pour Unix et Windows NT.
Étend RCS en prenant en charge un modèle client-serveur et un accès simultané à
des dossiers.
[URL
[URL 35]
35] Gestion
Gestion de
de la
la configuration
configuration basée
basée sur
sur les
les transactions
transactions Aegis
Aegis
http://www.canb.auug.org.au/~millerp/aegis.html
Un outil de contrôle de révision orienté processus qui impose des normes de projet
(par exemple, vérifier que le code enregistré réussit les tests).
[URL
[URL 36]
36] ClearCase
ClearCase
www.rational.com
[URL
[URL 37]
37] Intégrité
Intégrité de
de la
la source
source MKS
MKS
www.mks.com
[URL
[URL 38]
38] Gestion
Gestion de
de la
la configuration
configuration PVCS
PVCS
www.merant.com
Un système de contrôle de code source, très populaire pour les systèmes Windows.
[URL
[URL 39]
39] Visual
Visual SourceSafe
SourceSafe
www.microsoft.com
www.perforce.com
Autres
Autres outils
outils
[URL
[URL 41]
41] WinZip—Utilitaire
WinZip—Utilitaire d'archivage
d'archivage pour
pour Windows
Windows
www.winzip.com
Un utilitaire d'archivage de fichiers basé sur Windows. Prend en charge les formats zip et tar.
[URL
[URL 42]
42] Le
Le shell
shell ZZ
sunsite.auc.dk/zsh
Un shell conçu pour une utilisation interactive, même s'il s'agit également d'un script puissant
langue. De nombreuses fonctionnalités utiles de bash, ksh et tcsh ont été
incorporé dans zsh ; de nombreuses caractéristiques originales ont été ajoutées.
[URL
[URL 43]
43] Un
Un client
client SMB
SMB gratuit
gratuit pour
pour les
les systèmes
systèmes Unix
Unix
samba.anu.edu.au/pub/samba/
Samba vous permet de partager des fichiers et d'autres ressources entre Unix et Windows
systèmes. Samba comprend :
Articles
Articles et
et publications
publications
[URL
[URL 44]
44] La
La FAQ
FAQ comp.object
comp.object
www.cyberdyne-object-sys.com/oofaq2
[URL
[URL 45]
45] Programmation
Programmation extrême
extrême
www.XProgramming.com
Extrait du site Web : "Dans XP, nous utilisons une combinaison très légère de
pratiques pour créer une équipe capable de produire rapidement des produits extrêmement fiables,
logiciel efficace et bien factorisé. De nombreuses pratiques XP ont été créées et
testé dans le cadre du projet Chrysler C3, qui est une paie très réussie
système implémenté dans Smalltalk."
[URL
[URL 46]
46] Page
Page d'accueil
d'accueil d'Alistair
d'Alistair Cockburn
Cockburn
membres.aol.com/acockburn
Recherchez "Structurer les cas d'utilisation avec des objectifs" et utilisez des modèles de cas.
[URL
[URL 47]
47] Page
Page d'accueil
d'accueil de
de Martin
Martin Fowler
Fowler
ourworld.CompuServe.com/homepages/martin_fowler
[URL
[URL 48]
48] Page
Page d'accueil
d'accueil de
de Robert
Robert C.
C. Martin
Martin
www.objectmentor.com
[URL
[URL 49]
49] Programmation
Programmation orientée
orientée aspect
aspect
www.pare.xerox.com/csl/projects/aop/
[URL
[URL 50]
50] Spécification
Spécification JavaSpaces
JavaSpaces
java.sun.com/products/javaspaces
Un système de type Linda pour Java qui prend en charge la persistance distribuée et
algorithmes distribués.
[URL
[URL 51]
51] Code
Code source
source Netscape
Netscape
www.mozilla.org
[URL
[URL 52]
52] Le
Le fichier
fichier Jargon
Jargon
www.jargon.org
Eric S.Raymond
[URL
[URL 53]
53] Papiers
Papiers d'Eric
d'Eric S.
S. Raymond
Raymond
www.tuxedo.org/~esr
www.kde.org
[URL
[URL 55]
55] Le
Le programme
programme de
de manipulation
manipulation d'images
d'images GNU
GNU
gimp.org
Gimp est un programme librement distribué utilisé pour la création d'images, la composition,
et retouche.
[URL
[URL 56]
56] Le
Le projet
projet Demeter
Demeter
www.ccs.neu.edu/research/demeter
Divers
Divers
[URL
[URL 57]
57] Le
Le projet
projet GNU
GNU
www.gnu.org
La Free Software Foundation est une organisation caritative exonérée d'impôt qui collecte des fonds pour
le projet GNU. L'objectif du projet GNU est de produire une version complète, libre et
Système de type Unix. Bon nombre des outils qu'ils ont développés en cours de route ont
deviennent des standards de l'industrie.
[URL
[URL 58]
58] Informations
Informations sur
sur le
le serveur
serveur Web
Web
www.netcraft.com/survey/servers.html
Liens vers les pages d'accueil de plus de 50 serveurs Web différents. Certains sont
produits commerciaux, tandis que d'autres sont disponibles gratuitement.
Bibliographie
Bibliographie
[FBB + 99] Martin Fowler, Kent Beck, John Brant, William Opdyke et Don
Roberts. Refactoring : amélioration de la conception du code existant. Addison
Wesley Longman, Reading, MA, 1999.
[Hol78] Michael Holt. Puzzles et jeux mathématiques. Dorset Press, New York,
NY, 1978.
[Lak96] John Lakos. Conception de logiciels C++ à grande échelle. Addison Wesley
Longman, Reading, MA, 1996.
[LH89] Karl J. Lieberherr et Ian Holland. Assurer un bon style pour
programmes orientés objet. Logiciel IEEE, pages 38–48, septembre 1989.
[Mey96] Scott Meyers. C++ plus efficace : 35 nouvelles façons d'améliorer votre
Programmes et conceptions. Addison-Wesley, Reading, MA, 1996.
[Str35] James Ridley Stroop. Études des interférences dans les séries verbales
réactions. Journal de psychologie expérimentale, 18: 643–662, 1935.
[Vous95] Edward Yourdon. Gérer des projets pour produire assez bien
logiciel. Logiciel IEEE, mars 1995.
Annexe B. Réponses aux exercices
Exercer de l'orthogonalité
Exercer
1:
1:
Vous écrivez une classe appelée Split, qui divise les lignes d'entrée en
des champs. Laquelle des deux signatures de classe Java suivantes est la
c
Répondre
RépondreA notre façon de penser, la classe Split2 est plus orthogonal. Il
1:
1: se concentre sur sa propre tâche, divise les lignes et ignore les détails
comme d'où viennent les lignes. Non seulement cela
rendre le code plus facile à développer, mais cela le rend également plus
flexible. Split2 peut diviser les lignes lues à partir d'un fichier, généré par
une autre routine, ou transmis via l'environnement .
Exercer de l'orthogonalité
Exercer
22 ::
Ce qui conduira à une conception plus orthogonale : non modale ou modale
Boîtes de dialogue?
Répondre
RépondreSi c'est fait correctement, probablement sans mode. Un système qui utilise
22 :: les boîtes de dialogue non modales seront moins concernées par ce qui se passe
à un moment donné dans le temps. Il aura probablement un meilleur
infrastructure de communications intermodules qu'une infrastructure modale
système, qui peut avoir des hypothèses intégrées sur l'état de
le système - hypothèses qui conduisent à un couplage accru et
diminution de l'orthogonalité.
Exercer
Exercer de l'orthogonalité
33 ::
Qu'en est-il des langages procéduraux par rapport à la technologie objet ?
Répondre
RépondreLa low-tech à la rescousse ! Dessinez quelques caricatures avec des marqueurs sur un
44 :: tableau blanc : une voiture, un téléphone et une maison. Cela ne doit pas être
grand art; les contours en forme de bâton sont bons. Mettez des Post-it qui
décrire le contenu des pages cibles sur les zones cliquables. Comme
la réunion avance, vous pouvez affiner les dessins et
placement des Post-it .
Exercer
Exercer à partir des langues du domaine
55 ::
Nous voulons implémenter un mini-langage pour contrôler un simple
package de dessin (peut-être un système de graphiques de tortues). Le
le langage se compose de commandes à une seule lettre. Quelques commandes
sont suivis d'un seul chiffre. Par exemple, ce qui suit
'l e
W 2 # t
Implémentez le code qui parse ce langage. Ça devrait être
conçu pour qu'il soit simple d'ajouter de nouvelles commandes.
Répondre
RépondreParce que nous voulons rendre le langage extensible, nous allons faire
55 :: la table d'analyseur pilotée. Chaque entrée du tableau contient les
lettre de commande, un drapeau pour dire si un argument est requis,
et le nom de la routine à appeler pour gérer ce particulier
c
,Enfi
Exercer
Exercer à partir des langues du domaine
66 ::
Concevoir une grammaire BNF pour analyser une spécification temporelle. La totalité de la
el
Répondre
RépondreEn utilisant BNF, une spécification de temps pourrait être
66 ::
<eh
<a
<eh
<umin
<c
RépondreoN
Répondre
7:
7: Pour plus de clarté, nous ne montrons ici que le corps de l'analyseur. Regarder
à al
; un
Répondre
Répondre
8 :
Exercer
Exercer de l'estimation
99 ::
On vous demande "Qui a une bande passante plus élevée : un 1Mbps
ligne de communication ou une personne marchant entre deux
ordinateurs avec une bande complète de 4 Go dans leur poche ? »
mettrez-vous des contraintes sur votre réponse pour vous assurer que la portée
de votre réponse est-elle correcte ? (Par exemple, vous pourriez dire que le
le temps nécessaire pour accéder à la bande est ignoré.)
Répondre
RépondreNotre réponse doit reposer sur plusieurs hypothèses :
99 ::
• La bande contient les informations dont nous avons besoin pour être
transféré.
• Nous connaissons la vitesse à laquelle la personne marche.
• Nous connaissons la distance entre les machines.
Exercer
Exercer de l'estimation
dix:
dix:
Alors, qui a la bande passante la plus élevée ?
Répondre
RépondreSous réserve des mises en garde de la réponse 9 : Une bande de 49 Go contient 32 × 10
dix:
dix: bits, donc une ligne 1Mbps devrait pomper des données pour environ 32 000
secondes, soit environ 9 heures, pour transférer le montant équivalent
d'information. Si la personne marche à une vitesse constante de 3½ mph,
alors nos deux machines devraient être distantes d'au moins 31 miles
pour que la ligne de communication surpasse notre service de messagerie.
Sinon, la personne gagne.
Exercer
Exercer de la manipulation de texte
11
11 ::
Votre programme C utilise un type énuméré pour représenter l'un des
100 états. Vous aimeriez pouvoir imprimer l'état sous forme de chaîne
(par opposition à un nombre) à des fins de débogage. Écrire un scénario
q
oPr
RépondreoN
Répondre
11
11 ::
*/
*/
En utilisant le principe DRY, nous n'allons pas couper et coller ce nouveau fichier dans
notre code. Au lieu de cela, nous l'inclurons : le fichier plat est la source principale
de ces constantes. Cela signifie que nous aurons besoin d'un makefile pour
régénérer l'en-tête lorsque le fichier change. L'extrait suivant
p
Exercer
Exercer de la manipulation de texte
12
12 ::
A mi-chemin de l'écriture de ce livre, nous avons réalisé que nous n'avions pas
mettre la directive use strict dans beaucoup de nos exemples Perl.
Rédigez un script qui passe par le fichiers .pl dans un répertoire et
ajoute un
utiliser strict à la fin du bloc de commentaire initial pour tous
fichiers qui n'en ont pas déjà un. N'oubliez pas de conserver une sauvegarde de
tous les fichiers que vous modifiez.
tE
Exercer
Exercer de la conception par contrat
14:
14:
Qu'est-ce qui fait un bon contrat ? N'importe qui peut ajouter des conditions préalables et
postconditions, mais vous seront-elles utiles ? Pire encore, sera
ils font en fait plus de mal que de bien? Pour l'exemple ci-dessous
et pour ceux des Exercices 15 et 16, décidez si le
contrat spécifié est bon, mauvais ou laid, et expliquez pourquoi.
Prenons d'abord un exemple Eiffel. Ici, nous avons une routine pour
ajouter une chaîne à une liste circulaire doublement liée (rappelez-vous que
les préconditions sont étiquetées avec require et les postconditions avec
ég
Répondre
Répondre Cet exemple Eiffel est bon. Nous exigeons que les données non nulles soient
14:
14: passé, et nous garantissons que la sémantique d'une circulaire,
liste doublement liée sont honorés. Cela aide aussi à pouvoir trouver le
chaîne que nous avons stockée. Puisqu'il s'agit d'une classe différée, le véritable
la classe qui l'implémente est libre d'utiliser tout sous-jacent
mécanisme qu'il veut. Il peut choisir d'utiliser des pointeurs ou un
tableau, ou autre chose ; tant qu'il respecte le contrat, nous ne
se soucier .
Exercer
Exercer de la conception par contrat
16:
16:
Voici un fragment d'une classe de pile en Java. Est-ce un bon
c
Répondre
Répondre C'est un bon contrat, mais une mauvaise mise en œuvre. Ici le
16:
16: l'infâme "Heisenbug" [URL 52 ] dresse sa vilaine tête. Le
le programmeur vient probablement de faire une simplepop aufaute
lieu de frappe—
haut. Bien qu'il s'agisse d'un exemple simple et artificiel, les effets secondaires dans
les assertions (ou à n'importe quel endroit inattendu dans le code) peuvent être très
difficile à diagnostiquer.
Exercer
Exercer de la conception par contrat
17:
17:
Les exemples classiques de DEC (comme dans les exercices 14 à 16) montrent une
mise en œuvre d'un ADT (Abstract Data Type) - généralement un
pile ou file d'attente. Mais peu de gens écrivent vraiment ce genre de
classes de bas niveau.
Donc, pour cet exercice, concevez une interface vers un mixeur de cuisine. Il
sera éventuellement un système basé sur le Web, compatible avec Internet et basé sur CORBA
blender, mais pour l'instant nous avons juste besoin de l'interface pour le contrôler. Il
a dix réglages de vitesse (0 signifie éteint). Vous ne pouvez pas le faire fonctionner à vide,
et vous ne pouvez modifier la vitesse que d'une unité à la fois (c'est-à-dire
de 0 à 1, et de 1 à 2, et non de 0 à 2).
tin
Répondre
Répondre Nous allons montrer les signatures de fonction en Java, avec les pré- et
17:
17: postconditions étiquetées comme dans iContract .
oT
sEn
Répondre
Répondre Il y a 21 termes dans la série. Si vous avez dit 20, vous venez de
18:
18: a rencontré une erreur de clôture .
Répondre
Répondre Le 1er septembre 1752 n'avait que 19 jours. Cela a été fait pour
19:
19: synchroniser les calendriers dans le cadre du grégorien
Réformation.
2. Le répertoire a peut-être été supprimé par un autre
processus, vous n'êtes peut-être pas autorisé à le lire, &sb
peut être invalide - vous obtenez l'image.
3. Nous n'avons pas précisé les types de a et b. Opérateur
la surcharge aurait pu définir +, = ou ! = avoir
comportement inattendu. De plus, a et b peuvent être des alias pour le
même variable, donc la deuxième affectation écrasera
la valeur stockée dans le premier.
4. En géométrie non euclidienne, la somme des angles d'un
triangle ne totalisera
cartographié pas 180°.
sur la surface Pensez
d'une à un triangle
sphère.
5. Les minutes intercalaires peuvent avoir 61 ou 62 secondes.
6. Le débordement peut laisser le résultat
a + 1denégatif (cela peut
se produisent également en C et C++).
Répondre
RépondreNous avons choisi d'implémenter une classe très simple avec un seul statique
20:
20: méthode, TEST, qui imprime un message et une trace de pile si le
el
Exercer
Exercer à partir de Quand utiliser les exceptions
21:
21:
Lors de la conception d'une nouvelle classe de conteneur, vous identifiez les
conditions d'erreur possibles suivantes :
Répondre
RépondreLe manque de mémoire est une condition exceptionnelle, nous nous sentons donc
21:
21: ce cas (1) devrait soulever une exception .
Le cas (3) est plus problématique—si la valeur null est significative pour
la demande, alors il peut être à juste titre ajouté à la
récipient. Si, toutefois, cela n'a aucun sens de stocker des valeurs nulles, un
exception devrait probablement être levée.
Exercer
Exercer de Comment équilibrer les ressources
22:
22:
Certains développeurs C et C++ mettent un point d'honneur à définir un pointeur vers
NULL après avoir désalloué la mémoire à laquelle il fait référence. Pourquoi est-ce
une bonne idée?
Répondre
RépondreDans la plupart des implémentations C et C++, il n'y a aucun moyen de vérifier
22:
22: qu'un pointeur pointe réellement vers une mémoire valide. Un commun
l'erreur est de désallouer un bloc de mémoire et de référence qui
mémoire plus tard dans le programme. À ce moment-là, la mémoire indiquait
peut très bien avoir été réaffecté à une autre fin. Par
en définissant le pointeur sur NULL, les programmeurs espèrent empêcher
ces références malveillantes - dans la plupart des cas, déréférencer un NULL
le pointeur générera une erreur d'exécution.
Exercer
Exercer de Comment équilibrer les ressources
23:
23:
Certains développeurs Java mettent un point d'honneur à définir une variable objet
à NULL après avoir fini d'utiliser l'objet. Pourquoi est-ce un
bonne idée?
Répondre
RépondreEn définissant la référence sur NULL, vous réduisez le nombre de
23:
23: pointeurs vers l'objet référencé par un. Une fois que ce décompte atteint
personne1.h
personne1.h :: personne2.h
personne2.h ::
#icn d
"d c
c p
p
p
p
/
Répondre
RépondreUn fichier d'en-tête est censé définir l'interface entre le
24:
24: mise en œuvre correspondante et le reste du monde. Le
le fichier d'en-tête lui-même n'a pas besoin de connaître les composants internes du
Classe de date - il suffit de dire au compilateur que la
Le constructeur prend une Date comme paramètre. Donc, à moins que l'en-tête
le fichier utilise des dates dans les fonctions en ligne, le deuxième extrait fonctionnera
bien .
Quel est le problème avec le premier extrait ? Sur un petit projet, rien,
sauf que vous faites inutilement tout ce qui utilise un
La classe Personl inclut également le fichier d'en-tête pour Date. Une fois ce genre
d'utilisation devient courant dans un projet, vous constaterez bientôt que l'inclusion
un fichier d'en-tête finit par inclure la plupart du reste du
système - un sérieux frein aux temps de compilation.
RépondreaL
Répondre
25
25 :: l'appel est autorisé. Cependant, l'appel de amt.printFormat() ne l'est pas. Nous
ne "possède" pas amt et il ne nous a pas été transmis. On pourrait éliminer
eL
ev
Répondre
RépondrePuisque Colada crée et possède à la fois myBlender et myStuff, le
26:
26: les appels à addIngredients et elements sont autorisés.
Répondre
RépondreDans ce cas, processTransaction possède amt — il est créé sur le
27:
27: pile, acct est passé, donc setValue et setBalance sont
autorisé. Mais processTransaction ne possède pas qui, donc l'appel
who->name() est en violation. La loi de Déméter suggère
e
Exercer de la métaprogrammation
Exercer
28:
28:
Laquelle des choses suivantes serait mieux représentée comme
code dans un programme, et lequel en externe comme métadonnées ?
Répondre
RépondreIl n'y a pas de réponses définitives ici - les questions étaient
28:
28: destiné avant tout à vous donner matière à réflexion. Cependant, ceci est
ce que nous pensons :
2.
2. Un
Un support
support d'éditeur
d'éditeur pour
pour la
la mise
mise en
en évidence
évidence de
de la
la syntaxe
syntaxe de
de divers
divers
langues. Cela devrait être implémenté sous forme de métadonnées.
Vous ne voudriez pas avoir à pirater du code simplement parce que le
la dernière version de Java a introduit un nouveau mot-clé.
3. Le support d'un éditeur pour différents périphériques graphiques. Ce
serait probablement difficile à mettre en œuvre strictement
métadonnées. Vous ne voudriez pas alourdir votre candidature
avec plusieurs pilotes de périphériques uniquement pour en sélectionner un lors de l'exécution.
Vous
le pouvez
pilote cependant
et charger utiliser des le
dynamiquement métadonnées pour
code. Ceci est unspécifier
autre le nom de
bon argument pour conserver les métadonnées dans un
format lisible par l'homme ; si vous utilisez le programme pour configurer
un pilote vidéo dysfonctionnel, vous ne pourrez peut-être pas utiliser
le programme pour le remettre en place.
4. Une machine d'état pour un analyseur ou un analyseur. Cela dépend
sur ce que vous analysez ou scannez. Si vous analysez
certaines données définies de manière rigide par un organisme de normalisation et
est peu susceptible de changer sans un acte du Congrès, alors
codage dur c'est bien. Mais si vous êtes confronté à un plus
situation volatile, il peut être avantageux de définir l'état
tableaux en externe.
5. Exemples de valeurs et de résultats à utiliser dans les tests unitaires. La plupart
les applications définissent ces valeurs en ligne dans les tests
harnais, mais vous pouvez obtenir une meilleure flexibilité en déplaçant le
données de test—et la définition de la
résultats—hors du code lui-même.
Exercer
Exercer de C'est juste une vue
29:
29:
Supposons que vous disposiez d'un système de réservation de compagnie aérienne comprenant
el
On aimerait avoir un peu plus de souplesse dans le traitement des listes d'attente
passagers, et nous devons faire quelque chose à propos de ce gros
rapport—il prend trop de temps à s'exécuter. Utilisez les idées de cette section
pour repenser cette interface.
Répondre
RépondreNous allonsVol
prendre
et ajouter quelques méthodes supplémentaires pour
29:
29: maintenir deux listes d'auditeurs : une pour la notification de la liste d'attente,
e
Si nous essayons d'ajouter un passager et échouons parce que le vol est complet, nous pouvons,
éventuellement, mettez
Passager
le sur liste d'attente. Lorsqu'une place se libère,
waitList-Available sera appelé. Cette méthode peut alors choisir de
ajouter le
Passager automatiquement ou avoir un représentant de service
appeler le client pour lui demander s'il est toujours intéressé, ou quoi que ce soit. Nous
ont maintenant la flexibilité d'effectuer différents comportements sur un
par client.
Répondre
Répondre 1. Traitement d'images. Pour une planification simple d'une charge de travail
30:
30: parmi les processus parallèles, une file d'attente de travail partagée peut
être plus que suffisant. Vous voudrez peut-être envisager un
système de tableau noir s'il y a une rétroaction impliquée, c'est-à-dire,
si les résultats d'un morceau traité affectent d'autres morceaux,
comme dans les applications de vision industrielle ou la 3D complexe
transformations de distorsion d'image.
2. Calendrier de groupe. Cela pourrait être un bon ajustement. Tu peux
après les réunions planifiées et la disponibilité pour le
tableau noir. Vous avez des entités fonctionnant de manière autonome,
les commentaires sur les décisions sont importants et les participants
peuvent aller et venir.
Répondre
RépondreIl existe plusieurs problèmes potentiels avec ce code. D'abord, il
31:
31: suppose un environnement tty. Cela peut être bien si l'hypothèse
est vrai, mais que se passe-t-il si ce code est appelé à partir d'un environnement graphique
où ni stderr ni stdin n'est ouvert ?
Répondre
RépondrePOSIX strcpy n'est pas garanti de fonctionner pour les chaînes qui se chevauchent.
32:
32: Il peut arriver que cela fonctionne sur certaines architectures, mais uniquement en
hasard .
Exercer
Exercer de la programmation par coïncidence
33:
33:
Ce code provient d'une suite de traçage Java à usage général. Le
La fonction écrit une chaîne dans un fichier journal. Il réussit son test unitaire, mais
échoue lorsqu'un des développeurs Web l'utilise. Quelle coïncidence
s
Répondre
RépondreCela ne fonctionnera pas dans un contexte d'applet avec des restrictions de sécurité
33:
33: contre l'écriture sur le disque local. Encore une fois, quand vous avez le choix
de s'exécuter dans des contextes GUI ou non, vous voudrez peut-être vérifier
dynamiquement pour voir à quoi ressemble l'environnement actuel. Dans ce
cas, vous voudrez peut-être placer un fichier journal ailleurs que dans le
disque local s'il n'est pas accessible.
Répondre
RépondreDe toute évidence, nous ne pouvons pas donner de réponses absolues à cet exercice.
34:
34: Cependant, nous pouvons vous donner quelques indications.
Si vous constatez que vos résultats ne suivent pas une courbe régulière, vous
voudriez peut-être vérifier si une autre activité utilise certains de
la puissance de votre processeur. Vous n'obtiendrez probablement pas de bons chiffres sur un
système multi-utilisateurs, et même si vous êtes le seul utilisateur que vous pouvez trouver
que les processus d'arrière-plan prennent périodiquement des cycles
vos programmes. Vous pouvez également vérifier la mémoire : si le
l'application commence à utiliser l'espace d'échange, les performances chuteront.
Exercer
Exercer à partir de la vitesse de l'algorithme
35
35 ::
La routine ci-dessous imprime le contenu d'un arbre binaire.
En supposant que l'arbre est équilibré, à peu près combien d'espace de pile
la routine utilisera-t-elle lors de l'impression d'un arbre de 1 000 000 éléments ?
(Supposons que les appels de sous-programmes n'imposent aucune pile significative
s
Répondre
RépondreLa routine printTree utilise environ 1 000 octets d'espace de pile pour
35
35 :: la variable tampon. Il s'appelle récursivement descendre à travers
l'arborescence, et chaque appel imbriqué ajoute 1 000 octets supplémentaires à
empiler. Il s'appelle également lorsqu'il atteint les nœuds feuilles, mais quitte
immédiatement lorsqu'il découvre que le pointeur transmis est
Nous nous attendrions donc à ce que notre routine utilise environ 21 000 octets de
empiler.
Répondre
RépondreQuelques optimisations me viennent à l'esprit. Premièrement
p la
36:
36: la routine s'appelle sur les nœuds feuilles, seulement pour sortir car il n'y a pas
enfants. Cet appel augmente la profondeur de pile maximale d'environ
1 000 octets. Nous pouvons également éliminer la récursivité de la queue (la seconde
appel récursif), bien que cela n'affecte pas la pile dans le pire des cas
u
}
Exercer
Exercer à partir de la vitesse de l'algorithme
37:
37:
À la page 180, nous avons affirmé qu'un hachage binaire est O(lg(n)). Peux-tu
prouver cela ?
Répondre
RépondreIl y a plusieurs façons d'y arriver. L'une consiste à tourner le
37:
37: problème sur sa tête. Si le tableau n'a qu'un seul élément, nous ne
itérer autour de la boucle. Chaque itération supplémentaire double le
taille du tableau que nous pouvons rechercher. La formule générale de la
la taille du tableau est donc nm=, où
2 m est le nombre de
itérations. Si vous amenez des bûches à la base 2 de chaque côté, vous obtenez lg(n)
= lg(2 m), qui par définition des logs devient lg(n) = m.
Exercer de la refactorisation
Exercer
38:
38:
Le code suivant a évidemment été mis à jour plusieurs fois
au fil des ans, mais les changements n'ont pas amélioré sa structure.
eR
Répondre
RépondreNous pourrions suggérer ici une restructuration assez légère : assurez-vous
38:
38: que chaque test est effectué une seule fois, et faire tous les
c
apparaît à d'autres endroits du programme, nous devrions probablement
en faire une fonction. Nous n'avons pas pris la peine ici.
Nous avons ajouté un tableau rate_lookup, initialisé pour que les entrées
autres que le Texas, l'Ohio et le Maine ont une valeur de 1.
permet d'ajouter facilement des valeurs pour d'autres états dans le
avenir. Selon le modèle d'utilisation prévu, nous pourrions
veux faire le p
Exercer
Exercer de la refactorisation
39:
39:
La classe Java suivante doit prendre en charge quelques formes supplémentaires.
eR
c
Répondre
RépondreLorsque vous voyez quelqu'un utiliser des types énumérés (ou leurs
39:
39: équivalent en Java) pour distinguer les variantes d'un type,
ov
Exercer
Exercer de la refactorisation
40
40 ::
Ce code Java fait partie d'un framework qui sera utilisé
tout au long de votre projet. Refactorisez-le pour qu'il soit plus général et
plus facile à étendre à l'avenir.
p
Répondre
RépondreCe cas est intéressant. A première vue, il semble raisonnable qu'un
40
40 :: fenêtre doit avoir une largeur et une hauteur. Cependant, considérez
l'avenir. Imaginons que l'on veuille soutenir arbitrairement
fenêtres en forme (ce qui sera difficile si la classe Window sait
tout sur les rectangles et leurs propriétés) .
Notez que dans cette approche, nous avons utilisé la délégation plutôt que
sous-classement : une fenêtre n'est pas une forme "en quelque sorte" - une fenêtre "a-un"
forme. Il utilise une forme pour faire son travail. Vous trouverez souvent la délégation
utile lors de la refactorisation.
Exercer
Exercer de Code facile à tester
41
41 ::
Concevoir un gabarit de test pour l'interface du mélangeur décrit dans le
réponse à l'exercice 17. Écrivez un script shell qui effectuera une
test de régression pour le mélangeur. Vous devez tester de base
fonctionnalité, conditions d'erreur et aux limites, et tout
obligations contractuelles. Quelles sont les restrictions imposées à
changer la vitesse? Sont-ils honorés ?
Répondre
RépondreTout d'abord, nousprincipal pour
ajouterons unagir en tant que pilote de test unitaire. Il acceptera un
41
41 :: très petit langage simple comme argument : "E" pour vider le
emix
Vei
e
Les tests vérifient si des changements de vitesse illégaux sont détectés, si vous
essayez de vider le mélangeur en cours d'exécution, et ainsi de suite. Nous mettons cela dans le
makefile afin que nous puissions compiler et exécuter le test de régression simplement
t
Notez que nous avons la sortie de test avec 0 ou 1 afin que nous puissions l'utiliser comme partie
d'un test plus large également.
Exercer
Exercer de la fosse aux exigences
42:
42:
Parmi les exigences suivantes, lesquelles sont probablement de véritables exigences ? Reformulez ceux
qui ne sont pas pour les rendre plus utiles (si possible).
Répondre
Répondre 1. Cette affirmation ressemble à une exigence réelle : il peut y avoir
42:
42: contraintes imposées à l'application par son environnement.
2. Même s'il s'agit d'une norme d'entreprise, ce n'est pas un
exigence. Il serait mieux indiqué comme "L'arrière-plan de la boîte de dialogue
doit être configurable par l'utilisateur final. Comme expédié, la couleur sera
gris." Encore mieux serait la déclaration plus large "Tous les visuels
les éléments de l'application (couleurs, polices et langues) doivent être
configurable par l'utilisateur final."
3. Cette déclaration n'est pas une exigence, c'est une architecture. Lorsqu'ils sont confrontés
avec quelque chose comme ça, vous devez creuser profondément pour savoir ce que le
l'utilisateur pense.
4. L'exigence sous-jacente est probablement quelque chose de plus proche de "La
le système empêchera l'utilisateur de faire des entrées invalides dans les champs,
et avertira l'utilisateur lorsque ces entrées seront effectuées."
5. Cette déclaration est probablement une exigence stricte.