c++ - 将功能放入 API 或让开发人员自己制作的标准

标签 c++ api interface class-design utility-method

<分区>

我正在定义一个抽象基类作为 API 的一部分,供其他开发人员使用,这有点像定义 Android API 并让开发人员使用它来制作手机应用程序。 API 的创建者(也就是我)何时应提供特定功能,创建者何时应将其留给开发人员(即 API 的用户)来定义该功能?

这是一个相关的例子:假设我正在定义 MyObj 的一般树(用户可以在其中创建从 MyObj 派生的类并有 child , parent , 并且可以通过类型和值进行过滤。

class MyObj
{
 public:
  // These must be provided
  MyObj const * parent();
  bool setParent(MyObj const * i_obj);

  std::vector<MyObj const * > children() const;
  bool addChild(MyObj const * i_obj);
  bool removeChild(MyObj const * i_obj);


  // The following functions can be implemented
  // by using the functions listed above.
  // Should I provide them (by leaving them in the class or
  // defining them as utility functions, etc), or should I let 
  // the developers define them?
  MyObj const * root() const;
  bool hasChild(MyObj const * i_obj) const;
  std::vector<MyObj const * > descendants() const;
  std::vector<MyObj const * > childrenFiltered(FilterType i_type, FilterValue i_val) const;
  std::vector<MyObj const * > descendantsFiltered(FilterType i_type, FilterValue i_val) const;

 private:
  std::vector<MyObj * > m_children;
  MyObj * m_parent;
};

需要考虑的事项:

  • 如果它涉及使用私有(private)变量以致于开发人员(API 的用户)不能自己提供该功能,那么我必须提供它。
  • 如果某些功能将被许多开发人员(API 的用户)使用,请自行定义。这样,开发人员 A 就不需要开发开发人员 B 开发的同一套极其有用的实用功能;他们都会使用我提供的。
    • 另一方面,也许最好不要尝试预测如何使用基类,而是提供允许开发人员做任何他们想做的事所需的最少功能。
  • 如果该功能是核心功能,请提供它(即使它可以仅使用其他公共(public)功能来实现)
    • 确定某事是否是核心功能似乎是一件相当模糊的事情

相关帖子:

最佳答案

图书馆设计是一项相当复杂的工作,需要考虑许多不同的事情。根据我对这个主题的笔记,我可能会写一本书。上面的问题似乎集中在个别类(class)上,这就是这个答案的内容。如果事情变得更复杂,例如如果您有用于类或算法的系统,那么在决定将什么放在哪里时会出现更多层的复杂性。

对于类来说,基本规则其实比较简单:

  1. 类(class)应足够。也就是说,您需要抽象的基本部分以及维护类内部完整性所必需的一切:一旦构造对象将保持有效状态直到销毁(可能的异常(exception)是成员函数仅支持基本异常保证可能会将对象变成仅可破坏状态;你应该努力不要有任何这些)。
  2. 类(class)应该有效率。也就是说,如果公开的接口(interface)不允许有效实现典型用例,但使用类的内部结构可以支持这一点,那么提供相应的功能可能是个好主意。例如std::list<T>::sort()可以比使用例如更有效std::merge_sort()在公开的迭代器上。
  3. 类(class)应该是最小的。 不要包含任何使对象变大的东西,因为它会“很好”。
  4. 可选地,您可能希望提供本质上的转发功能,使界面更美观。例如,在一个序列上,您可能希望有一个 push_back()功能而不是要求用户使用类似 cont.insert(value, cont.end()) 的东西.任何编写起来不简单但可以用界面完成的事情都是界面的一部分。

在某种程度上,这让您获得了一个非常简单的类(class)。用户可以使用它编写自己的算法。为了避免大量重复,您可能还想提供可能根据您的类的抽象实现的算法。例如,如果您的类代表一棵树,则对节点的所有子节点进行操作的算法应该适用于所有类型的树。例如,std::find()适用于所有序列。将它添加到容器只有在容器可以做得更好的情况下才有意义,例如当您搜索容器的键类型时关联容器的情况。如果你需要找别的东西std::find()即使是这些,也是您想要的。然而,创建合适的算法库并提出合适的抽象比创建体面的类要困难得多。

顺便说一句,您上面的“界面”会让我搜索替代库。如果没有,我会认真考虑是否可以选择自己创建。在我考虑使用它之前,具有公开特定容器或指针的接口(interface)的 C++ 库需要增加相当多的值(value)。

关于c++ - 将功能放入 API 或让开发人员自己制作的标准,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8946012/

相关文章:

c++ - 显式赋值与隐式赋值

c++ - 复制赋值运算符说明

api - 如何使用 Slack API 发送 "@here"?

api - 使用Graph API以粉丝页面(而不是用户)的身份发布到粉丝页面

java - 在 FragmentActivity 中初始化接口(interface)

java - 界面最佳实践

Java List 和 Collection 抽象方法不指定主体

c++ - 如何使用 UART 板从 DS​​18B20 读取温度

python - 在 python 中线程化 c++ 程序

javascript - Google Drive API 中的开发者 key 无效