Tôi đang đánh giá một thư viện có API công khai hiện tại trông như thế này:
libengine.h
/* Handle, used for all APIs */ typedef size_t enh; /* Create new engine instance; result returned in handle */ int en_open(int mode, enh *handle); /* Start an engine */ int en_start(enh handle); /* Add a new hook to the engine; hook handle returned in h2 */ int en_add_hook(enh handle, int hooknum, enh *h2);
Lưu ý rằng đó enh
là một tay cầm chung, được sử dụng như một tay cầm cho một số kiểu dữ liệu khác nhau ( động cơ và móc ).
Trong nội bộ, hầu hết các API này dĩ nhiên chuyển "xử lý" sang cấu trúc bên trong mà chúng đã malloc
:
động cơ.c
struct engine { // ... implementation details ... }; int en_open(int mode, *enh handle) { struct engine *en; en = malloc(sizeof(*en)); if (!en) return -1; // ...initialization... *handle = (enh)en; return 0; } int en_start(enh handle) { struct engine *en = (struct engine*)handle; return en->start(en); }
Cá nhân, tôi ghét giấu những thứ đằng sau typedef
s, đặc biệt là khi nó ảnh hưởng đến sự an toàn kiểu. (Đưa ra một enh
, làm thế nào để tôi biết những gì nó thực sự đề cập đến?)
Vì vậy, tôi đã gửi yêu cầu kéo, đề xuất thay đổi API sau (sau khi sửa đổi toàn bộ thư viện để tuân thủ):
libengine.h
struct engine; /* Forward declaration */
typedef size_t hook_h; /* Still a handle, for other reasons */
/* Create new engine instance, result returned in en */
int en_open(int mode, struct engine **en);
/* Start an engine */
int en_start(struct engine *en);
/* Add a new hook to the engine; hook handle returned in hh */
int en_add_hook(struct engine *en, int hooknum, hook_h *hh);
Tất nhiên, điều này làm cho việc triển khai API nội bộ trông tốt hơn rất nhiều, loại bỏ các phôi và duy trì an toàn loại đến / từ quan điểm của người tiêu dùng.
libengine.c
struct engine
{
// ... implementation details ...
};
int en_open(int mode, struct engine **en)
{
struct engine *_e;
_e = malloc(sizeof(*_e));
if (!_e)
return -1;
// ...initialization...
*en = _e;
return 0;
}
int en_start(struct engine *en)
{
return en->start(en);
}
Tôi thích điều này vì những lý do sau:
- Đã thêm loại an toàn
- Cải thiện sự rõ ràng của các loại và mục đích của chúng
- Loại bỏ phôi và
typedef
s - Nó tuân theo mô hình được đề xuất cho các loại mờ trong C
Tuy nhiên, chủ sở hữu của dự án đã bỏ qua yêu cầu kéo (diễn giải):
Cá nhân tôi không thích ý tưởng phơi bày
struct engine
. Tôi vẫn nghĩ rằng cách hiện tại là sạch sẽ và thân thiện hơn.Ban đầu tôi sử dụng một kiểu dữ liệu khác cho tay cầm hook, nhưng sau đó quyết định chuyển sang sử dụng
enh
, vì vậy tất cả các loại tay cầm đều chia sẻ cùng một kiểu dữ liệu để giữ cho nó đơn giản. Nếu điều này gây nhầm lẫn, chúng tôi chắc chắn có thể sử dụng một loại dữ liệu khác.Hãy xem những gì người khác nghĩ về PR này.
Thư viện này hiện đang ở giai đoạn beta riêng tư, vì vậy không có nhiều mã người tiêu dùng phải lo lắng (chưa). Ngoài ra, tôi đã xáo trộn tên một chút.
Làm thế nào là một tay cầm mờ tốt hơn so với một cấu trúc mờ có tên?
Lưu ý: Tôi đã hỏi câu hỏi này tại Code Review , nơi nó đã bị đóng.