samedi 27 juillet 2019

Observer with a call back to the observed class

How to nicely express something like the observer pattern which returns observed object to the observers?

I need to have a class which is able to periodically query other components to generate some sort of data (I called it sample in the code below) and then process the received data.

The problem is that data generator functions are complex and may generate a significant number of samples. It would be nice to pass them back to the manager as return values and then manager can process them without exposing any other functions. But unfortunately that does not work due to memory constraints (I use C++ without dynamic memory allocations, so no way to move data).

What I have below is broken in two ways: 1) SampleManager exposes unrelated responsibilities, one to register observers and call them, second to process the data. 2) The components using sample manager get it back in the callback and they already have the pointer.

Any idea how I can fix/improve the design?

class ISampleReceiver
{
public:
      virtual void receive(const sample&) = 0;
};

using SampleGeneratorFn = std::function<void(ISampleReceiver*)>;

class SampleManager : public ISampleReceiver
{
      registerSampleGenerator(SampleGeneratorFn);

      virtual void receive(const sample&) {
             // process the sample
      }
};    

And the usage, from multiple different components:

void generator(ISampleReceiver* r)
{
   while (...) {
     sample s = {...}; // generate objects

     r.receive(s);
   }
}

SampleManager manager;

// initialise the manager
manager.registerSampleGenerator(generator);

Aucun commentaire:

Enregistrer un commentaire