0

I am refactoring a biometric recognition SDK, which public API provide feature extraction and some CRUD feature management interface like:

class PublicComponent{
public:
  FeaturePublic extract_feature();
  int add_feature(const FeaturePublic&);
  void update_feature(int id, const FeaturePublic&);
  void delete_feature(int id);
}

The actual feature that all other private implementation component must to deal with is complicated, it contains many fields that we don't want to expose to the API user, like:

struct FeatureDetail{
  int detail1;
  int detail2;
  // ...
  float detailN;
};

And basically the PublicComponent just forward its job to these internal components.

So the gap occurred, basically all the public API accept or give back FeaturePublic as argument/result. However all other existed internal implementation heavily depends on FeatureDetail, they must touch the internal data member of feature. It just seems that we need to retrieve concrete type from the type erased public handle, but unable to publish the retrieve method. I've came up with two solutions, but either of them seems quirky.

Solution 1

Just use type erased raw buffer like std::vector<std::byte> or std::pair<std::byte*, size_t> as FeaturePublic.

It is simple, however, the cons is pretty straightforward: We just throw away the type safety that we already have, and i have to insert all the input data integrity check and serialize/deserialize code at all the public API border even though the caller might just add a feature that generated right before.

Solution 2

Use pimpl like idiom to hide FeatureDetail inside FeaturePublic.

// public api header
class FeatureDetail; // forward declartion

class FeaturePublic{
private:
  std::unique_ptr<FeatureDetail> detail_;
};

Under which we can maintain the type safety, however, to let the internal component to touch the concrete type FeatureDetail, we must have some way to let them retrieve a FeatureDetail from PublicComponent passed FeaturePublic. But since the detail_ field is a private member, The two ways that i can think of is to provide a get_raw method on FeaturePublic or make the field public, any of them seems pretty ugly.

user8510613
  • 1,242
  • 9
  • 27
  • I'm not sure I follow you. You have an `id` argument. Why don't you have a `map` (`vector`?) to retrieve the `FeatureDetail` by that `id`? – Dmytro Ovdiienko Jun 22 '22 at 10:13
  • Also user passes into the `add_feature` member function an instance of the `FeaturePublic` class which is created without the `FeatureDetail` under the hood. Because of that I'm not sure the Solution 2 is good to go. – Dmytro Ovdiienko Jun 22 '22 at 10:16
  • Yeah, I admit that when we started to using raw pointer, the so called "type safety" might be meaningless – user8510613 Jun 23 '22 at 03:05

0 Answers0