Domanda

Mi piace il concetto di immutabilità ma a volte mi chiedo, quando un'applicazione non è pensata per essere parallela, si dovrebbe evitare di rendere le cose immutabili?

Quando un'applicazione non è multi-thread, non sei afflitto da problemi di stato condiviso, giusto?

O l'immutabilità è un concetto come OOP che usi o no fino in fondo? Escludendo i casi in cui qualcosa non dovrebbe essere immutabile in base all'uso / alle prestazioni, ecc.

Mi trovo di fronte a questa domanda quando scrivo un'applicazione per me, che è moderatamente grande (forse come 1-2k righe).

È stato utile?

Soluzione

Adoro l'immutabilità perché significa che non devo fidarmi del codice di altre persone per non scherzare con oggetti che mi aspetto di rimanere lo stesso.

Quando passi un oggetto a un altro componente come List<T>, sei in balia di ciò che fa quel componente. Ciò è particolarmente importante quando si restituiscono raccolte come proprietà.

public class Foo { 
  private List<Bar> _barList;
  public ICollection<Bar> BarList { get return _barList; } 
}

Non c'è niente che impedisce a un consumatore di questa classe di cancellare la raccolta da sotto di me. Anche cambiare il tipo di ritorno in IEnumerable<Bar> non è del tutto sicuro. Non c'è niente che impedisce a un pezzo di codice scritto male di riportarlo su <=> e chiamare .Clear ().

Tuttavia, se voglio davvero che la raccolta rimanga coerente, potrei riscriverla come segue

public class Foo {
  private ImmutableCollection<Bar> _barList;
  public ImmutableCollection<Bar> BarList { get { return _barList; } }
}

Ora sono sicuro di non fidarmi di altro codice dall'uso errato della mia classe. Non possono sbagliare.

Altri suggerimenti

Mi piace il vantaggio dell'immutabilità di cui hai bisogno per convalidarlo una sola volta - alla creazione dell'oggetto. Questo è un enorme vantaggio in realtà.

Un grande vantaggio dell'immutabilità è che non è necessario tenere traccia della proprietà di oggetti immutabili. Esistono solo finché qualcuno ne ha bisogno e poi svaniscono nel nulla quando non sono più necessari. Anche se l'utilizzo di un garbage collector in molti casi significa che non è necessario scrivere espressamente alcun codice relativo alla proprietà di oggetti mutabili (la più grande eccezione sono quelli che implementano IDisposable), in molti casi è molto difficile scrivere il codice corretto in cui gli oggetti che hanno uno stato mutabile non hanno un " chiaramente definito; proprietario " ;. La confusione su chi possiede lo stato degli oggetti mutabili può essere una fonte molto frequente di bug; quando si utilizzano oggetti immutabili (a parte alcuni che implementano List<T>) si può generalmente ignorare i problemi di proprietà.

Un altro punto da considerare è che è molto più facile ragionare su un riferimento mutabile a un oggetto semanticamente immutabile, o un riferimento immutabile a un oggetto mutabile, piuttosto che ragionare su un riferimento mutabile a un oggetto mutabile. Se uno ha un riferimento mutabile a un oggetto mutabile, spesso può non essere chiaro se l'approccio corretto per aggiornare lo stato sia semplicemente quello di mutare direttamente l'oggetto o copiarne lo stato su un nuovo oggetto, mutarlo e aggiornare il riferimento. In alcuni casi, ci saranno circostanze che richiedono ogni tipo di operazione (come con <=>, che a volte sostituisce un array con uno più grande, ma di solito esegue aggiornamenti sul posto), ma tale approccio funziona solo se il tipo mantiene esclusivo controllo sugli oggetti mutabili in questione. Spesso è più utile avere un riferimento immutabile a un tipo mutabile (nel qual caso il codice può esporre il riferimento, possibilmente attraverso un wrapper di sola lettura, ad altri oggetti che vogliono un & Quot; live view & Quot; del suo stato) oppure hanno un riferimento mutabile a un oggetto che è immutabile o, come minimo, non sarà mai mutato durante la durata del riferimento.

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