J'ai lu divers articles sur la gestion des exceptions, mais je ne l'ai pas compris, j'ai donc élargi ma perspective. Résumez du point de vue «comment utiliser les exceptions dans le système pour améliorer la qualité».
Identifiez les caractéristiques de l'exception.
L'essence des exceptions réside dans la relation entre l'appelant et le générateur d'exceptions. C'est juste une fonction pour informer l'appelant d'un message. Il est nécessaire de concevoir pour suivre toutes les causes, telles que les programmes à distance et d'autres destinations de coopération.
Si vous l'utilisez tel quel
Réfléchissez à la façon de l'implémenter pour que le développeur n'ait pas à lire le code autant que possible. Le point de vue de l'enquête sur les causes est le suivant.
--Bug ou échec (informations généralement manquantes)
Organisez en fonction de l'exemple d'implémentation suivant. Certaines méthodes sont omises par souci de brièveté.
//Classe de virement bancaire
class BankTransfer implements BankProcess {
//Renseignements sur les remises
Account from; //Compte source de remise
Account to; //Compte de remise
long amount; //Montant de la remise
//Traitement des transferts
@override
void process() throws BankException {
try {
from.withdrawal(amount); //Traitement des retraits
to.deposit(amount); //Traitement des dépôts
log("transfer completed."); //Sortie de journal
} catch (TransferException e) {
//Échec du transfert d'argent
log("transfer failed."); //Sortie de journal
rollback();
log("rollback completed.");
throw e;
}
}
}
//Traitement du compte
abstract class Account {
int no; //numéro de compte
//Traitement des dépôts
void deposit(long amount) {
try {
//Hypothèse qu'une exception se produira
deposit(amount);
} catch (ConnectionTimeoutException e) { //2.2.3 Transport (qui est mauvais)
//La connexion a échoué et le système de gestion de compte n'est pas disponible
var error = new TransferException(e); //2.2 Structure avec exceptions logiques
error.setNo(this.no); //2.1 Utilisation d'informations supplémentaires
throw error;
}
}
//Traitement des retraits
void withdrawal(long amount) {
try {
//Hypothèse qu'une exception se produira
withdrawal();
} catch (ConnectionTimeoutException e) { //2.2.3 Transport (qui est mauvais)
//La connexion a échoué et le système de gestion de compte n'est pas disponible
var error = new TransferException(e); //2.2 Structure avec exceptions logiques
error.setNo(this.no); //2.1 Utilisation d'informations supplémentaires
throw error;
}
}
//Abstrait parce que chaque compte a une banque différente
abstract void deposit(int no, long amount);
abstract void withdrawal(int no, long amount);
}
Lorsqu'une exception est levée, les informations de la méthode qui implémente l'instruction catch peuvent être collectées. Définissez les données associées du début de la méthode au point d'occurrence de capture en tant qu'exception. Collectez les données pertinentes jusqu'au bout.
Résolu les points de vue suivants.
--Identification du lieu de l'événement --Informations pour la reproduction
Des points de vue suivants, nous fournirons les informations nécessaires à la suite de l'enquête sur la cause.
--Bug ou obstacle
Après cela, nous utiliserons le "traitement des virements bancaires" facile à imaginer comme exemple et l'implémenterons en utilisant des exceptions logiques. Concentrez-vous sur la partie implémentation de la gestion des exceptions.
Le nom de la classe d'exception vous informe que "le traitement a échoué", mais le nom de la classe agit comme sujet. Les classes d'exceptions suivantes montrent l'arborescence d'héritage.
RuntimeException Exception non vérifiée
└── BankException Échec bancaire
└── NameResolveException Le processus d'adressage du nom a échoué (non pertinent ci-dessous)
└── Le traitement du transfert TransferException a échoué
Afin de le juger comme un bug, il peut être résolu en établissant une règle pour attraper les exceptions. Pour le dire autrement, il est important de savoir comment identifier l'exception attendue. Pour cela, dans le cas d'une exception abstraite (SQLException, etc.), il est nécessaire de restreindre les instances d'exception à traiter par les informations supplémentaires de l'exception.
--Bug: Exception non interceptée --Echec: exception logique (suggère un événement attendu)
Dans l'enquête sur la cause, les choses nécessaires sont isolées, mais les personnages généralement suspectés sont les suivants.
--Utilisateur (peut-être que l'opération est mauvaise) --Opérateur (La configuration / opération n'est-elle pas mauvaise?) --Autres systèmes de composants connectés (DB, autres services Web, etc.)
Ce problème peut être identifié par l'exception physique (provoquant l'exception) interceptée. Un exemple est présenté ci-dessous.
--Exceptions qui se produisent au point de contact avec les opérations utilisateur / opérateur
Vous pouvez librement notifier la méthode supérieure. Il est également bon de le définir comme information supplémentaire dans l'exception logique, Vous pouvez également créer une nouvelle classe OperatorException (une classe qui suggère une erreur d'opération) et augmenter le nombre de classes d'exception abstraites. Vous pouvez également l'écrire dans le message. (Parce que la connexion a échoué, XX a échoué.)
En conséquence, une trace de pile est ajoutée et le résultat de l'enquête est terminé. Un exemple de l'exemple ci-dessus sera décrit.
L'exception qui se produit doit être interceptée quelque part et traitée d'une manière ou d'une autre. Le motif de ce concept de conception est "de faire usage d'exceptions dans le système pour améliorer la qualité", j'ai donc pensé que les règles suivantes étaient nécessaires.
Il y a peu de raisons d'utiliser "Exception" pour intercepter toutes les exceptions.
--Pour ne pas arrêter le système --Lorsque la bibliothèque fournie, etc. la force (lorsqu'elle n'est pas froide)
Les cas qui peuvent être mis en œuvre sont indiqués ci-dessous.
Certaines choses, comme les serveurs d'applications Web, gèrent correctement les exceptions, Dans ce cas, vous n'êtes pas obligé de tout attraper. Il est nécessaire de vérifier le comportement lorsque WAS détecte une exception.
Si vous interceptez toutes les exceptions indiquées dans la version 3.1, vous détecterez également les exceptions physiques inattendues. Par conséquent, il est nécessaire d'enregistrer le rapport de bogue au développeur sous une forme cohérente. Les méthodes possibles sont les suivantes.
--Enregistrer dans le fichier journal --Afficher sur un écran Web, etc. --Envoyer à l'outil ou à la plate-forme de collecte de journaux
Les exceptions logiques (exceptions attendues) et les exceptions physiques (exceptions inattendues) peuvent être facilement distinguées. La généralisation et la spécialisation des classes d'exception prennent vie ici. L'exemple de code est illustré ci-dessous.
try {
var job = new BankTransfer(from, to);
job.process();
} catch (BankException e) {
//Traitement des exceptions attendues
} catch (RuntimeException e) {
//Gérer les exceptions inattendues
}
Si vous ne créez pas votre propre classe d'exceptions, vous ne pouvez pas déterminer s'il s'agit d'un bogue ou d'un échec en fonction du nom de la classe d'exception qui s'est produite. De plus, il n'est pas possible d'obtenir des informations pour la reproduction. Par conséquent, en réalisant les choses suivantes, il est possible de trouver des informations efficaces pour identifier la cause à un stade précoce.
--Créez votre propre classe d'exceptions et concevez-la de manière structurée
Recommended Posts