2008-11-20 9 views
5

¿Es necesario que los métodos setter tengan un argumento? Por lo general, los métodos setter aceptan un argumento como el valor de una determinada propiedad de un objeto. ¿Qué pasa si quiero probar primero la validez que depende de otro argumento que es un booleano, si es verdadero, validar primero, sino simplemente establecer el valor.¿Es necesario que los métodos setter tengan un argumento?

Estoy obteniendo los valores de los clientes a través del servidor ftp. A veces esos archivos contienen valores basura. Por ejemplo, un número de teléfono como # 3432838 # 9. Entonces, antes de establecer el valor, necesito eliminar esos caracteres basura. ¿Puedo hacerlo en los métodos setter? ¿Es un enfoque válido?

¡Muchas gracias por adelantado!

EDIT:

Es esto válido:

public void setSomething(String strValue){ 
    if(checkValidity(strValue)){ 
     // set the value 
    } else { 
     // set the value to an empty string 
    } 
    } 
+0

Véase también http://stackoverflow.com/questions/2750/data-verifications-in-gettersetter-or- elsewhere – VonC

+0

Muchas gracias. – DragonBorn

+0

Acaba de agregar una respuesta a su fragmento – VonC

Respuesta

12

Es necesario específicamente en el modelo de marco de Java Bean, pero no es obligatorio en general.

Puede tener setter sin argumentos cuando están destinados a "swith" un valor.

void setCheck() 

podría ser, por ejemplo destinado a establecer el "cheque" atributo booleano true.

Por lo tanto, incluso si no es un "setter" en el sentido de Java Bean del término, se puede imaginar el colocador utilizado para otros fines.

Además, según el artículo 7 de las especificaciones JavaBean, un regulador puede tener más de un argumento, por ejemplo, para propiedades indizadas (Una propiedad indexada soporta un rango de valores. Siempre que la propiedad se lee o se escribe sólo tiene que especificar un índice para identificar qué valor que desee.)

void setter(int index, PropertyType value); // indexed setter 
void setter(PropertyType values[]); // array setter 

En su caso, un enfoque válido sería añadir un runtime exception a la firma de nuestra función.
De esta manera no pone ninguna verificación de excepción de tiempo de compilación innecesaria para todas las otras clases que ya están llamando a su instalador.

O bien, podría considerar su propiedad como Restricción de la propiedad y agregar una excepción no de tiempo de ejecución.

Se requieren métodos restringidos de configuración de propiedades para admitir PropertyVetoException. Esto documenta a los usuarios de la propiedad restringida que las actualizaciones intentadas pueden ser vetadas. Así un simple propiedad restringida podría ser:

PropertyType getFoo(); 
void setFoo(PropertyType value) throws PropertyVetoException; 

que permite VetoableChangeListener que se añade si es necesario.


En cuanto a su fragmento, que es "válido", pero puede no ser óptima debido a que (como se ha dicho en this question):

  • validación debe ser capturada por separado de getters o setters en un método de validación . De esta forma, si la validación debe reutilizarse en múltiples componentes, está disponible.
  • Es mejor fail fast (de ahí mi proposición de agregar excepción al setter).
+0

Pero void setCheck() ya no es "setter". Es simplemente un método sencillo cuyo nombre comienza con "establecer". – Marko

+0

Verdadero: sólo quise decir que un "setter" no necesariamente está asociado a Java Bean. Se puede rechazar para otros fines. – VonC

+0

Entonces, ¿el fragmento de código agregado es un enfoque válido? Gracias. – DragonBorn

5

Por especificación Java Bean colocador tienen un argumento. Si agrega otro, por la razón que sea, ya no se considera setter.

Setter es perfectamente válido para "limpiar" su argumento, o lanzar una excepción si no es válido.

2

¿Por qué no? Verificar y validar la entrada es una buena variante para incluir en el setter. La pregunta aquí es si desea permitir la configuración del miembro sin validación.

Es posible que necesite la forma estándar del colocador para algún marco que utilice (uso como bean). Pero si no está restringido de esta manera, puede intentar esto.

También puede usar las afirmaciones en el colocador, si cree que otro código debe hacer la validación pero los valores incorrectos nunca deben establecerse.

1

En el libro "Effective Java 2nd Edition" de Joshua Bloch (ISBN-13: 978-0-321-35668-0) dice que es mejor utilizar el patrón de construcción que la convención de beans para las creaciones de objetos.

Por ejemplo (modelo del grano):

NutritionFacts cocaCola = new NutritionFacts(); 
cocaCola.setServingSize(240); 
cocaCola.setServings(8); 
cocaCola.setCalories(100); 
cocaCola.setSodium(35); 
cocaCola.setCarbohydrate(27); 

Uso con Builder:

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8). 
    calories(100). 
    sodium(35). 
    carbohydrate(27). 
    build(); 

La implementación de Builder:

// Builder Pattern 
public class NutritionFacts { 
    private final int servingSize; 
    private final int servings; 
    private final int calories; 
    private final int fat; 
    private final int sodium; 
    private final int carbohydrate; 
    public static class Builder { 
     // Required parameters 
     private final int servingSize; 
     private final int servings; 
     // Optional parameters - initialized to default values 
     private int calories = 0; 
     private int fat = 0; 
     private int carbohydrate = 0; 
     private int sodium = 0; 
     public Builder(int servingSize, int servings) { 
      this.servingSize = servingSize; 
      this.servings = servings; 
     } 
     public Builder calories(int val) 
     { calories = val; return this; } 
     public Builder fat(int val) 
     { fat = val; return this; } 
     public Builder carbohydrate(int val) 
     { carbohydrate = val; return this; } 
     public Builder sodium(int val) 
     { sodium = val; return this; } 
     public NutritionFacts build() { 
      return new NutritionFacts(this); 
     } 
    } 
    private NutritionFacts(Builder builder) { 
     servingSize = builder.servingSize; 
     servings = builder.servings; 
     calories = builder.calories; 
     fat = builder.fat; 
     sodium = builder.sodium; 
     carbohydrate = builder.carbohydrate; 
    } 
} 

Cuando los dos primeros argumentos ar necesario.
Para la validación puede usar la validación anticipada (en cada método <field>) o la validación diferida (en el método build()). Y el formato es una especie de inicialización de clave-valor python.

+0

¿Cuál es la importancia de tener el método de compilación? ¿Por qué no detenerse en .carbohydrate()? – Allyn

+0

El método de compilación devuelve un objeto NutritionFacts. Los otros devuelven un Constructor. Puede escribir algo como esto: NutritionFacts n = new NutritionFacts.Builder (12, 15) .sodium (12) .build(); – user2427

Cuestiones relacionadas