从库公开 API 的最佳方式

发布于 2024-12-09 11:23:28 字数 1010 浏览 1 评论 0原文

我正在设计一个 Win32 库来解析文件的内容(列和值)并将其内部存储在数据结构(映射)中。现在我需要公开 API,以便消费者可以调用这些 API 来获取结果。

该文件可能具有不同的格式,例如 FM1、FM2 等。消费者可能会这样查询:

FM1Provider.GetRecords("XYZ");
FM2Provider.GetRecords("XYZ");

我计划做的是拥有一个 CParser 类来完成所有解析并公开该类。

CParser
{
  bool LoadFile(string strFile);
  Map<string,string> GetFM1Records(string key);
  Map<string,string> GetFM1Records(string key);
};

或者

   class CResultProvider
   {
     virtual Map<string,string> GetRecords(string key)=0;
   }

   class CFM1ResultProvider : public CResultProvider
   {
      Map<string,string> GetRecords(string key);
   }

   class CFM2ResultProvider : public CResultProvider
   {
      Map<string,string> GetRecords(string key);
   }

   CParser
   {
      bool LoadFile(string strFile);
      CResultProvider GetFM1ResultProvider();
      CResultProvider GetFM1ResultProvider();
   };

考虑到我正在开发一个库,请建议我其中哪一种方法是正确且可扩展的。

I am designing a Win32 library to parse the contents of the file (Columns and Values) and store it internally in a datastructure (Map). Now i need to expose API's so that the consumer can call those API's to get the results.

The file may have different formats eg FM1, FM2 etc. The consumer may query like

FM1Provider.GetRecords("XYZ");
FM2Provider.GetRecords("XYZ");

What i am planning to do is to have a CParser class that does all the parsing and expose the class.

CParser
{
  bool LoadFile(string strFile);
  Map<string,string> GetFM1Records(string key);
  Map<string,string> GetFM1Records(string key);
};

or

   class CResultProvider
   {
     virtual Map<string,string> GetRecords(string key)=0;
   }

   class CFM1ResultProvider : public CResultProvider
   {
      Map<string,string> GetRecords(string key);
   }

   class CFM2ResultProvider : public CResultProvider
   {
      Map<string,string> GetRecords(string key);
   }

   CParser
   {
      bool LoadFile(string strFile);
      CResultProvider GetFM1ResultProvider();
      CResultProvider GetFM1ResultProvider();
   };

Please suggest me which one of these approaches are correct and scalable considering i am developing a library.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

网白 2024-12-16 11:23:29

您的组件似乎正在处理两个问题:解析和存储。将它们分成不同的组件以便它们可以独立使用是一个很好的设计实践。

我建议您仅向解析器提供解析数据的回调。这样,用户可以选择最适合其应用程序的容器,或者可以选择应用和丢弃读取的数据而不存储。

例如:

namespace my_lib {

struct ParserCb {
    virtual void on_column(std::string const& column) = 0;
    virtual void on_value(std::string const& value) = 0;

protected:
    ~ParserCb() {} // no ownership through this interface
};

void parse(char const* filename, ParserCb& cb);

} // my_lib

顺便说一句,更喜欢使用命名空间,而不是在类中添加 C 前缀

Your component seems to be dealing with two problems: parsing and storing. It is a good design practise to separate these into different components so that they can be used independently.

I would suggest you provide the parser only with callbacks for parsed data. This way the user of it can choose the most suitable container for her application, or may choose to apply and discard read data without storing.

E.g.:

namespace my_lib {

struct ParserCb {
    virtual void on_column(std::string const& column) = 0;
    virtual void on_value(std::string const& value) = 0;

protected:
    ~ParserCb() {} // no ownership through this interface
};

void parse(char const* filename, ParserCb& cb);

} // my_lib

BTW, prefer using namespaces instead of prefixing your classes with C.

你曾走过我的故事 2024-12-16 11:23:29

假设客户端只需调用 GetRecords 一次,然后使用地图,第一种方法我更喜欢第一种方法,因为它更简单。

如果客户端必须在代码中的不同位置重新加载地图,那么第二种方法是更好的选择,因为它使客户端能够针对一个接口 (CResultProvider) 编写代码。因此,他只需选择不同的实现即可轻松切换文件格式(他的代码中应该有一个地方选择了该实现)。

Assuming the client would only have to call GetRecords once, and then work with the map, the first approach I prefer the first approach because it is simpler.

If the client has to reload the map in different places in his code, the second approach is preferable, because it enables the client to write his code against one interface (CResultProvider). Thus, he can easily switch the file format simply by selecting a different implementation (there should be exactly one place in his code where the implementation is chosen).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文