Esta é uma abordagem aceitável para desfazer / refazer em Python?

5

Estou fazendo uma aplicação (wxPython) para processar alguns dados de documentos do Excel. Eu quero que o usuário seja capaz de desfazer e refazer ações, até mesmo ações gigantescas, como processar o conteúdo de 10 000 células simultaneamente. Eu pesquisei o tópico no Google e todas as soluções que consegui encontrar envolveram muita magia negra ou são excessivamente complicadas.

Veja como eu imagino meu esquema simples de desfazer / refazer. Eu escrevo duas classes - uma chamada ActionStack e uma abstrata chamada Action . Cada operação "desfazível" deve ser uma subclasse de Action e definir os métodos do e undo . A subclasse Action é passada na instância do "documento" ou modelo de dados e é responsável por confirmar a operação e lembrar como desfazer a alteração.

Agora, cada documento está associado a uma instância do ActionStack . O ActionStack mantém uma pilha de ações (surpresa!). Toda vez que ações são desfeitas e novas ações são realizadas, todas as ações desfeitas são removidas para sempre. O ActionStack também removerá automaticamente o mais antigo Action quando a pilha atingir o valor máximo configurável.

Eu imagino que o fluxo de trabalho produziria código com algo parecido com isto:

class TableDocument(object):
    def __init__(self, table):
        self.table = table
        self.action_stack = ActionStack(history_limit=50)

    # ...

    def delete_cells(self, cells):
        self.action_stack.push(
            DeleteAction(self, cells)
        )

    def add_column(self, index, name=''):
        self.action_stack.push(
            AddColumnAction(self, index, name)
        )

    # ...

    def undo(self, count=1):
        self.action_stack.undo(count)

    def redo(self, count=1):
        self.action_stack.redo(count)

Dado que nenhum dos métodos que encontrei é tão simples, pensei em obter a opinião dos especialistas antes de prosseguir com este plano. Mais especificamente, o que eu estou pensando é - há algum buraco neste plano que eu não estou vendo?

    
por Hubro 27.11.2012 / 22:26
fonte

1 resposta

7

Sua abordagem é apenas uma aplicação do padrão de comando , não específico para Python, e bem conhecido pela implementação de desfazer funcionalidade. Google para "comando padrão desfazer" para encontrar exemplos, mesmo os pequenos que não são excessivamente complicados.

E sim, se você fizer isso corretamente, poderá implementar a funcionalidade desfazer dessa maneira. Se for fácil ou difícil de implementar, depende muito do tipo de ações que você terá e da quantidade de dados a processar. Em teoria, antes de aplicar uma ação, você pode salvar todo o estado de seus dados e redefinir para esse estado sempre que quiser "desfazer". Isso tornará possível implementar seu desfazer de maneira simples e genérica, sem a necessidade de operações de "desfazer" individuais. No entanto, se você tiver uma quantidade enorme de dados para processar e desejar uma grande desfazer, essa abordagem geralmente não é viável devido a restrições de memória. Se essa é a sua situação, um salvamento específico dos dados modificados e uma implementação de "desfazer" correspondente podem ser muito mais eficientes, mas somente se você tiver muitas ações "pequenas" a serem processadas, o que permitirá essa otimização.

Outros pontos importantes:

  • você espera que as Ações paralelas sejam aplicadas aos dados, por vários segmentos ou processos ou usuários? Isso pode dificultar muito a implementação do "undo".
  • você espera ações nas quais não é possível prever qual parte de seus dados será alterada? Nesse caso, você precisará de uma abordagem "salvar tudo" para essas ações, o que pode ou não ser um problema, veja acima.
por 27.11.2012 / 22:44
fonte

Tags