Domanda

È necessario che i metodi setter abbiano un argomento? Solitamente i metodi setter accettano un argomento come valore di una determinata proprietà di un oggetto. E se volessi testare prima la validità che dipende da un altro argomento che è un valore booleano, se vero, per primo convalida, altrimenti basta impostare il valore.

Ricevo i valori dai client tramite il server ftp. A volte quei file contengono valori inutili. Ad esempio, un numero di telefono come # 3432838 # 9. Quindi, prima di impostare il valore, devo rimuovere quei caratteri spazzatura. Posso farlo con i metodi setter? È un approccio valido?

Grazie mille in anticipo!

Modifica

È valido:

public void setSomething(String strValue){ 
     if(checkValidity(strValue)){ 
         // set the value 
     } else { 
         // set the value to an empty string
     }  
  }
È stato utile?

Soluzione

È necessario specificamente nel modello di framework java bean, ma non è obbligatorio in generale.

Puoi avere setter senza argomenti quando sono destinati a " swith " un valore.

void setCheck()
Ad esempio,

potrebbe essere inteso per impostare " controlla " attributo booleano su true.

Quindi, anche se non è un " setter " nel senso del termine java bean, puoi immaginare setter usato per altri scopi.

Inoltre, secondo la sezione 7 delle specifiche JavaBean, un setter può avere più di un argomento , ad esempio per le proprietà indicizzate (una proprietà indicizzata supporta un intervallo di valori. Ogni volta che la proprietà viene letta o scritto basta specificare un indice per identificare quale valore si desidera.)

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

Nel tuo caso, un approccio valido sarebbe quello di aggiungere un eccezione di runtime alla firma della nostra funzione.
In questo modo non inserirai inutili eccezioni durante il tempo di compilazione per tutte le altre classi che stanno già chiamando il tuo setter.

Oppure potresti considerare la tua proprietà come Proprietà vincolata e aggiungere un'eccezione non di runtime.

Per supportare PropertyVetoException sono richiesti metodi di impostazione proprietà vincolati. Questo documento può essere per gli utenti della proprietà vincolata che ha tentato di aggiornare posto il veto. Quindi una semplice proprietà vincolata potrebbe apparire come:

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

che consente di aggiungere VetoableChangeListener se necessario.


Per quanto riguarda lo snippet, è " valido " ma potrebbe non essere ottimale perché (come detto in questa domanda ):

  • La convalida deve essere acquisita separatamente da getter o setter in un metodo di convalida. In questo modo se la convalida deve essere riutilizzata su più componenti, è disponibile.
  • È meglio fallire velocemente (da qui la mia proposta di aggiungere un'eccezione al setter).

Altri suggerimenti

Il setter delle specifiche di Java Bean ha un argomento. Se ne aggiungi un altro, per qualsiasi motivo, non viene più considerato setter.

Setter è perfettamente valido per " ripulisci " il suo argomento o genera un'eccezione se non è valido.

Perché no. La verifica e la convalida dell'input è una buona variante da includere nel setter. La domanda qui è, se si desidera consentire l'impostazione del membro senza convalida.

Probabilmente hai bisogno della forma standard del setter per un framework che usi (uso come bean). Ma se non sei limitato in questo modo, puoi provare questo.

Puoi anche usare assert nel setter, se pensi che altri codici dovrebbero fare la validazione ma valori errati non dovrebbero mai essere impostati.

Nel libro " Effective Java 2nd Edition " di Joshua Bloch (ISBN-13: 978-0-321-35668-0) afferma che è meglio utilizzare il modello di costruzione rispetto alla convenzione bean per le creazioni di oggetti.

Ad esempio (modello bean):

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

Utilizzo con pattern builder:

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

L'implementazione del modello 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;
    }
}

Quando sono richiesti i primi due argomenti.
Per la convalida è possibile utilizzare la convalida anticipata (in ciascun metodo <field>) o la convalida lenta (nel metodo build ()). E il formato è una specie di inizializzazione del valore-chiave di Python.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top