Question

Quelle est la meilleure pratique pour la spécification des indicateurs dans une méthode en Java?

J'ai vu SWT l'aide d'int comme bitfields, comme:

(exemple partiellement de "Effective Java, 2nd Ed." page 159):

public class Text {
  public static final int STYLE_BOLD = 1 << 0; // 1
  public static final int STYLE_ITALIC = 1 << 1; // 2

  void printText(String text, int flags) {

  }
}

et votre appel du client ressemble à:

printText("hello", Text.STYLE_BOLD | Text.STYLE_ITALIC);

..mais c'est pas recommandée, car vous pouvez mixtes drapeaux (int valeur) de différentes classes d'ensemble sans compilateur vérifie.

Dans le même livre ("Effective Java"), je vois l'utilisation de EnumSet, mais alors votre appel utilisateur devient:

printText("hello", EnumSet.of(Style.Bold, Style.ITALIC));

Je trouve que c'est un peu verbeux et je préfère l'élégance de SWT.

Est-il une autre solution ou est-ce fondamentalement, les deux saveurs que vous devez choisir?

Était-ce utile?

La solution

Je suppose que vous avez frappé un mur.Je ne vois aucune autre option.Java est verbeux c'est un fait.Dans des situations comme celle-ci, j'aime habituellement une variable locale pour rendre le code plus lisible.Vous pouvez faire cela,

EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.ITALIC);
printText("hello", styles);

Autres conseils

Si vous voulez bits indicateurs de style, Java les enveloppe dans un BitSet.Il a été autour depuis des siècles, mais peu de personnes prennent la peine de l'utiliser (préférant l'incorporation de C bit de style de manutention dans ints).

L'api pour BitSet peuvent être trouvés ici.

Couplé avec quelques bien choisi statique ints, il fait très bien jusqu'à ce que vous commencer à entrer dans la vérification et le réglage des bits multiples en un seul passage.

Je vous informe que vous allez avec le EnumSet approche.

EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic);

Cette approche fournit une meilleure sécurité de type, et Style étant un enum aura de plein fouet l'OO capacités.

Réponse tardive pour quiconque qui traverse cela.Voici une façon de le faire pour réduire la mémoire et avoir une belle énumible comme API:

public static class MyFlag {

    public static final MyFlag A = new MyFlag(1<<0);
    public static final MyFlag B = new MyFlag(1<<1);
    public static final MyFlag C = new MyFlag(1<<2);
    public static final MyFlag ALL = A.and(B).and(C);

    private final int flag;

    private MyFlag(int flag){
        this.flag = flag;
    }

    public MyFlag and(MyFlag limit){
        return new MyFlag(flag & limit.flag);
    }

    public MyFlag not(MyFlag limit){
        return new MyFlag(flag | ~limit.flag);
    }

    public boolean isSet(MyFlag limit){
        if(limit ==null){
            return false;
        }
        return (this.flag & limit.flag) != 0;
    }
}

Méthode:

public void doFoo(MyFlag flag){
   if(MyFlag.A.isSet(flag)){
   ....
   }
   if(MyFlag.C.isSet(flag)){
   ....
   }
}

appel:

x.doFoo(MyFlag.A.and(MyFlag.C));

Si vous avez seulement un nombre limité de méthodes qui seront en prenant un ensemble de styles (comme printText, dans votre exemple), vous pouvez modifier leur signature à prendre un nombre variable de Style params:

void printText(String text, Style... flags) {
  EnumSet<Style> style = logicalOr(flags); // see comment below
  ...
 }

Et puis, vos appels sont très proches de la non typé (int) drapeau de la route:

printText("hello", Style.BOLD, Style.ITALIC);

Malheureusement, il n'y a pas de EnumSet.of(E... ) l'usine, juste EnumSet.of(E first, E... more), de sorte que vous aurez besoin d'un générique logicalOr méthode de diviser un tableau en premier + reste des morceaux. Laissé comme exercice au lecteur =).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top