Progettazione di una API di comando centralizzata

3

Sto lavorando a un progetto personale che ha un'interfaccia utente abbastanza complessa. Per quanto possibile vorrei rimuovere l'interazione del mouse. Per aiutarlo sto lavorando su una specie di linea di comando in app, dove puoi trovare tutte le azioni aprendo un popup e digita i nomi per eseguirle. (pensa intellij ctrl-shift-a, o eclipse ctrl-f12). Mi piacerebbe anche un modo per aggiungere un modo per passare un argomento al comando (ad esempio skipback 50s )

Sto avendo difficoltà a capire come progettare questo. Attualmente la mia idea è di avere un oggetto Commands comune che contenga tutti i comandi e un'interfaccia Command che contenga logica, un nome descrittivo e una descrizione arg (se presente). Parte del problema è che alcune azioni possono essere eseguite solo in determinati contesti, e l'altro problema è dove mettere il singolo Command s (questo è un problema perché gli oggetti scala sono pigri e non saranno aggiunti al Commands oggetto fino a dopo essere stato referenziato). Inoltre, non sono sicuro di come mantenere la sicurezza del tipo, dal momento che thees Command s sarà anche collegato ai ganci dell'interfaccia utente all'interno dell'app.

Qualche idea su come risolvere questo problema e / o migliorare il modello attuale?

    
posta J Atkin 18.05.2016 - 03:40
fonte

2 risposte

5

Un modo per ottenere ciò che stai cercando è implementare il pattern Observer .

Ad esempio, invece di avere un singolo oggetto "comandi" centralizzato che definisce tutti i possibili comandi, avresti un dispatcher di eventi centralizzato. Ogni "comando", quando istanziato, si registrerebbe con il dispatcher.

Quando viene richiamata la tavolozza comandi, viene emesso un "evento" contenente i dati di contesto correnti. Il dispatcher invierà quell'evento a ciascun comando registrato. Utilizzando i dati di contesto inviati con l'evento, il comando può decidere cosa fare: includersi nell'elenco, ignorare l'evento, modificarsi in base ai dati contestuali forniti, ecc.

Un modello più sofisticato sarebbe quello di emettere diversi tipi di eventi per ogni contesto. I comandi potrebbero quindi, quando si registrano con il dispatcher, indicare esplicitamente quali tipi di eventi interessano. Il dispatcher deciderà quindi quali comandi devono ricevere l'evento in primo luogo.

    
risposta data 18.05.2016 - 07:05
fonte
-3

Una possibile soluzione è qui sotto.

Questi contengono una struttura dati e restituiscono un'altra struttura dati. Questi delegano e non hanno if o loop. Questo dovrebbe avere idempotent solo le funzioni, quindi è un'unità testabile.

Per cose che dipendono dall'ambiente, crea un'interfaccia per un ruolo pietoso. Quindi, fai in modo che i ruoli implementino l'interfaccia con l'iniezione delle dipendenze (test di integrazione, una cosa alla volta con i mock per ciò che non è sotto test). Quindi fai un ritorno di classe una delle scelte.

L'interfaccia utente è ora variabile, separata dalle regole aziendali.

Per quanto riguarda il contesto, i tuoi pacchetti o spazi dei nomi dovrebbero urlarlo. Crea nomi dopo i titoli di lavoro. Quelli sono ruoli utente. Le sedi nell'edificio aziendale hanno alcuni flussi di lavoro. Ogni flusso di lavoro può essere un'interfaccia e una situazione può essere un'implementazione. Assicurarsi che l'interfaccia consenta il fallimento e il completamento parziale. Una classe di insuccesso aggraziata per ognuno potrebbe reindirizzare ciò che le persone fanno per aggirare il problema.

    
risposta data 18.05.2016 - 22:35
fonte

Leggi altre domande sui tag