Pergunta

Eu li o seguinte em um artigo

Objetos imutáveis ??são particularmente útil para implementação de algumas comum expressões tais como desfazer / refazer e abortable transações. Tome desfazer por exemplo. UMA técnica comum para implementar undo é manter uma pilha de objetos que de alguma forma, sabe como executar cada comando em sentido inverso (o chamado "Command Padrão "). No entanto, para descobrir como para executar um comando no sentido inverso pode ser complicado. Uma técnica simples é manter uma pilha de objetos imutáveis representando o estado do sistema entre os comandos sucessivos. Então, para desfazer um comando, você volta simplesmente revert para o estado anterior do sistema (e provavelmente armazenar o estado atual em a pilha de repetição).

Howver, o artigo não mostra um bom exemplo prático de como objetos imutáveis ??poderia ser usado para implementar operações de "desfazer". Por exemplo ... exclusão de 10 e-mails de uma caixa de entrada do Gmail. Depois de fazer isso, ele tem uma opção de desfazer. Como é que um objeto ajuda imutável a este respeito?

Foi útil?

Solução

Os objetos imutáveis ??iria realizar todo o estado do sistema, portanto, neste caso você teria objeto A que contém a caixa de entrada original, e em seguida, objeto B que contém a caixa de entrada com e-mails dez excluído, e (em vigor ) a volta do ponteiro de B para a, indicando que, se você fizer um "undo", então você parar de usar B como o estado do sistema e começar a usar uma vez.

No entanto, as caixas de entrada do Gmail são demasiado grande para usar esta técnica. Você poderia usá-lo em documentos que podem realmente ser armazenados em uma quantidade relativamente pequena de memória, de modo que você pode manter muitos deles em torno de desfazer multi-nível.

Se você quiser manter os níveis de dez de desfazer, você pode potencialmente salvar memória, mantendo apenas dois objetos imutáveis ??- uma que é atual, e um que é de dez "undos" atrás - e uma lista de comandos que foram aplicados entre -los.

Para fazer um "undo", você re-executar todos, mas o último objeto de comando, use isso como o novo objeto atual, e apagar o último comando (ou salvá-lo como um objeto "Redo"). Toda vez que você faz uma nova ação, você atualizar o objeto atual, adicione o comando associado à lista, e depois (se a lista é mais de dez Comandos de comprimento) de executar o primeiro comando no objeto desde o início da lista de undo e jogar fora o primeiro comando na lista.

Você pode fazer vários outros sistemas de checkpointing bem, envolvendo um número variável de representações completas do sistema, bem como um número variável de Comandos entre eles. Mas torna-se mais e mais a partir da idéia original que você citou e torna-se cada vez mais como um sistema mutável típico. É, no entanto, evitar o problema de fazer Comandos consistentemente reversível; você só precisa sempre aplicar comandos a um objeto para frente e não inversa.

outros sistemas de controle de versão SVN e são efetivamente uma forma disk-ou baseado em rede de desfazer-and-redo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top