Quali sono i vantaggi del modello delegato rispetto al modello osservatore?


9

Nel modello delegato , solo un oggetto può ascoltare direttamente gli eventi di un altro oggetto. Nel modello di osservatore , qualsiasi numero di oggetti può ascoltare gli eventi di un particolare oggetto. Quando si progetta una classe che deve notificare altri oggetti di eventi, perché mai utilizzare il modello delegato sul modello osservatore? Vedo il modello di osservatore come più flessibile. Al momento potresti avere un solo osservatore, ma un progetto futuro potrebbe richiedere più osservatori.


4
Cosa intendi con "modello delegato"? Se stai parlando di qualcosa come i delegati di .net, puoi avere tutti gli abbonati che desideri.
Codici InCos

Correlati, anche se più focalizzati sul cacao: NSNotificationCenter vs delega (usando i protocolli)?
mouviciel,

Risposte:


7

Non esiste un modello delegato di per sé. Suppongo che intendi il modello di delega .

A quanto ho capito, sono il contrario completo e usati per scopi diversi.

Generalmente, con un modello di osservatore , qualsiasi numero di oggetti osservatore ascolta un evento su un secondo oggetto e agisce sull'evento. Il secondo oggetto non ha conoscenza dei suoi ascoltatori. Li chiama e basta.

Un oggetto delegato viene passato al secondo oggetto che chiama i metodi direttamente sul delegato. E qui sta il vantaggio che stai cercando. Invece di inviare un singolo messaggio a più listener, ha il controllo completo su un singolo oggetto (in un determinato momento). Vedi anche Inversion of Control .


6

Stai guardando le cose in modo errato. Un osservatore vede che si verifica un evento particolare. Non ha alcun impatto né è proprietario. Un delegato gestisce un evento particolare e ha la proprietà del gestore, anche se il delegatore possiede l'interfaccia per l'evento.


1
Un delegato non è altro che un osservatore di un evento. Un delegato non deve "gestire" nulla. Non può assolutamente fare nulla e non influenzerà (o almeno non dovrebbe) influenzare l'istanza che ha attivato l'evento.
Marjan Venema,

5
@MarjanVenema - se l'oggetto A non sta delegando la responsabilità dell'evento all'oggetto B, non stai usando il modello di delega: stai usando il modello di osservatore con un solo osservatore.
Telastyn,

Sì, è quello che stavo pensando. Ho inteso delegato per essere i tipi di firma dell'evento che devono essere utilizzati dal sottoscrittore di un evento "OnWhatever". Apparentemente i delegati in C # non sono abbonati singoli come lo sono ad esempio Delphi.
Marjan Venema,

@Marjan Venema "Un delegato non è altro che un osservatore di un evento." - dipende dalla lingua di cui stai parlando. Nell'obiettivo C, alcuni delegati sono responsabili della fornitura di dati, ad esempio i delegati dei dati, e un oggetto mancante di un delegato dei dati non ha dati da presentare. In questi casi, sta accadendo una delega, distinta dall'atto di osservare semplicemente qualcosa.
occulus

1
@occulus: grazie per il chiarimento. Peccato che le lingue non possano concordare sulla terminologia ... Parlare di programmazione in un modo agnostico linguistico diventa un po 'difficile quando le persone capiscono cose diverse con le stesse parole.
Marjan Venema,

4

Questa è una questione di numerosi compromessi.

Trade-off:

  • flessibilità (in termini di avere n> 1 delegati / osservatori)
  • costo di invio di un messaggio
  • resilienza (capacità di sostenere indisponibilità di delegati / osservatori)
  • facilità d'uso

Modello delegato:

  • non molto flessibile: non è possibile aggiungere più di 1 delegato (implica una qualche forma di "multi-delegato", cioè un modello di osservatore)
  • l'invio di un messaggio è economico, O (1) - stesso costo della chiamata a qualsiasi altra funzione o metodo (nessuna ricerca, coda di messaggi o altra infrastruttura richiesta)
  • di solito non resilienti - ci si aspetta che siano presenti delegati che svolgono la loro parte del lavoro, vale a dire che il mittente tende a fallire se non si conosce il delegato
  • facile da afferrare, facile da implementare

