Esiste un modello di progettazione per tali eventi con conferma?

4

Contesto

Esiste un'applicazione C ++ modulare. Ogni modulo fornisce un'interfaccia (una classe astratta) che viene utilizzata da altri moduli. Non ci sono dipendenze circolari. L'interazione del modulo avviene tramite chiamate al metodo diretto in un modo e tramite eventi (una variazione del pattern dell'osservatore, simile ai segnali di Qt) nell'altro modo.

Ad esempio:

// an interface towards the battery manager
class IBatteryManager
{
public:
    // get the battery level
    virtual int batteryLevel() = 0;
    // the system is about to run out of battery and enter
    // a power saving mode
    virtual Event<> &aboutToRunOutOfBattery() = 0;
};

La classe Event ha il seguente aspetto:

template<typename... tArgs>
class Event
{
public:
    // client: the provided function will be called when this
    //         event is emitted
    void subscribe(std::function<void(tArgs...)>);
    // server: emit the event
    void notify(tArgs...);
};

Problema e possibile soluzione

A volte un evento fire-and-forget non è abbastanza. Un modulo potrebbe voler informare i suoi clienti su alcuni eventi e attendere fino a quando non vengono elaborati (e magari recuperare alcuni valori).

Ad esempio, BatteryManager potrebbe voler attendere che tutti i client abbiano elaborato l'evento circa l'esaurimento della batteria prima di accedere alla modalità di risparmio energetico.

Posso immaginare più modi in cui ciò può essere fatto. Uno di questi sarebbe quello di estendere la classe Event con lo schema futuro / promesso nel seguente modo:

template<typename tValue, typename... tArgs>
class Event
{
public:
    // client: now must return some value
    void subscribe(std::function<Future<tValue>(tArgs...)>);
    // server: this future is fulfilled as soon as all clients
    //         have completed their promises
    Future<std::vector<tValue>> notify(tArgs...);
};

Domande

Aggiornato: ho riformulato alcune domande per essere più chiaro.

Esiste un modello di progettazione che descrive l'approccio mostrato sopra? In altre parole, tale approccio ha un nome comunemente accettato, un vocabolario, pro / contro, un'implementazione canonica, una lista di cose alle quali bisogna prestare attenzione e altre cose quali sono i modelli di solito?

Sto chiedendo perché questo potrebbe non essere un problema che è unico per me. Quindi non voglio finire per reinventare la ruota, sia in termini di implementazione (probabilmente rifacendo gli errori di qualcun altro) che di terminologia (introducendo i miei termini, che renderanno più difficile la comunicazione con gli altri sviluppatori).

Domande secondarie: ci sono forse approcci migliori? Quale sarebbe la migliore pratica in questo caso?

    
posta Kane 30.10.2017 - 16:59
fonte

1 risposta

2

Il punto del modello "Evento" è la fonte non sa o cura se sono collegati degli ascoltatori. La fonte è disaccoppiata dai client. Gli eventi spesso sono eseguiti in modo sincrono, ma la fonte non dovrebbe nemmeno saperlo.

Ma nel tuo caso vuoi aspettare un valore di ritorno, il che significa che sei a seconda del cliente e stai facendo ipotesi sul comportamento del cliente (altrimenti non ti importerebbe aveva finito di elaborare o meno). Quindi hai una dipendenza diretta, il che significa che la fonte dovrebbe semplicemente andare avanti e chiamare direttamente il metodo - salta tutta l'indiretta con abbonamento e quant'altro.

In breve, ciò che stai cercando di fare non è riconosciuto come un "pattern", poiché è così semplice: vuoi chiamare un metodo su un altro oggetto.

    
risposta data 30.10.2017 - 19:09
fonte

Leggi altre domande sui tag