È un approccio accettabile per annullare / ripristinare in Python?

5

Sto facendo un'applicazione (wxPython) per elaborare alcuni dati da documenti Excel. Voglio che l'utente sia in grado di annullare e ripetere azioni, anche azioni gigantesche come l'elaborazione simultanea dei contenuti di 10.000 celle. Ho cercato su Google l'argomento e tutte le soluzioni che ho trovato riguardano un sacco di magia nera o sono eccessivamente complicate.

Ecco come immagino il mio semplice schema di annullamento / ripristino. Scrivo due classi, una chiamata ActionStack e una astratta chiamata Action . Ogni operazione "annullabile" deve essere una sottoclasse di Action e definire i metodi do e undo . La sottoclasse Action riceve l'istanza del "documento" o modello di dati ed è responsabile per l'operazione e per ricordare come annullare la modifica.

Ora, ogni documento è associato a un'istanza di ActionStack . Il ActionStack mantiene una pila di azioni (sorpresa!). Ogni volta che le azioni vengono annullate e vengono eseguite nuove azioni, tutte le azioni annullate vengono rimosse per sempre. Anche ActionStack rimuoverà automaticamente il più vecchio Action quando lo stack raggiunge il valore massimo configurabile.

Immagino che il flusso di lavoro produca codice simile a questo:

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)

Dato che nessuno dei metodi che ho trovato sono così semplici, ho pensato di ottenere l'opinione degli esperti prima di andare avanti con questo piano. Più nello specifico, ciò di cui mi sto chiedendo è: ci sono dei buchi evidenti in questo piano che non vedo?

    
posta Hubro 27.11.2012 - 22:26
fonte

1 risposta

7

Il tuo approccio è solo un'applicazione del classico schema di comando , non specifico per Python, e ben noto per l'implementazione di undo funzionalità. Google per "command pattern undo" per trovare esempi, anche piccoli che non siano eccessivamente complicati.

E sì, se lo fai bene, puoi implementare la funzionalità di annullamento in questo modo. Se sarà facile o difficile da implementare, dipenderà molto dal tipo di azioni che avremo e dalla quantità di dati da elaborare. In teoria, prima di applicare un'azione, è possibile salvare l'intero stato dei dati e ripristinarli a quel punto ogni volta che si desidera "annullare". Ciò renderà possibile implementare l'annullamento in modo semplice e generico, senza la necessità di singole operazioni di "annullamento". Tuttavia, se si dispone di un'enorme quantità di dati da elaborare e si desidera un grande stack di annullamento, questo approccio spesso non è possibile a causa dei vincoli di memoria. Se questa è la tua situazione, un salvataggio specifico dei dati modificati e una corrispondente implementazione "annulla" possono essere molto più efficienti, ma solo se hai molte azioni "piccole" da elaborare che consentiranno tale ottimizzazione.

Altri punti chiave:

  • ti aspetti che le azioni parallele vengano applicate ai dati, da più thread o processi o utenti? Ciò può rendere molto difficile l'implementazione di "annullare".
  • ti aspetti Azioni in cui non puoi prevedere quale parte dei tuoi dati sarà modificata? In questo caso, avrai bisogno di un approccio "salva tutto" per quelle azioni, che potrebbero o meno essere un problema, vedi sopra.
risposta data 27.11.2012 - 22:44
fonte

Leggi altre domande sui tag