The example I'm about to give is for the PHP language, but I think this scenario applies to most languages.
Diciamo che ho un oggetto chiamato Response e voglio che sia immutabile. Ogni metodo dovrebbe restituire una nuova istanza piuttosto che modificare lo stato dell'istanza corrente. Response s ha intestazioni, quindi creo un metodo chiamato withHeader($name, $value) che crea una copia del mio oggetto risposta, imposta l'intestazione e restituisce la nuova istanza. È piuttosto semplice da usare:
$newResponse = $oldResponse->withHeader('Content-Type', 'application/json');
Quindi decido che le intestazioni in realtà abbiano alcune proprietà e preferisco separarle in un oggetto separato chiamato HeaderBag . Ora voglio che il mio Response tenga un HeaderBag ma voglio comunque che sia immutabile.
Non posso rendere la borsa una proprietà pubblica, come $response->headers perché anche se l'oggetto $headers è immutabile, la proprietà può ancora essere riassegnata. Quindi forse aggiungo qualcosa come $response->getHeaders() che restituisce il mio oggetto HeaderBag , ma ora come lo manipolo?
Se sposto il mio metodo withHeader in questo sottooggetto, allora finisco con qualcosa come $response->getHeaders()->withHeader(...) . Il metodo withHeader restituirebbe presumibilmente un nuovo HeaderBag poiché anch'esso è immutabile, ma allora? Credo che finirei con qualcosa di simile:
$newResponse = $oldResponse->withHeaders($oldResponse->getHeaders()->withHeader($name, $value));
Che sembra un po 'ridicolo; per aggiungere un singolo valore dobbiamo clonare due oggetti e scrivere questo abominio di una linea. Certo, possiamo scrivere un metodo di supporto sull'oggetto Response per accorciarlo, ma l'idea era di spostare tutti i metodi relativi all'intestazione nella classe HeaderBag .
Domande:
- C'è un modo migliore per farlo?
- Se non c'è, vale anche lo sforzo / il costo per rendere gli oggetti immutabili?
- Se potessimo progettare un nuovo linguaggio con immutabilità in mente, come sarebbe questo?