Non utilizzare un bean Java se è possibile
Sebbene i Java Beans siano estremamente utili in molte occasioni, direi che sarebbe meglio che User
non fosse un bean nel contesto che descrivi. Puoi progettare questa classe in modo che le sue istanze siano sempre in uno stato valido.
Nell'esempio seguente, il nome è obbligatorio e l'indirizzo è facoltativo.
class User {
private String name;
private String address;
User(String name) {
setName(name);
}
void setName(String name) {
if (name == null)
throw new IllegalArgumentException("[name] cannot be null");
this.name = name;
}
String getName() {
return name;
}
void setAddress(String address) {
this.address = address;
}
String getAddress() {
return address;
}
}
Come puoi vedere, con quel design, non è possibile in alcun momento avere un'istanza User
senza un nome. Tuttavia, puoi avere istanze con un indirizzo, oltre a istanze senza.
Si noti inoltre che nell'esempio di codice sopra sto eseguendo alcune convalide di base. Se necessario, è possibile eseguire una convalida più complessa di quella. Ad esempio assicurandoti che il nome non contenga caratteri che non appaiono nel tuo contesto.
Cose da considerare
Ci sono alcune cose da considerare per assicurarsi che una classe soddisfi il suo obiettivo. Solo il suo contenuto immutabile può essere mostrato al mondo esterno, per esempio. Considera un'altra classe simile che contiene un elenco che deve sempre contenere almeno un elemento. Se quell'elenco è mutabile e il codice esterno può accedervi (tramite un getter, ad esempio), nulla gli impedisce di rimuovere oggetti da esso finché non è vuoto, ponendo l'istanza iniziale in uno stato che non dovrebbe essere consentito. Naturalmente, se hai bisogno di esporre quei dati, considera solo di dare una copia dell'elenco o di renderlo immutabile.
Che cosa succede se ci sono molti valori obbligatori?
Se ha senso raggruppare alcuni di questi valori in classi proprie e che così facendo il costruttore diventa maneggevole, provaci. Tali classi dovrebbero essere progettate tenendo conto dei vincoli sopra menzionati.
In alternativa, puoi definire un Builder per aiutarti a costruire gli oggetti.
Che cosa succede se è necessario un bean Java in una parte specifica del mio codice?
Il design potrebbe funzionare bene nella maggior parte dei casi in cui queste classi vengono utilizzate tranne che in luoghi specifici in cui, poiché ad esempio un framework ne ha bisogno, è necessario utilizzare i bean Java. Quando ciò accade, invece di usare i bean ovunque, puoi definire un bean che contiene gli stessi dati con costruttore e metodo aggiunti per occuparsi della conversione dei dati. Ad esempio ...
class UserBean {
private String name;
private String address;
UserBean() {
}
UserBean(User user) {
this.name = user.getName();
this.address = user.getAddress();
}
void setName(String name) {
this.name = name;
}
String getName() {
return name;
}
void setAddress(String address) {
this.address = address;
}
String getAddress() {
return address;
}
User toUser() {
User ret = new User(name);
ret.setAddress(address);
return ret;
}
}
In questo modo è facile avere un bean dall'istanza non bean e viceversa.
Conclusione
Come puoi vedere il problema che hai può essere risolto mantenendo la sua firma iniziale. È possibile che andando in questo modo si ottenga più codice da scrivere per un risultato simile (anche se non ne garantirei, dal momento che passare un oggetto necessariamente valido attorno significa meno convalida richiesta dal codice che lo utilizza).
Ho cercato di farla breve (ehm ...) e di usare qui un disegno simile a quello iniziale (fagioli). Tuttavia, è più per il gusto della spiegazione che per il fatto che considero il miglior design the . Con tutta la seccatura di forse bisogno di costruttori e classi di bean aggiuntive, tenderei a fare il miglio supplementare e rendere la classe passata immutabile. È così che ho progettato un progetto recente e breve, che si è rivelato particolarmente efficace.