[JAVA] Je souhaite concevoir une structure pour la gestion des exceptions

Motivation

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é».

1. À propos des exceptions

1.1. Caractéristiques

Identifiez les caractéristiques de l'exception.

1.2. Limites d'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

2. Recherchez la cause par la gestion des exceptions

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);
}

2.1. Utiliser des informations supplémentaires lors de la levée d'une exception

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

2.2. Structure avec exceptions logiques

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.

2.2.1 Arbre d'héritage des classes d'exception

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é

2.2.2. Bug ou échec

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)

2.2.3 Isolement (qui est mauvais)

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é.)

2.2.4 Résultats de l'enquête

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.

3. Que faire avec les exceptions

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.

3.1. Règles de principe pour intercepter toutes les exceptions

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.

3.2. Signaler un bug au développeur

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
}

4. Résumé

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

Je souhaite concevoir une structure pour la gestion des exceptions
Je souhaite développer une application web!
Je veux écrire un joli build.gradle
Je veux écrire un test unitaire!
[Ruby] Je veux faire un saut de méthode!
Je veux écrire une simple répétition d'une chaîne de caractères
Je veux appeler une méthode d'une autre classe
Je souhaite surveiller un fichier spécifique avec WatchService
Je souhaite définir une fonction dans la console Rails
Je veux cliquer sur une broche GoogleMap dans RSpec
Je souhaite créer une annotation générique pour un type
Je souhaite ajouter une fonction de suppression à la fonction de commentaire
Je veux convertir des caractères ...
[Java] Je souhaite convertir un tableau d'octets en un nombre hexadécimal
Je veux trouver un chemin relatif dans une situation où Path est utilisé
Je souhaite implémenter une fonction d'édition des informations produit ~ part1 ~
Je souhaite créer un modèle spécifique d'ActiveRecord ReadOnly
Je veux faire une liste avec kotlin et java!
Je veux appeler une méthode et compter le nombre
Je veux créer une fonction avec kotlin et java!
Je souhaite créer un formulaire pour sélectionner la catégorie [Rails]
Même en Java, je veux afficher true avec un == 1 && a == 2 && a == 3
Je veux donner un nom de classe à l'attribut select
Je veux créer un fichier Parquet même en Ruby
Je souhaite utiliser FireBase pour afficher une chronologie comme Twitter
[Rails] Comment écrire la gestion des exceptions?
Gestion des exceptions avec une interface fluide
Je souhaite rechercher de manière récursive des fichiers dans un répertoire spécifique
Je veux créer un bouton avec un saut de ligne avec link_to [Note]
Je souhaite ajouter une fonction de navigation avec ruby on rails
Je souhaite utiliser le balayage arrière sur un écran qui utilise XLPagerTabStrip
Je veux extraire entre des chaînes de caractères avec une expression régulière
[Rails] Je souhaite envoyer des données de différents modèles dans un formulaire
Je souhaite éliminer les messages d'erreur en double
Je veux créer une application ios.android
Je souhaite sélectionner plusieurs éléments avec une disposition personnalisée dans la boîte de dialogue
Je souhaite utiliser DBViewer avec Eclipse 2018-12! !!
Même en Java, je veux afficher true avec un == 1 && a == 2 && a == 3 (édition PowerMockito)
Je voudrais résumer Apache Wicket 8 car c'est une bonne idée
Je souhaite installer PHP 7.2 sur Ubuntu 20.04.
Je souhaite créer un SNS Web sombre avec Jakarta EE 8 avec Java 11
Gestion des exceptions
Je souhaite afficher un PDF chinois (coréen) avec des rapports fins
Je veux arrêter complètement les mises à jour Java
Je veux utiliser @Autowired dans Servlet
Je veux ForEach un tableau avec une expression Lambda en Java
Je souhaite cibler les champs statiques sur @Autowired
Je veux faire du développement d'équipe à distance
"Professeur, je souhaite implémenter une fonction de connexion au printemps" ① Hello World
Exception de traitement des exceptions