我正在编写一个包含 REST API 的库,并且表示一些数据需要使用 C 标准库中不可用的数据结构,例如哈希映射,因此在内部我使用 3rd 方库来实现它们。现在我想在响应结构中公开它们,我想出了几个解决方案:
hashmap_lib_get(users, "key")
获取值):// header.h (Include guards excluded)
#include <hashmap_lib.h>
struct api_response {
int field1;
char *field2;
HASHMAP_LIB_HM *users; // Map of users to their email. (example)
};
问题:需要额外的用户干预,如果使用通用宏实现库,问题就更大。
// header.h
struct api_response {
int field1;
char *field2;
void *users; // Don't touch
};
char *api_hashmap_get(void *hm, const char *key);
的内部实现api_hashmap_get
只是return hashmap_lib_get((HASHMAP_LIB_HM *) hm, key);
问题:需要重复各种函数定义并需要使用空指针。
这个问题在图书馆中通常是如何解决的?如果两个库彼此“相关”(例如使用事件系统libevent
来处理用户的应用程序),第一个解决方案就会有意义,但在这种情况下,它只是关于通用数据结构,因此没有意义对我来说,因为用户也会将其他库用于相同类型的数据结构。
我会以不同的方式描述优缺点。:
选项 1将第三方库的 API 合并到您自己的 API 中。谨慎处理这个问题既有技术上的原因,也有法律上的原因。
选项 2涉及提供您自己的 API 来操作第三方数据结构,并要求您放弃一些类型安全。另一方面,它将您的用户与 3p 库隔离。
你在评论里说
我想要关于改进选项 2 的建议,因为它感觉太冗长了。
,但是如果您不打算让用户通过他们的本地方式访问第三方数据结构,那么您别无选择,只能提供您自己的方式。如果您想将您的客户端与第三方库隔离,那么它必须表现为包装器函数。但是,您不必包装整个第三方 API,也不必将包装器表示为第三方函数/宏的直接类似物。
但也有这样的:
选项 3:使您自己的结构对您图书馆的客户不透明。这将要求您为您支持的所有类型的访问提供合适的函数,因此在这方面为您做更多的工作,但它允许您声明结构成员(仅供内部使用),但您认为这是最自然的。另外,所有访问都通过函数而不是其中的一些函数可能会感觉更一致。这使您可以轻松更改结构的细节,而不会破坏库的客户端。
面向客户端的标头可能如下所示:
struct api_response; // members not declared
int api_get_field1(const struct api_response *resp);
const char *api_get_field2(const struct api_response *resp);
const char *api_get_user_email(const struct api_response *resp, const char *user);
// ...
这将由仅提供(至少)完整定义的内部、非分布式标头补充struct api_response
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句