Programmazione basata su eventi: quando ne vale la pena?

18

Ok, so che il titolo di questa domanda è quasi identico a Quando dovrei utilizzare la programmazione basata su eventi? ma le risposte a tale domanda non mi hanno aiutato a decidere se utilizzare gli eventi nel caso specifico che sto affrontando.

Sto sviluppando una piccola applicazione. È un'app semplice e, per la maggior parte, la sua funzionalità è CRUD di base.

In determinati eventi (quando si modificano determinati dati) l'applicazione deve scrivere una copia locale di tali dati in un file. Non sono sicuro di quale sia il modo migliore per implementarlo. Posso:

  • Incendi gli eventi quando i dati vengono modificati e associa una risposta (genera il file) a tali eventi. In alternativa, implementa il modello di osservatore. Sembra una complessità inutile.
  • Chiama il codice che genera file direttamente dal codice che modifica i dati. Molto più semplice, ma sembra sbagliato che la dipendenza dovrebbe essere in questo modo, cioè, sembra sbagliato che la funzionalità di base dell'app (codice che modifica i dati) debba essere accoppiata a quel extra perk (codice che genera un file di backup). So, tuttavia, che questa app non evolverà fino al punto in cui tale accoppiamento pone un problema.

Qual è l'approccio migliore in questo caso?

    
posta abl 12.03.2016 - 21:18
fonte

4 risposte

30

Segui il principio KISS: Keep It Simple, Stupid, o il principio YAGNI: non hai intenzione di averne bisogno.

Puoi scrivere il codice come:

void updateSpecialData() {
    // do the update.
    backupData();
}

O puoi scrivere un codice come:

void updateSpecialData() {
     // do the update.
     emit SpecialDataUpdated();
}

void SpecialDataUpdatedHandler() {
     backupData();
}

void configureEventHandlers() {
     connect(SpecialDataUpdate, SpecialDataUpdatedHandler);
}

In assenza di un valido motivo per fare diversamente, segui la strada più semplice. Le tecniche come la gestione degli eventi sono potenti, ma aumentano la complessità del codice. Richiede più codice per funzionare, e rende più difficile seguire ciò che accade nel tuo codice.

Gli eventi sono molto critici nella giusta situazione (immagina di provare a programmare UI senza eventi!), ma non usarli quando puoi KISS o YAGNI.

    
risposta data 12.03.2016 - 23:03
fonte
13

L'esempio che descrivi di un semplice dato, in cui la modifica attiva alcuni effetti può essere perfettamente implementato con il schema di progettazione dell'osservatore :

  • questo è più semplice da implementare e gestire rispetto al codice completo basato sugli eventi.
  • l'accoppiamento tra soggetto e osservatore può essere astratto, il che facilita la separazione delle preoccupazioni.
  • è ideale per una relazione da uno a molti (i soggetti hanno uno o più osservatori).

L'approccio guidato dagli eventi vale il suo investimento per scenari più complessi, quando possono verificarsi molte diverse interazioni, in un contesto molti-a-molti o se sono previste reazioni a catena (per esempio un soggetto informa un osservatore, che in alcuni casi vuole per modificare il soggetto o altri soggetti)

    
risposta data 12.03.2016 - 22:13
fonte
5

Come dici tu, gli eventi sono un ottimo strumento per ridurre l'accoppiamento tra le classi; quindi, mentre può comportare la scrittura di codice aggiuntivo in alcune lingue senza il supporto integrato per gli eventi, riduce la complessità del quadro generale.

Gli eventi sono probabilmente uno degli strumenti più importanti in OO (secondo Alan Kay - Gli oggetti comunicano inviando e ricevendo messaggi ). Se utilizzi un linguaggio che ha il supporto integrato per gli eventi o tratta le funzioni come cittadini di prima classe, utilizzarle è un gioco da ragazzi.

Anche nelle lingue senza supporto integrato, la quantità di piastra di riscaldamento per qualcosa come il modello di Osservatore è abbastanza ridotta. Potresti essere in grado di trovare una libreria di eventi generica decente da qualche parte che puoi usare in tutte le tue applicazioni per ridurre al minimo lo standard. (Un aggregatore di eventi generici o un mediatore di eventi è utile in quasi tutti i tipi di applicazioni).

Vale la pena in una piccola applicazione? Direi sicuramente si .

  • Mantenere le classi separate l'una dall'altra mantiene pulito il grafico delle dipendenze delle classi.
  • Le classi senza dipendenze concrete possono essere testate isolatamente senza considerazione per altre classi nei test.
  • Le classi senza dipendenze concrete richiedono meno test unitari per una copertura completa.

Se stai pensando "Oh, ma in realtà è solo una piccola applicazione, non importa molto" , considera:

  • A volte le piccole applicazioni finiscono per essere combinate con applicazioni più grandi in seguito.
  • È probabile che le piccole applicazioni includano almeno alcuni componenti logici o componenti che possono essere successivamente riutilizzati in altre applicazioni.
  • I requisiti per le piccole applicazioni possono cambiare, sollecitando la necessità di refactoring, che è più facile quando il codice esistente viene disaccoppiato.
  • È possibile aggiungere funzionalità aggiuntive in un secondo momento, suggerendo la necessità di estendere il codice esistente, che è anche molto più semplice quando il codice esistente è già disaccoppiato.
  • Generalmente, il codice con accoppiamento lento non richiede molto più tempo rispetto al codice strettamente accoppiato; ma il codice strettamente accoppiato richiede molto più tempo per il refactoring e per il test rispetto al codice liberamente accoppiato.

Nel complesso, la dimensione di un'applicazione non dovrebbe essere un fattore decisivo per mantenere le classi unite liberamente; I principi SOLID non sono solo per le grandi applicazioni, ma si applicano a software e basi di codice su qualsiasi scala.

In effetti, il tempo risparmiato in unità che testano in isolamento le classi unidoneamente accoppiate dovrebbe controbilanciare ogni ulteriore tempo dedicato al disaccoppiamento di quelle classi.

    
risposta data 12.03.2016 - 22:33
fonte
2

Il modello di osservatore può essere implementato in un modo molto più piccolo rispetto a articolo di Wikipedia (o il libro del GOF) descrive Supponendo che i tuoi linguaggi di programmazione supportino qualcosa come "callback" o "delegati". Basta passare un metodo di callback nel tuo codice CRUD (il metodo observer, che potrebbe essere un metodo generico "write-to-file" o uno vuoto). Invece di "attivazione evento" basta chiamare quella richiamata.

Il codice risultante sarà solo il minimo complesso di chiamare direttamente il codice di generazione file, ma senza gli svantaggi dell'accoppiamento stretto di componenti non correlate.

Questo ti porterà "il meglio di entrambi i mondi", senza sacrificare il disaccoppiamento per "YAGNI".

    
risposta data 13.03.2016 - 11:56
fonte

Leggi altre domande sui tag