Annulla / Ripristina con oggetti immutabili
-
06-07-2019 - |
Domanda
Ho letto quanto segue in un articolo
Gli oggetti immutabili sono particolarmente utile per l'implementazione di alcuni comuni modi di dire come annulla / ripristina e abilitabili transazioni. Prendi annulla per esempio. UN tecnica comune per l'implementazione dell'annullamento è quello di mantenere una pila di oggetti che in qualche modo sapere come eseguire ciascun comando al contrario (il cosiddetto comando "quot" Reticolo "). Tuttavia, capire come per eseguire un comando al contrario può essere difficile. Una tecnica più semplice è mantenere una pila di oggetti immutabili che rappresenta lo stato del sistema tra comandi successivi. Poi a annulla un comando, semplicemente torni indietro allo stato di sistema precedente (e probabilmente memorizza lo stato corrente su la pila di ripetizioni).
Tuttavia, l'articolo non mostra un buon esempio pratico di come oggetti immutabili potrebbero essere usati per implementare "annulla" operazioni. Ad esempio ... eliminando 10 e-mail da una casella di posta di Gmail. Una volta fatto, ha un'opzione di annullamento. In che modo un oggetto immutabile aiuterebbe in questo senso?
Soluzione
Gli oggetti immutabili manterrebbero l'intero stato del sistema, quindi in questo caso avresti l'oggetto A che contiene la posta in arrivo originale, quindi l'oggetto B che contiene la posta in arrivo con dieci e-mail cancellate e (in effetti ) un puntatore indietro da B ad A che indica che, se fai uno "annulla", smetti di usare B come stato del sistema e inizi a utilizzare A invece.
Tuttavia, le caselle di posta in arrivo di Gmail sono troppo grandi per usare questa tecnica. Lo useresti su documenti che possono essere effettivamente archiviati in una quantità abbastanza piccola di memoria, in modo da poterne tenere molti per un annullamento multi-livello.
Se vuoi mantenere dieci livelli di annullamento, puoi potenzialmente risparmiare memoria mantenendo solo due oggetti immutabili - uno che è attuale e uno che è da dieci "undos" fa - e un elenco di comandi applicati tra di loro.
Per eseguire un " undo " ;, riesegui tutto tranne l'ultimo oggetto Command, usalo come nuovo oggetto corrente e cancella l'ultimo Comando (o salvalo come " Ripeti " oggetto). Ogni volta che esegui una nuova azione, aggiorni l'oggetto corrente, aggiungi il comando associato all'elenco e quindi (se l'elenco contiene più di dieci comandi) esegui il primo comando sull'oggetto dall'inizio dell'elenco di annullamenti e getta via il primo comando nell'elenco.
Puoi anche fare vari altri sistemi di checkpoint, coinvolgendo un numero variabile di rappresentazioni complete del sistema e un numero variabile di Comandi tra di loro. Ma va sempre più lontano dall'idea originale che hai citato e diventa sempre più come un tipico sistema mutabile. Tuttavia, evita il problema di rendere i Comandi costantemente reversibili; devi solo applicare i comandi a un oggetto in avanti e non al contrario.
SVN e altri sistemi di controllo della versione sono effettivamente una forma di annullamento e ripetizione basata su disco o in rete.