Là tốt hơn để tài liệu chức năng trong tệp tiêu đề hoặc tệp nguồn?


86

Trong các ngôn ngữ phân biệt giữa tệp "nguồn" và "tiêu đề" (chủ yếu là C và C ++), tốt hơn là ghi lại các chức năng trong tệp tiêu đề:

(lấy từ CCAN )

/**
 * time_now - return the current time
 *
 * Example:
 *  printf("Now is %lu seconds since epoch\n", (long)time_now().tv_sec);
 */
struct timeval time_now(void);

hoặc trong tập tin nguồn?

(lấy từ PostgreSQL)

/*
 * Convert a UTF-8 character to a Unicode code point.
 * This is a one-character version of pg_utf2wchar_with_len.
 *
 * No error checks here, c must point to a long-enough string.
 */
pg_wchar
utf8_to_unicode(const unsigned char *c)
{
...

Lưu ý rằng một số thứ chỉ được xác định trong tiêu đề, chẳng hạn như cấu trúc, macro và static inlinehàm. Tôi chỉ nói về những thứ được khai báo trong tệp tiêu đề và được xác định trong tệp nguồn.

Dưới đây là một số đối số tôi có thể nghĩ ra. Tôi đang nghiêng về tài liệu trong tệp nguồn, vì vậy các đối số "Tiêu đề Pro" của tôi có thể hơi yếu.

Tiêu đề chuyên nghiệp:

  • Người dùng không cần mã nguồn để xem tài liệu.
    • Nguồn có thể bất tiện, hoặc thậm chí là không thể có được.
    • Điều này giữ cho giao diện và thực hiện xa hơn.

Nguồn chuyên nghiệp:

  • Nó làm cho tiêu đề ngắn hơn rất nhiều, cho người đọc một cái nhìn toàn cảnh về mô-đun nói chung.
  • Nó ghép tài liệu của một chức năng với việc thực hiện của nó, làm cho nó dễ dàng hơn để thấy rằng một chức năng thực hiện những gì nó nói.

Khi trả lời, xin hãy cảnh giác với các lập luận dựa trên những công cụ và "IDE hiện đại" có thể làm gì. Ví dụ:

  • Tiêu đề chuyên nghiệp: Việc gấp mã có thể giúp làm cho các tiêu đề nhận xét có thể điều hướng nhiều hơn bằng cách ẩn các nhận xét.
  • Pro-source: tính năng của cscopeFind this global definition đưa bạn đến tệp nguồn (nơi định nghĩa là) chứ không phải tệp tiêu đề (nơi khai báo ).

Tôi không nói rằng đừng đưa ra những lập luận như vậy, nhưng hãy nhớ rằng không phải ai cũng thoải mái với các công cụ bạn sử dụng như bạn.


Câu hỏi tương tự có thể áp dụng cho Pascal / Delphi nơi chúng tôi không có tệp nguồn và tiêu đề, nhưng phần giao diện và phần triển khai.
Jan Doggen

Câu trả lời:


96

Quan điểm của tôi ...

  • Tài liệu làm thế nào để sử dụng chức năng trong tệp tiêu đề, hoặc chính xác hơn gần với khai báo.

  • Tài liệu về cách thức hoạt động của chức năng (nếu nó không rõ ràng từ mã) trong tệp nguồn, hoặc chính xác hơn, gần với định nghĩa.

Đối với điều mắt chim trong tiêu đề, bạn không nhất thiết cần tài liệu đóng - bạn có thể ghi lại các nhóm khai báo cùng một lúc.

Nói rộng hơn, người gọi nên quan tâm đến các lỗi và ngoại lệ (nếu chỉ để chúng có thể được dịch khi chúng di chuyển qua các lớp trừu tượng), vì vậy những điều này nên được ghi lại gần với các tuyên bố liên quan.


13
+1 - tức là ghi lại giao diện trong tiêu đề. Các chi tiết Gory về làm thế nào và tại sao trong nguồn.
quick_now

2
Đối với các tiêu đề thư viện nơi không có nguồn có sẵn, có thể thêm các điều kiện trước và sau, v.v ... để giúp kiểm tra. Cộng thêm hiệu suất O (n) nếu nó có ý nghĩa, vì vậy người dùng thư viện có thể chọn một cách khôn ngoan.
Patrick Hughes

Đương nhiên, đôi khi khai báo và định nghĩa là một và giống nhau.
Ded

@Ded repeatator - khi các quy tắc tương tự vẫn dẫn đến điều đúng ngay cả trong trường hợp đặc biệt, tại sao lại lặp lại các quy tắc đó cho mọi trường hợp đặc biệt? Chắc chắn một người sao chép không nên muốn điều đó?
Steve314

1
@Ded repeatator - tất nhiên đó là một lý do ồ ạt vì không làm theo lời khuyên của bạn, nhưng tôi vẫn kiên trì với nó.
Steve314

34

Nếu bạn sẽ sử dụng một công cụ như Doxygen (lưu ý trong ví dụ đầu tiên, nó thực sự trông giống như một nhận xét Doxygen vì nó bắt đầu bằng /**) thì nó không thực sự quan trọng - Doxygen sẽ xem qua các tệp tiêu đề và nguồn của bạn và tìm tất cả các ý kiến ​​để tạo tài liệu.

Tuy nhiên, tôi sẽ có xu hướng đưa các bình luận tài liệu vào các tiêu đề, nơi khai báo. Các khách hàng của bạn sẽ xử lý các tiêu đề để giao tiếp với phần mềm của bạn, các tiêu đề là những gì họ sẽ đưa vào trong các tệp nguồn của riêng họ và đó là nơi họ sẽ tìm kiếm đầu tiên để xem API của bạn trông như thế nào.

Ví dụ, nếu bạn xem hầu hết các thư viện Linux, hệ thống quản lý gói Linux của bạn thường có một gói chỉ chứa các nhị phân của thư viện (đối với người dùng "bình thường" có chương trình cần thư viện) và bạn có gói "dev" chứa các tiêu đề cho thư viện. Mã nguồn thường không được cung cấp trực tiếp trong một gói. Sẽ rất cồng kềnh nếu bạn phải lấy mã nguồn của thư viện ở đâu đó để lấy tài liệu về API.


2
+1 - với một bằng chứng rằng ngay cả khi bạn sử dụng Doxygen, điều đó không có nghĩa là bạn sẽ không bao giờ đọc trực tiếp từ nguồn. Các chú thích Doxygen thậm chí đôi khi hữu ích như các mẫu chuẩn cho grep, và thật tiện dụng nếu chú thích bạn tìm thấy gần với mã mà nó mô tả.
Steve314

1
@ Steve314 ofcference Tôi không nói rằng bạn sẽ không bao giờ muốn xem mã nguồn của một số thư viện - nhưng đó sẽ không phải là nơi đầu tiên bạn tìm kiếm API trông như thế nào và cách sử dụng nó.
Jesper

Tôi cũng sẽ ủng hộ để giữ mọi thứ liên quan đến API trong tiêu đề (hoặc ít nhất là trong tiêu đề hoặc nguồn), vì nó sẽ tránh được sự thiếu sót tiềm ẩn khi cập nhật tài liệu ở một nơi chứ không phải ở nơi khác.
jopasserat

12

Chúng tôi đã giải quyết vấn đề này (khoảng 25 năm trước) bằng cách tạo ra một loạt #defines (ví dụ: công khai, riêng tư, v.v., đã giải quyết <nothing>) có thể được sử dụng trong tệp nguồn và được quét bởi một tập lệnh awk (nỗi kinh hoàng !) để tự động tạo các tệp .h. Điều này có nghĩa là tất cả các ý kiến ​​sống trong nguồn và được sao chép (khi thích hợp) vào tệp .h được tạo. Tôi biết rằng đó là Trường học cũ, nhưng nó đã đơn giản hóa rất nhiều loại tài liệu nội tuyến này.


1
hmm tôi biết phong cách này có thể hữu ích, nhưng từ quan điểm của tôi, tôi luôn thấy loại tài liệu đó hết sức khó chịu ...
osirisgothra

1
Để diễn giải Donald Rumsfeld (một người đàn ông tôi không thích), "Bạn lập trình với các công cụ bạn có, không phải với các công cụ bạn muốn bạn có." Mỗi ngôn ngữ tôi đã làm việc trong hơn 40 năm qua đã có ít nhất một mụn cóc lớn (nếu không nói là nhiều hơn). Giải pháp của chúng tôi a) đã hoạt động, b) sử dụng các công cụ tồn tại vào thời điểm đó, c) chúng ta hãy dành thời gian để lấy mã tạo doanh thu ra khỏi cửa.
Peter Rowell

Mặc dù tôi có thể không chọn cách này, nhưng đây là một cách thú vị để xử lý các bình luận trong các tiêu đề. Các tiêu đề được tạo sẽ được kiểm soát phiên bản? hoặc đây là một số quy trình phát hành để tạo nguồn phân phối lại? (nhưng không được sử dụng bởi các nhà phát triển)
ideaman42

Ồ, tôi đã thấy mô hình tương tự gần đây trong một dự án bắt đầu từ năm 2000 và họ rất tự hào về phát minh thông minh của họ
5gon12eder

3
Trong trường hợp của chúng tôi, chúng tôi đã không giữ bất kỳ tệp nào được tạo dưới sự kiểm soát phiên bản vì chúng dễ dàng và trực tiếp (tái) từ các tệp được theo dõi.
Peter Rowell

9

Giả sử đây là mã trong một dự án lớn hơn (nơi các nhà phát triển sẽ di chuyển giữa nguồn và tiêu đề thường xuyên) và cung cấp đây không phải là thư viện / kho trung gian, nơi những người khác có thể không có quyền truy cập vào nguồn, tôi đã tìm thấy công việc này tốt...

  • Tiêu đề:
    Nhận xét 1-2 dòng, chỉ khi chúng cần thiết.
    Đôi khi ý kiến ​​trên một nhóm các chức năng liên quan cũng hữu ích.
  • Nguồn:
    Tài liệu về API trực tiếp trên hàm (văn bản thuần hoặc doxygen nếu bạn thích) .
  • Giữ chi tiết triển khai, chỉ liên quan đến nhà phát triển sửa đổi mã trong phần thân của hàm.

Lý do chính cho việc này là để giữ các bình luận gần với mã, tôi nhận thấy các tài liệu trong tiêu đề có xu hướng không đồng bộ với các thay đổi đối với mã thường xuyên hơn (tất nhiên là không nên, nhưng họ đã làm trong dự án của chúng tôi tại ít nhất) . Ngoài ra, các nhà phát triển có thể thêm tài liệu ở đầu các chức năng khi họ thực hiện một số thay đổi, ngay cả khi có tài liệu tiêu đề ... ở một nơi khác. Gây ra thông tin kép hoặc thông tin hữu ích chỉ ở một trong các chuỗi doc.

Tất nhiên bạn có thể chọn một quy ước và đảm bảo tất cả các nhà phát triển tuân theo, tôi chỉ tìm thấy quy ước trên phù hợp tự nhiên nhất và gây ra ít rắc rối nhất để duy trì.


Cuối cùng, đối với các dự án lớn - có khuynh hướng không thực hiện các chỉnh sửa nhỏ trong tiêu đề khi bạn biết rằng nó sẽ khiến các tệp 100 hoặc 1000 có khả năng biên dịch lại khi những người khác cập nhật kiểm soát phiên bản - cũng làm chậm các lỗi bis.


5

Theo ý kiến ​​của tôi (khá hạn chế và thiên vị), tôi là cách suy nghĩ mã nguồn thân. Khi tôi thực hiện các bit và phần trong C ++, tôi thường chỉnh sửa tệp tiêu đề một lần và sau đó tôi không bao giờ thực sự quay lại để xem nó.

Khi tôi đặt tài liệu vào tệp nguồn, tôi luôn thấy nó khi tôi chỉnh sửa hoặc đọc mã. Tôi đoán đó là một thói quen.

Nhưng đó chỉ là tôi ...


1
Không hoạt động tốt nếu tất cả những gì bạn có là một thư viện được biên dịch và tệp tiêu đề. Trong trường hợp đó, thêm thông tin trong tiêu đề là một điều tốt vì đó là tài liệu giao diện duy nhất bạn có.
quick_now

bạn có thể tạo tài liệu với doxygen - nó cũng lấy nó từ các tệp .c. Do đó bạn có thể phân phối tài liệu dễ dàng với các thư viện được biên dịch. Nhưng rắc rối sẽ xảy ra với IDE có thể phân tích cú pháp các tệp tiêu đề và cung cấp cho bạn tài liệu trong khi sử dụng chức năng ... Nhưng có lẽ nó có thể giải quyết một số tập lệnh triển khai sẽ sao chép các nhận xét chức năng frm .c vào .h ...
Vit Bernatik

5

Bình luận không phải là tài liệu. Tài liệu cho một chức năng thường có thể là 2K văn bản, có thể bằng sơ đồ - xem ví dụ tài liệu về các chức năng trong SDK Windows. Ngay cả khi nhận xét của bạn cho phép một điều như vậy, bạn sẽ làm cho mã chứa bình luận không thể đọc được. Nếu bạn muốn sản xuất tài liệu, hãy sử dụng trình xử lý văn bản.


cập nhật, rất dễ dàng để ghi lại những ngày này (với những thứ như người tạo Qt ngoài kia) để chỉ ghi lại cách doxygen (hoặc bản sao), ví dụ, trong qtc bạn chỉ cần nhấn phím / vài lần trước khi nhận xét và một nửa công việc được thực hiện cho bạn Bởi vì những thứ như thế này, tôi nghi ngờ mọi người sẽ muốn chuyển sang một trình xử lý văn bản chỉ để ghi lại mã của họ. Tôi đã từng làm điều này, được cấp, trở lại vào năm 2005, nhưng tôi sẽ không bao giờ làm điều đó bây giờ. Ngay cả việc sử dụng một trình soạn thảo html dường như khá cổ xưa.
osirisgothra

@osirisgothra Doxygen- "tài liệu" có thể dễ thực hiện và chắc chắn tạo ra rất nhiều chữ viết nhanh chóng, nhưng giá trị của "tài liệu" được sản xuất vẫn còn gây tranh cãi trong phần lớn các trường hợp. Nhận xét của Doxygen không phải là tài liệu tốt (hầu như tất cả các chi tiết quan trọng đều bị thiếu), cũng không phải là nhận xét tốt (họ có xu hướng lặp lại những gì đã rõ ràng từ chữ ký). Tôi nghĩ nbt đã đúng khi nói rằng tài liệu thực sự tốt nhất không được trộn lẫn với mã bởi vì nó gây bất lợi cho khả năng đọc mã. Dù sao thì nó cũng sẽ không đồng bộ, không có viên đạn bạc nào cho việc đó.
cmaster

4

Nếu các bên liên quan của mã nguồn của bạn (giả sử, một thư viện nhỏ) bao gồm "người dùng" (các nhà phát triển đồng nghiệp sẽ sử dụng chức năng của thư viện của bạn mà không tham gia vào việc triển khai) và "nhà phát triển" (bạn và các nhà phát triển khác sẽ triển khai thư viện) , sau đó đặt "thông tin của người dùng" vào tiêu đề và "ghi chú thực hiện" trong nguồn.

Liên quan đến mong muốn không thay đổi các tệp tiêu đề nhiều hơn là hoàn toàn cần thiết - tôi cho rằng nếu thư viện của bạn không "trong một dòng thay đổi điên rồ", thì "giao diện" và "chức năng" sẽ không thay đổi nhiều, và cũng không các bình luận tiêu đề thay đổi quá thường xuyên. Mặt khác, các nhận xét về mã nguồn sẽ phải được giữ đồng bộ ("mới") với mã nguồn.


0

Toàn bộ quan điểm của việc sử dụng doxygen là bạn tạo tài liệu và làm cho nó có thể truy cập được ở một nơi khác. Bây giờ tất cả các tài liệu trong các tiêu đề chỉ là rác, khiến cho việc phát hiện nhanh chóng khai báo funciton cần thiết và có thể quá tải. Một nhận xét lót là tối đa nên đi đến đó, nhưng ngay cả đó là thực hành xấu. Nguyên nhân nếu bạn thay đổi tài liệu trong nguồn bạn biên dịch lại nguồn đó và phát lại. Nhưng nếu bạn đặt tài liệu vào tiêu đề, bạn thực sự không muốn thay đổi một điều nhỏ nhặt nhất trong đó, vì nó sẽ kích hoạt một phần quan trọng của việc xây dựng lại dự án.


1
điều này dường như không cung cấp bất cứ điều gì đáng kể qua các điểm được thực hiện và giải thích trong 7 câu trả lời trước
gnat

1
@gnat từ 7 câu trả lời trước chỉ có một người ủng hộ mã chống lại các tiêu đề. Và người ta đang đưa ra lập luận hoàn toàn khác nhau.
Slava
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.