30 votes

Renvoyer un résultat avec plusieurs valeurs en mode Java

J'ai l'habitude de développer en Python, mais pour des raisons professionnelles ont à le faire en Java. Je suis confronté à une tâche qui serait trivial en Python, et j'aimerais avoir quelques conseils sur la façon de gérer cela en Java de la bonne façon.

J'ai besoin d'analyser une durée de chaîne. Il peut être en millisecondes (235ms) ou secondes (32s). Et il peut aussi être "< 1ms" comme un cas spécial.

L'analyse se produit au moins trois fois dans le code, donc je tiens à les séparer en une méthode. Mais mon code n'a besoin de savoir, non seulement la valeur résultante de la sp, mais aussi de savoir s'il était en ms ou s et si c'était <1ms (0 est une valeur différente).

En Python, je voudrais juste revenir un n-uplet:

return (value_in_milliseconds,is_in_seconds,is_under_1ms)

En C je voudrais définir une structure de ces trois valeurs et le retourner. En Pascal, je voudrais définir un enregistrement.

En Java, je ne peux pas rendre un n-uplet et je ne peux pas définir un dossier de sorte que dois-je faire?

La seule chose que je peux penser à est de créer une classe représentant une valeur de durée. Le constructeur serait de prendre la chaîne et de l'analyser. La classe aurait champs: int millisecondes, boolean inSeconds, boolean, en vertu de 1ms .

Mais cela sonne terriblement lourd - est-il une meilleure solution?

23voto

ErikE Points 18233

Ne passez pas autour d'un ensemble d'indicateurs qui doivent être compatibles entre eux afin de faire un état cohérent. Que faire si is_in_seconds et is_under_1ms sont à la fois true? Et pourquoi une variable qui contient le mot milliseconds jamais être interprétées comme des secondes? Comment mal-à la recherche qui seront dans le code. Mal-à la recherche de code n'est pas bon si vous ne pouvez rien faire à ce sujet: nous sommes censés écrire de code dont l'apparence de véracité/fausseté correspond à la réalité-le Principe de moindre Étonnement appliqués au code, et peut-être même le noyau de Succès pour la suite des développeurs dont le cerveau va exploser sur que.

Cela ressemble peut-être un peu de la Primitive Obsession odeur de code/antipattern, peut-être à partir de votre Python à l'arrière-plan? (Je sais rien à propos de Python, donc n'hésitez pas à négliger cette supposition.)

Solution: faire un vrai nom de domaine au niveau de l'objet que représente l'idée d'une durée approximative.

Une implémentation possible de:

  1. Créer un DurationScale enum qui a les membres de l' Second, Millisecond, SubMillisecond.

  2. Créer une classe ApproximateDuration, qui prend un duration entier et un durationScale valeur d'enum.

  3. Maintenant utiliser cet objet dans votre code. Si vous avez besoin de la somme d'une série de ces durées, faire une classe qui sait comment interpréter chacun et de les additionner. Ou ajouter des méthodes de cette classe.

Une alternative à un concept comme DurationScale pourrait être MarginOfError qui peut être exprimé dans certains arbitraire nombre de millisecondes, lui-même. Cela pourrait vous permettre d'utiliser une stricte formule mathématique afin d'augmenter la marge d'erreur d'une manière appropriée comme vous somme différente ApproximateDuration ensemble des objets dans un nouveau ApproximateDuration objet.

Remarque: Vous pouvez voir quelques - poursuite de la discussion sur pourquoi je vous recommande cette approche.

La mise en œuvre de partir vous installer sur est aussi une bonne façon de le gérer, où vous déclarez explicitement les limites inférieure et supérieure:

public final class ApproximateDuration {
   private final int lowMilliseconds;
   private final int highMilliseconds;

   public ApproximateDuration(int lowMilliseconds, int highMilliseconds) {
      this.lowMilliseconds = lowMilliseconds;
      this.highMilliseconds = highMilliseconds;
   }

   public int getLowMilliseconds() {
      return lowMilliseconds;
   }

   public int getHighMilliseconds() {
      return highMilliseconds;
   }
}

Notez que le fait de mettre le mot Milliseconds dans les variables et les noms de propriétés est importante, comme l'est l'immuabilité de cette classe.

20voto

jnbbender Points 391

Ce n'est pas différent d'une structure C, mais au moins, vous hériterez de Object

 class Blah {
   public String value_in_milliseconds;
   public String is_in_seconds;
   public String is_under_1ms;
}
 

14voto

maszter Points 3213

Définissez votre propre classe ou utilisez par exemple apache commons :

 return Triple.of(value_in_milliseconds, is_in_seconds, is_under_1ms);
 

8voto

Roshan Points 397

J'ai essayé avec un exemple ci-dessous de passer un Object[] place, en gardant les choses simples:

 public class MultiWayTest
{
    public static Object[] send() {
        return new Object[] { 1002322, false, true };
    }

    public static void main(String[] arg) {
        Object[] recieve=send();
    }
}
 

Vous avez peut-être remarqué la déclaration return new Object[] { 1002322, false, true };

J'espère que ça t'as aidé

6voto

meriton Points 30447

Personnellement, je ferais:

 class Duration {
    final int millis;
    final boolean specifiedInSeconds;
    final boolean under1ms;

    Duration(String s) {
        // parsing logic
    }
}
 

Cette solution est raisonnablement courte, permet au compilateur de détecter les fautes de frappe dans les noms de champs, encapsule l'invariant selon lequel les booléens ne peuvent pas être tous les deux définis, et peuvent être partagés en toute sécurité avec un autre code sans risquer des alias de bogues .

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