Pregunta

¿Cuál es la mejor práctica para la especificación de indicadores en un método de Java?

He visto SWT uso de int como campos de bits, como:

(por ejemplo, en parte, de "Effective Java, 2ª Ed.", página 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) {

  }
}

y su llamada de cliente se ve así:

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

..pero esto no se recomienda, ya que puede mixto de banderas (int valor) de diferentes clases juntos sin ningún compilador de cheques.

En el mismo libro ("Effective Java"), veo que el uso de EnumSet, pero entonces el usuario llamada se convierte en:

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

Me parece que esta un poco detallado y yo prefiero la elegancia de SWT.

Hay alguna otra alternativa o es esto, básicamente, los dos gustos que usted debe elegir?

¿Fue útil?

Solución

Supongo que has golpeado una pared.No veo ninguna otra opción.Java es verboso que es un hecho.En situaciones como esta, generalmente agrego una variable local para que el código sea más legible.Puedes hacer esto,

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

Otros consejos

Si desea bits indicadores de estilo de Java, los envuelve en un BitSet.Ha sido alrededor de las edades, sin embargo, pocas personas se molestan en utilizar (prefiriendo la incrustación de estilo de C bits en el manejo de enteros).

La api para BitSet se puede encontrar aquí.

Junto con un par bien elegido estática enteros, lo hace bastante bien hasta que empiezas a meterte en la comprobación y ajuste de múltiples bits en una sola pasada.

Te aconsejo que vayas con el EnumSet enfoque.

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

Este enfoque proporciona un mejor tipo de seguridad, y Style ser una enumeración se tienen en toda regla OO capacidades.

respuesta tardía para que cualquiera que vaya a través de esto.Aquí hay una forma de hacerlo para reducir la memoria y tener un agradable enume como 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ÉTODO:

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

Llamada:

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

Si sólo tiene un número limitado de métodos que será la adopción de un conjunto de estilos (como printText, en tu ejemplo), usted puede ajustar su firma para tomar un número variable de Estilo params:

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

Y, a continuación, tus llamadas son muy de cerca el tipo (int) indicador de ruta:

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

Lamentablemente, no hay EnumSet.of(E... ) de fábrica, sólo EnumSet.of(E first, E... more), por lo que necesitará un genérico logicalOr método para dividir la matriz en first + resto de fragmentos. Deja como ejercicio para el lector =).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top