3 votes

Existe-t-il un modèle de conception de type réussite/échec ?

Je ne suis pas tout à fait sûr du terme officiel pour ce type de schéma/problème, mais voici ce à quoi je suis confronté :

J'ai une opération qui est assez importante. Elle peut soit réussir, soit échouer. Chaque réussite ou échec entraîne soit le résultat de l'opération réussie, soit des informations sur la raison de l'échec de l'opération. J'ai du mal à architecturer cette fonction "correctement".

class Pass{
    int someGoodStuff;
    double someOtherGoodStuff;
}

class Fail{
    String failureMsg;
    float howMuchOperationWasOffBy;
}

class Operator{
    public ??? operation(){
    }
}

Approche 1 : Les états d'échec sont comme des exceptions. Il faut les lancer. Cela me permet d'inclure l'information sur l'échec et de faire en sorte que le type de retour soit simplement Pass. Cependant, ces états d'échec ne sont pas des erreurs de langage de programmation, mais des erreurs de logique commerciale. Cette approche me pose deux problèmes : d'une part, elle confond les échecs de la logique d'entreprise avec les erreurs Java réelles (ce qui semble erroné) et d'autre part, elle détourne le flux d'exécution normal sans raison valable.

Approche 2 : Les fonctions en java aiment retourner un seul type d'objet, donc que Pass et Fail implémentent tous les deux une interface Result, et que le type de retour de la fonction soit celui-là.

interface Result{...}
class Pass implements Result{...}
class Fail implements Result{...}
class Operator{
    public Result operation(){...}
}

Cependant, les états de réussite et d'échec que la fonction renvoie sont complètement différents. Ils n'ont que peu ou pas de variables ou de fonctions qui se chevauchent. Cela semble erroné et me réduit à devoir instanceof toutes les informations importantes des réussites et des échecs.

Approche 3 : Une sorte d'objet d'union qui peut être soit un succès, soit un échec (mais pas les deux).

class Result{
    public Pass pass=null;
    public Fail fail=null;
}

class Operator{
    public Result operation(){...}
}

Cela a l'avantage que je peux dire des choses comme

Result result=op.operation();
if (result.succeed()){
    doStuffWithPass(result.getPass());
}else{
    doStuffWithFail(result.getFail());
}

C'est en gros ce que je faisais avec instanceof, mais en plus joli ; le code ressemble maintenant à ce que l'on pourrait attendre de lui. Il est clair à suivre.

Cependant, Java ne dispose pas de véritables types d'Union. Je dois m'assurer que personne n'essaie accidentellement de manipuler les variables pass d'un Result fail ou vice versa. De plus, toutes les méthodes que j'appelle sur le type union doivent être prédites pour déterminer s'il s'agit d'un succès ou d'un échec (cette branche If doit soudainement être présente partout).

Enfin, bien que ce ne soit pas encore un réel problème, je pense qu'un tel modèle alloue de l'espace à la fois pour un succès et un échec pour chaque résultat, alors que je sais qu'il ne peut s'agir que de l'un d'entre eux (c'est-à-dire qu'il devrait occuper un espace égal à Max(space(Pass),space(Fail)) )

Aucune de ces approches ne semble parfaite. J'ai l'impression qu'il devrait y avoir un modèle pour résoudre ce genre de problème. En existe-t-il un ?

1voto

Naresh Bharadwaj Points 101

Dans ce cas, l'approche par l'erreur semble être la meilleure.

Raisons

  1. Vous pouvez créer plusieurs exceptions personnalisées pour plusieurs types et lorsque quelque chose d'anormal se produit. Par cette approche, vous vous assurez qu'à chaque fois que quelque chose de mauvais se produit, votre programme renvoie le contrôle avec l'erreur spécifiée.

  2. En tant que type de retour, vous pouvez renvoyer votre résultat avec une valeur spécifique. Ainsi, lorsque votre programme renvoie quelque chose, il semble fonctionner ou passer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X