dimanche 25 février 2018

Separating write function from calculation (design)

I am currently in refactoring my code. I try to use more OOP features instead of using one large main function. Though I struggle with using the right approach to separate the calculation from writing the file. I want to use the write(...) routine as an interface, so I can swap out the ParallelWriter with, say NullWriter. Is using a template in an interface a right choice?

Since the writing is actually not very much, I don't want it to stand in the way of the calculation. So enqueue_write actually just blocks for a moment and buffers the data. In any case, both ParallelWriter and Calc have to know about struct d, right? So if for example Calc is using some OpenCL which is placed inside struct d, I have to include the same header files in both compilation units?

From a design perspective, is using a pointer to Writer is the right approach? I mean, its non-owning, and has to be flexible. Or should Calc own the writer because it has to know about the datastructure struct d?

Note: I use struct to keep the code a bit shorter. Also, I do not know a lot about programming design principles.

struct d {cl_uint x;};
template <class T> struct Writer {
  virtual ~Writer() {}
  virtual void enqueue_write(T &data) = 0;
  virtual void close() = 0;
};
struct ParallelWriter : public Writer<std::unique_ptr<struct d>> {
  void enqueue_write(std::unique_ptr<struct d> &data) override {
    std::cout << "move into internal buffer, gets written somewhen. "
                 "Calculation can continue\n";
  }
  void close() override { /* ... */ }
};
struct Calc {
  Calc(Writer<std::unique_ptr<struct d>> *writer) { m_writer = writer; }
  void run(int param) {
    std::cout << "allocate struct s, work on it w/ param, send to writer\n";
    auto data = std::make_unique<struct d>();
    data->x = static_cast<cl_uint>(2 * param);
    m_writer->enqueue_write(data);
  }
  void stop() {}
  Writer<std::unique_ptr<struct d>> *m_writer = nullptr;
};
int main() {
  auto writer = ParallelWriter{/*filename*/};
  auto calculation_object = Calc{&writer /*, options */};
  calculation_object.run(42);
  calculation_object.stop();
  writer.close();
}

Cheers, Jonas

Aucun commentaire:

Enregistrer un commentaire