Modello di osservatore:

  • molto flessibile - l'aggiunta di n> 1 osservatori è prevista in base alla progettazione
  • l'invio di un messaggio ha un costo implicito dal numero di osservatori, O (n), vale a dire che n osservatori impiegano n tempo e messaggi (almeno in un'implementazione ingenua)
  • di solito resiliente - gli osservatori non sono generalmente tenuti a svolgere alcun lavoro da parte del mittente. Questo anche se non c'è osservatore, il mittente non è interessato
  • può diventare piuttosto complesso da comprendere, in particolare gli osservatori dovrebbero reagire ai messaggi (importa l'ordine ?, quale osservatore risponde in che modo?)

1

Il modello delegato, come ho capito, è noto come meccanismo di gestione degli eventi in altre lingue, ad esempio Delphi. In quanto tale, è semplicemente un'implementazione del modello di osservatore con un'importante restrizione: un solo ascoltatore alla volta.

Lo svantaggio di gestori di eventi o delegati è evidente: un solo osservatore.

Il vantaggio non è così evidente: prestazioni. Con un modello di osservatore puoi aggiungere molti osservatori. Quando si verifica un evento di cui gli osservatori devono essere informati, sarà necessario enumerare gli osservatori e inviare una notifica a ciascuno. Ciò può impantanare rapidamente qualsiasi istanza osservata, specialmente quando anche il numero di eventi che richiedono una notifica è significativo.


Eh? Il delegato C # è solo la firma di un metodo come tipo variabile (equivalente, ad esempio, int (*my_int_f)(int)in C). Ho sempre pensato che avrebbero reso più facile la comprensione rendendolo più simile a struct / enum. Un evento è un hook per un array flessibile di listener, che utilizza una firma a singolo delegato. Si potrebbe farlo senza un evento (che è il motivo per cui suppongo che il PO significava modello Delegazione, che è molto diverso), ma la lingua sta rendendo più facile per voi.
pdr

hmm. Non ancora ben versato in C #. Ho capito che i delegati erano l'equivalente dei tipi di firma degli eventi usati dagli eventi "OnWhatever" per esempio in Delphi. Quindi gli eventi C # possono essere sottoscritti da più ascoltatori?
Marjan Venema,

L'azione generica <T> è un delegato. Non ha nulla a che fare con gli eventi, è una variabile che viene passata in giro. E sì, più ascoltatori possono ascoltare un evento.
pdr,

ok grazie, spero di riuscire ad andare dritto ... :-) Ho eliminato il riferimento C # e mi sono concentrato maggiormente sul meccanismo dell'evento.
Marjan Venema,

1

Questo è un vecchio post, ma ho intenzione di suonare comunque perché le altre risposte non trattano di ciò che accade quando si utilizza uno dei due schemi, sembrano essere più sulla teoria che sulla pratica.

Come funzionano la delegazione e l'osservatore

Con la delega, il delegato sceglie esattamente chi risponderà a un determinato evento nel momento in cui viene creata la fonte del potenziale evento. Potresti pensare a questo ascoltatore come a un singolo osservatore . Nel caso del modello Observer, l'osservatore sceglie chi sta osservando ogni volta che ne ha voglia; così le dipendenze sono invertite quando si tratta di osservatore vs delegazione. Con il modello di osservatore, pensa a un giornale e agli abbonati come osservatori. Gli osservatori hanno il controllo di quando viene creata la relazione. Con delega pensa a un dipendente e un datore di lavoro. Il datore di lavoro ha il controllo di quando viene creata la relazione e di chi si occupa di eventi specifici. I dipendenti non possono scegliere quali compiti stanno lavorando ... in generale.

Alcuni sostengono che una delegazione possa avere un osservatore, ma penso che la vera differenza tra i due sia il modo in cui viene assegnata la gestione degli eventi. Non vedrai mai un registro delegato per un evento. Non saprà mai che gestirà l'evento fino a quando non si verificherà e il delegatore chiama un metodo pubblico su di esso.

Vantaggio di delega

Questo modello è molto rigido e con la maggior parte dei disegni regidi è più semplice e generalmente più robusto. Ti costringe a dichiarare il gestore dell'evento in anticipo al momento dell'inizializzazione della fonte del potenziale evento. Se hai bisogno di qualcuno per dirigere il traffico, assegni un direttore del traffico prima di aprire la strada. Nel caso dell'osservatore, lasci che il poliziotto del traffico scelga quando dirigere il traffico ogni volta che ne ha voglia.

Svantaggio della delega

Lo svantaggio di questo design è che non è flessibile. Se stai implementando un codice per abbonarti a un giornale, il giornale / delegato dovrebbe identificare esattamente chi può leggere le notizie nel momento in cui vengono create. Con il modello di osservatore possono essere registrati in un secondo momento in qualsiasi momento e il giornale dovrà solo sapere che una nuova persona si è registrata.

Quando scegliere la delegazione?

Se hai sicuramente bisogno di uno o più osservatori specifici e non hai motivo di cambiare chi sta osservando, allora il design rigido del modello di delega sarà utile.

Ad esempio, è necessaria una classe / oggetto per gestire la creazione di un popup per un errore specifico. Non ci sono molti motivi per cui in fase di esecuzione dovresti cambiare chi gestisce un errore specifico, quindi delegare l'errore "Memoria insufficiente" a una singola entità avrebbe senso. La creazione di una matrice di potenziali gestori e quindi la registrazione di tali gestori per l'errore "Memoria insufficiente" non avrebbe molto senso; quello sarebbe un esempio dell'uso del modello di osservatore in questa situazione. In fase di runtime potresti voler cambiare quali metodi vengono chiamati o quali "delegati" vengono chiamati per eventi variabili ma sostituire un gestore di eventi per un evento specifico in fase di runtime non è normale.

Non è impossibile scambiare i delegati come faresti nel modello di osservatore, è solo complicato. Nel mondo reale forse vuoi scambiare poliziotti in modo che un nuovo delegato stia gestendo il traffico. Si potrebbe sostenere che un design migliore renderebbe un delegato originale una stazione di polizia e non un singolo ufficiale di polizia, ma sto divagando ...

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.