Comment savez-vous que vous écrivez le code le plus robuste possible sans trop d'ingénierie?
Je pense trop à tous les chemins possibles que mon code peut emprunter, ce qui est parfois une perte de temps. Cela dépend du type de programme que vous écrivez, mais je ne veux pas trop utiliser mon temps pour prendre en compte des situations qui ne se produiront jamais.
self-improvement
programming-practices
Fran Sevillano
la source
la source
Réponses:
Que considérez-vous comme un code robuste? Un code déjà évolutif et si puissant qu’il peut faire face à toutes les situations? Faux, personne ne peut prédire l'avenir! Et encore une fois, parce que ça va être un gâchis compliqué et impossible à maintenir.
Je respecte divers principes: YAGNI (encore) et KISS , pour ne pas écrire de code inutile. Cela empêche également efficacement l'ingénierie. Je refactorise l'application lorsque des extensions sont nécessaires. Les outils de refactoring modernes vous permettent de créer assez facilement des interfaces et d’échanger des implémentations lorsque vous en avez besoin.
Ensuite, j'essaie de rendre le code que j'écris aussi robuste que possible, ce qui implique d'éliminer autant de chemins que le programme peut emprunter (et aussi d'états) que possible et un peu de programmation spartiate . Les fonctions / méthodes "atomiques" qui ne reposent pas sur des états externes ou du moins ne laissent pas le programme dans un état inconsistant s’avèrent bien utiles. Si vous le faites bien, il est également très peu probable que vous finissiez avec du code spaghetti, ce qui est également une bénédiction pour la facilité de maintenance. De plus, dans la conception orientée objet, les principes SOLID constituent un excellent guide pour un code robuste.
J'ai vraiment découvert qu'il est souvent possible de réduire la complexité, par exemple des explosions combinatoires de chemins ou d'états de programme, en réfléchissant profondément à la manière dont vous pourriez le concevoir comme le chemin le plus direct possible. Essayez de garder les combinaisons possibles au minimum en choisissant le meilleur ordre de vos sous-routines et en les concevant à cet effet.
Le code robuste est la plupart du temps un code simple et propre, mais la simplicité est un trait difficile à atteindre. Pourtant, vous devriez vous efforcer de l'obtenir. Écrivez toujours le code le plus simple possible et n’ajoutez de la complexité que lorsque vous n’avez pas le choix.
La simplicité est robuste, la complexité est fragile.
La complexité tue.
la source
J'essaie de garder un équilibre en me concentrant sur
C'est une zone frontalière floue - parfois, je réussis à faire un travail inutile, parfois, je ne fais pas quelque chose qui s'avère nécessaire par la suite. Si les échecs ne sont pas importants, je vais bien. En tout cas, je m'efforce d'apprendre de mes erreurs.
la source
La différence entre une ingénierie robuste et une ingénierie excessive est la différence entre le traitement en douceur de tous les cas d'utilisation possibles, même les cas d'utilisation bizarres et marginaux qui NE DEVRAIENT PAS se produire. Lorsque je dis gracieusement, l'utilisateur entre un cas d'exception bizarre ou se retrouve dans une situation qui appelle une fonctionnalité non prise en charge ou non spécifiée qui n'a pas été définie et le code se ferme normalement sans provoquer de panne ou informer l'utilisateur de fonctionnalités non prises en charge.
La suringénierie, par contre, peut tomber dans le domaine de la mise en œuvre complète de fonctionnalités inutiles ou non sollicitées (certaines fonctionnalités demandées par le client ne sont jamais demandées!) OU elles peuvent être définies en dérivant une conception trop complexe ou trop complexe. code pour traiter un problème relativement simple.
la source
1) Obtenir les exigences.
2) Écrivez le code minimum pour répondre aux exigences. Si quelque chose est ambigu, faites une supposition éclairée. Si elle est super ambiguë, revenir à 1.
3) envoyer à tester.
4) Si les testeurs disent que c'est bon, documentez l'approbation. Si quelque chose ne va pas, retournez à 1.
Concentrez-vous sur les tests et non sur les tests. Si vous n'avez pas de testeurs, procurez-vous des testeurs! Ils sont essentiels non seulement pour vérifier l'exactitude du code, mais pour tout le processus de développement.
la source
En premier lieu, gardez les données normalisées (non redondantes) autant que vous le pouvez. Si les données sont entièrement normalisées, aucune mise à jour des données ne peut les rendre incohérentes.
Vous ne pouvez pas toujours garder les données normalisées, autrement dit, vous ne pourrez peut-être pas éliminer la redondance. Dans ce cas, les états peuvent être incohérents. La chose à faire est alors de tolérer l’incohérence et de la réparer périodiquement à l’aide d’un programme quelconque qui la corrige et la corrige.
Il existe une forte tendance à essayer de gérer la redondance de manière stricte au moyen de notifications. Celles-ci sont non seulement difficiles à vérifier, mais peuvent également entraîner de graves problèmes d' efficacité. (Une partie de la tentation d'écrire des notifications est due au fait qu'elles sont pratiquement encouragées en POO.)
En général, tout ce qui dépend de la chronologie des événements, des messages, etc., devient vulnérable et nécessite des tonnes de codage défensif. Les événements et les messages sont caractéristiques des données redondantes, car ils communiquent les modifications d'une partie à une autre, en essayant d'éviter les incohérences.
Comme je l'ai dit, si vous devez avoir une redondance (et les chances sont assez bonnes, vous devez), il est préférable de pouvoir a) tolérer et b) le réparer. Si vous essayez d'éviter les incohérences uniquement au moyen de messages, de notifications, de déclencheurs, etc., il vous sera très difficile de les rendre robustes.
la source
des erreurs se produiront en cours de route, mais elles seront (heureusement) localisées et elles apparaîtront (dans la plupart des cas) très tôt dans les tests. L’autre avantage de la réutilisation est que le client / appelant peut enregistrer la plupart des erreurs de vérification / échafaudage en utilisant celles apportées par l’implémentation.
vos tests doivent ensuite définir les capacités de votre programme et leur robustesse - continuez à ajouter des tests jusqu'à ce que vous soyez satisfait des taux de réussite et des entrées; améliorer, étendre et fortifier au besoin.
la source
Je fais cette distinction en écrivant du code avec un comportement bien défini, mais pas nécessairement optimal, pour des passes d'exécution très improbables. Par exemple, lorsque je suis à peu près sûr (prouvé, mais non testé) qu'une matrice sera définie positive, j'insère une assertion ou une exception dans le programme pour tester l'état, mais je n'écris pas son propre chemin de code. De ce fait, le comportement est défini, mais sous-optimal.
la source
Robustesse: Mesure dans laquelle un système continue de fonctionner en présence d'entrées non valides ou de conditions environnementales stressantes. (Code complet 2, p464)
La question importante ici est de vous demander à quel point la robustesse est importante pour vous. Si vous êtes Facebook, il est primordial que votre site Web continue de fonctionner lorsqu'une personne entre des caractères spéciaux dans l'entrée et que votre serveur reste opérationnel lorsque 100 millions d'utilisateurs sont connectés simultanément. Si vous écrivez un script pour effectuer une opération courante que vous seul faites, vous ne vous en souciez pas beaucoup. Entre les deux il y a beaucoup de niveaux. L'une des compétences importantes qu'un développeur doit acquérir est de juger de la robustesse dont vous avez besoin.
Le principe de YAGNI s'applique à l'ajout de fonctionnalités dont un programme pourrait avoir besoin. Mais ce principe ne s'applique pas à la robustesse. Les programmeurs ont tendance à surestimer la probabilité qu'une extension donnée soit nécessaire (surtout s'il s'agit d'une solution cool), mais ils sous-estiment la probabilité que les choses tournent mal. De plus, s'il s'avère qu'une fonctionnalité omise est nécessaire après, le programmeur peut l'écrire ultérieurement. S'il s'avère qu'un contrôle d'erreur omis est nécessaire, le dommage peut être causé.
Par conséquent, il est préférable de ne pas vérifier les conditions d'erreur inhabituelles. Mais il y a un équilibre. Certaines des choses à considérer dans cet équilibre:
N'oubliez pas que les gens peuvent et voudront essayer d'utiliser votre programme de manière inattendue. C'est mieux si quelque chose de prévisible se produit quand ils le font.
Comme dernière ligne de défense, utilisez l'assertion ou l'arrêt. Si vous rencontrez un problème qui ne vous permet pas de résoudre le problème, fermez le programme. C'est généralement mieux que de laisser le programme continuer et faire quelque chose d'imprévisible.
la source