melhor método para reverter o estado se a falha ocorrer durante a adição / exclusão

5

Portanto, eu tenho uma estrutura genérica com um conceito de filhos e objetos pai, os objetos não precisam ser do mesmo tipo e eu posso adicionar ou remover qualquer um deles. Adicionando chamadas adicionar todos os filhos, e informa os pais, inverter para remover.

o conceito de Parent é genérico o suficiente para que possa haver um loop entre as classes. A pode ser um pai de B, que é pai de C, que é pai de A. Isso ainda funciona, pois marquei um objeto como adicionado ou removido como o primeiro passo na classe abstrata; então, mesmo que uma dependência circular chame Adicionar uma segunda vez no mesmo objeto, a segunda vez, através do add, retornará sem fazer nada (porque o booleano adicionado já está definido) e paramos nossa recursão.

Se ocorrer alguma exceção inesperada, quero reverter meu estado de volta ao que era antes da exceção ocorrer. Eu estava fazendo isso com o tratamento de exceção, se eu pegar uma conexão de tempo de execução eu remover objetos que eu adicionei e atualizar os pais antes de lançar a exceção. É aqui que minha lógica pode falhar. A partir de agora, eu reverti o método AddObject chamando removeObject e vice-versa. Se meu estado de alguma forma acabasse em um estado verdadeiramente bizarro, eu poderia continuar lançando exceções, adicionar lançamentos e chamadas remover, remover lançamentos e chamadas, etc etc. Acho que isso ainda tem uma chance de recursão infinita; apesar de admitir que algo já teria que ser muito confuso em meu estado para que isso aconteça.

Existe uma maneira mais clara de fazer minha lógica de reversão para evitar esse potencial? Em um ponto como este, o que devo dizer que meu estado deve ser assim que eu me recuperar de qualquer maneira?

    
por dsollen 30.04.2013 / 01:49
fonte

4 respostas

2

Existe uma maneira mais limpa e é usar estruturas de dados imutáveis / persistentes. Esta é uma ideia da programação funcional, mas não há realmente nenhuma razão para que você não possa fazê-lo em um paradigma orientado a objetos também.

Você constrói os dados de maneira que nunca sejam excluídos ou transformados. Atualizações criam uma nova estrutura sem alterar os dados da estrutura antiga. Se uma atualização der errado, você reverte para a versão anterior. Se for bem sucedido, você pode descartar a versão anterior, dependendo de suas necessidades.

link

    
por 30.04.2013 / 14:50
fonte
2

Se você puder pagar a memória, poderá tirar uma foto antes de fazer qualquer alteração. Se tudo correr bem, exclua o instantâneo. Se alguma coisa der errado, largue a nova versão e volte ao snapshot.

Se isso for muito caro, você poderá primeiro calcular quais partes poderiam ser afetadas (DFS ou algo assim) e tirar apenas uma foto dessas partes.

    
por 30.04.2013 / 01:58
fonte
0

Existem dois padrões de projeto disponíveis para operações de Desfazer / Refazer que valem a pena investigar. O primeiro é o padrão de design de comando: -

link

E o segundo, é o padrão de design Memento: -

link

Espero que ajude.

    
por 01.05.2013 / 18:05
fonte
0

Primeiramente, você realmente precisa reverter o estado? Quando algo acaba de dar errado no seu programa, faz sentido tentar ficar em vez de bater e queimar? Pode ser muito trabalhoso tentar tornar seu programa resiliente a esse tipo de coisa, e você deve avaliar se seria melhor gastar esse tempo corrigindo os erros que causam as exceções.

Sugiro fazer algo relacionado à técnica usada por um banco de dados. Os bancos de dados mantêm um registro de todas as alterações feitas para que possam retornar ao log e desfazer todas as alterações. Então, eu tenho código parecido com

transaction = TreeTransaction()
try
{
    foo.add(bar, transaction);
    bar.add(goat, transaction);
    transaction.commit();
}
catch(...)
{
    transaction.rollback();
}

Dependendo do seu idioma, geralmente há algumas maneiras de melhorar o padrão. A ideia é que todas as mudanças sejam feitas dentro do contexto de uma transação. Quando ocorre um erro inesperado, o método de reversão coloca tudo de volta como estava. Commit pode tornar as alterações oficiais, se isso fizer sentido.

    
por 01.05.2013 / 23:47
fonte

Tags