C'è molto campo da coprire tra tipi immutabili ed esponendo tutti gli interni della tua classe attraverso i setter pubblici.
Un tipico costrutto usato per mutare tipi immutabili sta avendo metodi simili a setter che restituiscono una copia dell'oggetto con valori aggiornati di determinati campi - che invece di avere questo:
public void setName (string value) {
this.name = value;
}
hai qualcosa di simile a questo:
public Customer withName (string value) {
Customer cust = this.Clone();
cust.name = value;
return cust;
}
In questo modo puoi avere un oggetto immutabile che puoi essenzialmente aggiornare. Linguaggi come F # hanno zucchero di sintassi per operazioni simili su record, ma in linguaggi OOP meno funzionali questo sembra innaturale. Ma comunque, probabilmente non è quello che vuoi fare.
Ciò che rende attraente lo stato immutabile è il fatto che rende molte cose più facili da ragionare, dal momento che lo stato non cambierà attraverso un effetto collaterale in un pezzo di codice non correlato - meno posti in cui le cose andranno male. Ma è solo un mezzo per lo stesso fine che i linguaggi OOP incoraggiano a incapsulare.
Invece di affidarti ai setter, mantieni la logica di aggiornamento all'interno della classe. Stesso effetto: meno pulsanti da premere e leve da tirare per mettere il tuo oggetto in uno stato inaspettato e indesiderato. Mantieni un'interfaccia ben definita per gli utenti del tuo oggetto da utilizzare e non ci sarà bisogno di getter e setter generici.
È più lavoro che avere gli oggetti di dominio come semplici oggetti di trasferimento dati e talvolta può non valerne la pena, quindi è un giudizio. Ma se stai facendo qualcosa di remotamente complesso con il tuo oggetto (e visto che stai guardando oltre 30 campi, probabilmente lo sei), potrebbe valerne la pena.