从库中公开API的最佳方式

时间:2011-10-13 06:44:13

标签: c++ oop dll

我正在设计一个Win32库来解析文件的内容(列和值),并将其内部存储在数据结构(Map)中。现在我需要公开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();
   };

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

2 个答案:

答案 0 :(得分:2)

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

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

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,更喜欢使用名称空间而不是prefixing your classes with C

答案 1 :(得分:1)

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

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