c - API 设计困境:不透明的句柄
问题描述
我正在设计一个库,该库试图在单个通用句柄 (1) 或其一组 (2) 下统一平台特定细节。
为了使问题更具体,我将提供两个实现的摘录和一个示例用法。
(1) 标记工会;包罗万象的类型:
enum tb_handle_kind {};
/* These two are never exposed to the user: */
struct tb_dir {
struct _WIN32_FIND_DATAW find_data;
HANDLE search_handle;
};
struct tb_file {
HANDLE native_handle;
};
struct tb_handle {
enum tb_handle_kind kind;
union {
struct tb_file file;
struct tb_dir dir;
};
};
您将通过以下方式使用它:
file_open(struct tb_handle *, const char *);
handle_close(struct tb_handle *);
struct tb_handle file;
file_open(&file, "path/to/file");
...
handle_close(&file); /* No need for a cast, or a file-specfic function. */
(2) 通用句柄作为其他人的基类:
struct tb_handle {
/* Fields shared by each handle. */
};
struct tb_dir {
struct tb_handle base; /* Now a "base class" of tb_dir. */
struct _WIN32_FIND_DATAW find_data;
HANDLE search_handle;
};
用法:
/* Either a pair of init/close functions. */
int dir_open(struct tb_dir *, const char *);
int dir_close(struct tb_dir *);
/* Or handle_close from the previous example, that now requires a cast: */
handle_close((struct tb_handle *) &some_dir);
据我所知,(1) 以牺牲类型安全为代价提供了一个更易于使用的 API,而 (2) 提供了更多的心理体操,并提高了安全性(您不能将错误类型的句柄传递给函数)。
从用户的角度来看,您更愿意使用哪一个?
解决方案
推荐阅读
- java - 使用 WSS4J 签署 XML。没有 ID 为“noXMLSig”的消息
- css - 我可以设置元素的大小以适应其潜在内容,而不是其实际内容吗?
- java - 为什么这个对象在这个 ArrayList 中作为“未知类”出现?
- php - 如何将所有访问文件夹的尝试重定向到索引,但服务器?
- c++ - vk::DeviceQueueCreateFlags() 实际上做了什么?
- php - 使用控制器转到其他页面时 $row 值丢失
- laravel - 如何找到重定向到 oauth 客户端回调的引用者
- swift - 在 Swift 中,您能否创建一个协议,该协议仅在关联类型的特定条件成立时才需要特定函数?
- javascript - 如何使用 JavaScript 将一个网站重定向到另一个网站?
- php - Php - 将数组中的数字一一相加