Quali sono gli "odori di codice" che sono un sintomo che è richiesto un modello di listener di eventi?


10

Quali sono i sintomi in una base di codice che indicano che è richiesto un approccio listener di eventi?

Mi sembra che quando ci sono classi che devono essere chiamate da più, non definite al set di altre classi in fase di progettazione, hai bisogno di una sorta di framework di segnalazione, ma vorrei sentire quali altre situazioni ci sarebbero migliorato passando a un modello basato su eventi.

Risposte:


8

L'approccio Event / Listener tenta di evitare l' accoppiamento stretto , quindi tutti gli odori di codice che indicano che, indicano l'approccio.

Sulla base di ciò, suggerirei i seguenti sintomi:

  • grandi costruttori , poiché ogni oggetto deve conoscere ogni altro oggetto e non può funzionare senza. Forse travestito da molti obj.set_dependecy(x)immediatamente dopo la chiamata del costruttore.

  • dipendenze bidirezionali , perché, senza eventi, in un linguaggio imperativo, il flusso di informazioni è sostanzialmente "push" (chiamando il metodo di qualcuno)

  • la "gerarchia della conoscenza" è difficile da determinare . Queste sono le dipendenze bidirezionali , solo un altro obiettivo: se c'è A, che ascolta B, A sa di B, ma B non di A, quindi c'è una 'gerarchia': alcuni oggetti non conoscono nulla, alcuni sanno altro , ecc. Ad esempio, quando si implementa MVC in questo modo: http://en.wikipedia.org/wiki/Model_View_Controller , il modello conosce solo se stesso, la vista conosce il modello e il controller conosce la vista e il modello.


1
Le dipendenze bidirezionali sono di gran lunga il segno più rivelatore che è necessario passare a un modello guidato dagli eventi. Il gonfiamento del costruttore potrebbe significare questo, ma il più delle volte non solo significa che devi fare di più in termini di aggregazione, composizione e / o astrazione generale (cioè refactoring, non modifiche del design).
Aaronaught,

Hai ragione. Ho provato a ordinarlo per facilità di rilevamento, e i grandi costruttori sono così semplici che potrebbero essere catturati da espressioni regolari.
keppla,

6

Quando non puoi o non dovresti sapere cosa dovrebbe reagire a una serie di messaggi / segnali / eventi.

Spesso è quando vuoi che "il mondo" sappia qualcosa che accade in un modulo (una classe o un sistema di classi) ma non vuoi preoccuparti di ciò che viene chiamato.

L'odore del codice associato, per essere precisi, è quando senti che inizi a mescolare il codice da moduli indipendenti, uno che fa qualcosa a cui l'altro dovrebbe reagire. Quando vedi che devi chiamare il codice dal modulo B in base allo stato / eventi del modulo A, hai bisogno di listener di eventi.


3

Vorrei cambiare la tua domanda e dire: quando un evento basato non è la soluzione giusta per un'applicazione orientata agli oggetti? Penso che la maggior parte delle applicazioni OO possano trarne vantaggio se sono progettate come produttori e consumatori di eventi.

Alla fine, una "chiamata di metodo" è in realtà un messaggio che arriva a un oggetto e l'oggetto è responsabile di decidere se sta per fare qualcosa con il messaggio ed eseguire l'operazione. Ciò non è molto chiaro in linguaggi fortemente tipizzati come Java, ma diventa più evidente in linguaggi dinamici come Ruby.

Un altro punto interessante della progettazione di un'applicazione basata sugli eventi è che di solito i componenti interni devono essere adeguatamente isolati e coerenti, altrimenti il ​​codice diventa un casino molto, molto rapidamente. Ad esempio, mi piace molto il concetto di Hexagonal Architecture utilizzato da Alistair Cockburn, poiché di solito questo modello crea un migliore incapsulamento e forza (a mio avviso) componenti più coerenti.

Penso (ma probabilmente sbaglio) che questo è anche correlato al concetto di Domain Driven Design di Domain Events , in cui le classi di dominio emettono eventi che sono catturati da altri oggetti e questi oggetti emettono ancora altri eventi (vedi dove questo sta andando: D). Quello che mi piace di questo modello è che dice che le interfacce dovrebbero modellare i ruoli, non le implementazioni.

Scusate se non ho molto senso, ho sperimentato questi schemi negli ultimi mesi con risultati sorprendenti, ma sto ancora cercando di capire i concetti e quanto raggiungono.


2

Pensa a cosa dovresti fare se gli ascoltatori di eventi (alias Observer Pattern) non esistessero.

Se hai un oggetto che ha riferimenti a un elenco di altri oggetti e chiama un metodo su di essi in un determinato punto del processo, avresti sicuramente dovuto avere un evento lì.

Se hai una bandiera su un oggetto per dire che qualcosa è stato fatto e stai guardando quella bandiera da altri oggetti, avresti sicuramente dovuto usare un modello guidato dagli eventi.

Tuttavia, non confonderlo con un callback. Se si chiama un metodo su un altro oggetto e si passa a un metodo sull'oggetto di origine a cui richiamare in un determinato momento, è necessario lasciarlo in questo modo, anziché utilizzare un listener di eventi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.