Nhận xét XML Tài liệu cần thiết?


10

Tôi đã từng là một người hâm mộ yêu cầu các bình luận XML cho tài liệu. Tôi đã thay đổi suy nghĩ vì hai lý do chính:

  1. Giống như mã tốt, phương pháp nên tự giải thích.
  2. Trong thực tế, hầu hết các bình luận XML là tiếng ồn vô dụng không cung cấp thêm giá trị.

Nhiều lần chúng tôi chỉ đơn giản sử dụng GhostDoc để tạo bình luận chung chung, và đây là điều tôi muốn nói bởi tiếng ồn vô dụng:

    /// <summary>
    /// Gets or sets the unit of measure.
    /// </summary>
    /// <value>
    /// The unit of measure.
    /// </value>
    public string UnitOfMeasure { get; set; }

Đối với tôi, đó là điều hiển nhiên. Phải nói rằng, nếu có các hướng dẫn đặc biệt để đưa vào, thì chúng ta hoàn toàn nên sử dụng các nhận xét XML.

Tôi thích đoạn trích từ bài viết này :

Đôi khi, bạn sẽ cần phải viết bình luận. Nhưng, nó phải là ngoại lệ không phải là quy tắc. Nhận xét chỉ nên được sử dụng khi chúng đang diễn đạt một cái gì đó không thể được thể hiện bằng mã. Nếu bạn muốn viết mã thanh lịch, hãy cố gắng loại bỏ các bình luận và thay vào đó hãy viết mã tự ghi.

Tôi có sai không khi nghĩ rằng chúng ta chỉ nên sử dụng các nhận xét XML khi mã không đủ để tự giải thích?

Tôi tin rằng đây là một ví dụ tốt trong đó các nhận xét XML làm cho mã đẹp trông xấu xí. Phải có một lớp học như thế này ...

public class RawMaterialLabel : EntityBase
{
    public long     Id                      { get; set; }
    public string   ManufacturerId          { get; set; }
    public string   PartNumber              { get; set; }
    public string   Quantity                { get; set; }
    public string   UnitOfMeasure           { get; set; }
    public string   LotNumber               { get; set; }
    public string   SublotNumber            { get; set; }
    public int      LabelSerialNumber       { get; set; }
    public string   PurchaseOrderNumber     { get; set; }
    public string   PurchaseOrderLineNumber { get; set; }
    public DateTime ManufacturingDate       { get; set; }
    public string   LastModifiedUser        { get; set; }
    public DateTime LastModifiedTime        { get; set; }
    public Binary   VersionNumber           { get; set; }

    public ICollection<LotEquipmentScan> LotEquipmentScans { get; private set; }
}

... Và biến nó thành thế này:

/// <summary>
/// Container for properties of a raw material label
/// </summary>
public class RawMaterialLabel : EntityBase
{
    /// <summary>
    /// Gets or sets the id.
    /// </summary>
    /// <value>
    /// The id.
    /// </value>
    public long Id { get; set; }

    /// <summary>
    /// Gets or sets the manufacturer id.
    /// </summary>
    /// <value>
    /// The manufacturer id.
    /// </value>
    public string ManufacturerId { get; set; }

    /// <summary>
    /// Gets or sets the part number.
    /// </summary>
    /// <value>
    /// The part number.
    /// </value>
    public string PartNumber { get; set; }

    /// <summary>
    /// Gets or sets the quantity.
    /// </summary>
    /// <value>
    /// The quantity.
    /// </value>
    public string Quantity { get; set; }

    /// <summary>
    /// Gets or sets the unit of measure.
    /// </summary>
    /// <value>
    /// The unit of measure.
    /// </value>
    public string UnitOfMeasure { get; set; }

    /// <summary>
    /// Gets or sets the lot number.
    /// </summary>
    /// <value>
    /// The lot number.
    /// </value>
    public string LotNumber { get; set; }

    /// <summary>
    /// Gets or sets the sublot number.
    /// </summary>
    /// <value>
    /// The sublot number.
    /// </value>
    public string SublotNumber { get; set; }

    /// <summary>
    /// Gets or sets the label serial number.
    /// </summary>
    /// <value>
    /// The label serial number.
    /// </value>
    public int LabelSerialNumber { get; set; }

    /// <summary>
    /// Gets or sets the purchase order number.
    /// </summary>
    /// <value>
    /// The purchase order number.
    /// </value>
    public string PurchaseOrderNumber { get; set; }

    /// <summary>
    /// Gets or sets the purchase order line number.
    /// </summary>
    /// <value>
    /// The purchase order line number.
    /// </value>
    public string PurchaseOrderLineNumber { get; set; }

    /// <summary>
    /// Gets or sets the manufacturing date.
    /// </summary>
    /// <value>
    /// The manufacturing date.
    /// </value>
    public DateTime ManufacturingDate { get; set; }

    /// <summary>
    /// Gets or sets the last modified user.
    /// </summary>
    /// <value>
    /// The last modified user.
    /// </value>
    public string LastModifiedUser { get; set; }

    /// <summary>
    /// Gets or sets the last modified time.
    /// </summary>
    /// <value>
    /// The last modified time.
    /// </value>
    public DateTime LastModifiedTime { get; set; }

    /// <summary>
    /// Gets or sets the version number.
    /// </summary>
    /// <value>
    /// The version number.
    /// </value>
    public Binary VersionNumber { get; set; }

    /// <summary>
    /// Gets the lot equipment scans.
    /// </summary>
    /// <value>
    /// The lot equipment scans.
    /// </value>
    public ICollection<LotEquipmentScan> LotEquipmentScans { get; private set; }
}

2
Tôi cho rằng XML là một lựa chọn tồi tệ cho mục đích này. Đó là cách quá dài dòng và chung chung cho việc sử dụng trong tầm tay. Kiểm tra reSturationuredTextsphinx để biết ngôn ngữ đánh dấu được nhúng vào các nhận xét mà không làm cho chúng không thể đọc được.
Latty

2
@Lattyware: VisualStudio hỗ trợ kiểu này theo mặc định, không cần thêm plugin hay công cụ nào. Nhận xét được tạo theo cách này có thể nhìn thấy ngay lập tức trong các chú giải công cụ bật lên.
Thất vọngWithFormsDesigner

@FrustratedWithFormsDesigner Tôi sẽ nói rằng việc có một plugin là xứng đáng để làm cho mã của bạn dễ đọc hơn nhiều. Hỗ trợ tích hợp cho reST với các chú giải công cụ như trong PyCharm, vì vậy tôi chắc chắn các plugin tồn tại cho các ngôn ngữ khác trong các IDE khác. Rõ ràng nếu bạn có một dự án mà mọi thứ đều được ghi lại theo cách này, tôi không khuyên bạn nên bắt đầu chia nhỏ cách thực hiện, nhưng đối với các dự án mới, tôi chỉ nghĩ rằng thật kinh khủng khi đọc và duy trì.
Latty

Câu trả lời:


21

Nếu bình luận của bạn chỉ trông như thế này:

/// <summary>
/// Gets or sets the sublot number.
/// </summary>
/// <value>
/// The sublot number.
/// </value>

Sau đó, có, chúng không phải là tất cả hữu ích. Nếu họ đọc một cái gì đó như thế này:

/// <summary>
/// Gets or sets the sublot number.
/// Note that the sublot number is only used by the legacy inventory system.
/// Latest version of the online inventory system does not use this, so you can leave it null. 
/// Some vendors require it but if you don't set it they'll send a request for it specifically.
/// </summary>
/// <value>
/// The sublot number.
/// </value>

Sau đó, tôi muốn nói rằng họ có giá trị. Vì vậy, để trả lời câu hỏi của bạn: Nhận xét là cần thiết khi họ nói điều gì đó mà mã không nói.

Một ngoại lệ: thật tốt khi có ý kiến ​​về bất cứ điều gì có thể truy cập công khai nếu bạn đang viết thư viện / API sẽ có sẵn cho công chúng. Tôi ghét sử dụng một thư viện và thấy một chức năng có tên getAPCDGFSocket()mà không có lời giải thích nào về APCDGFSocket là gì (tôi sẽ hài lòng với một cái gì đó đơn giản như This gets the Async Process Coordinator Data Generator File Socket). Vì vậy, trong trường hợp đó, tôi muốn sử dụng một số công cụ để tạo tất cả các nhận xét và sau đó điều chỉnh thủ công những cái cần thiết (và vui lòng đảm bảo các từ viết tắt khó hiểu của bạn được giải thích).

Ngoài ra, getters / setters thường là ví dụ xấu cho "có cần bình luận không?" bởi vì chúng thường khá rõ ràng và ý kiến ​​không cần thiết. Nhận xét quan trọng hơn đối với các hàm thực hiện một số thuật toán trong đó một số giải thích về lý do tại sao mọi thứ được thực hiện theo cách chúng có thể làm cho mã dễ hiểu hơn nhiều và cũng giúp các lập trình viên tương lai dễ dàng làm việc hơn.

... Và cuối cùng, tôi khá chắc chắn rằng câu hỏi này phù hợp với tất cả các kiểu nhận xét, không chỉ những câu hỏi được định dạng bằng XML (mà bạn đang sử dụng vì bạn đang làm việc trong môi trường .NET).


2
+1 - GhostDoc là điểm khởi đầu để tôi biến phiên bản đầu tiên, phiên bản nồi hơi, thành phiên bản thứ hai, chứa kiến ​​thức tên miền chi tiết.
Jesse C. Choper

4
+1 cho phần tại sao . Nguyên tắc DRY áp dụng - không lặp lại chính mình, và nếu mã đã làm một công việc tốt đẹp của mô tả những gì một phần, ý kiến của bạn nên tập trung vào giải thích cái gì khác (thường là lý do tại sao ).
Daniel B

@DanielB hoặc có thể bạn không cần bình luận gì cả;) Tôi đồng ý phần lớn với câu trả lời này ngoại trừ từ cần thiết trong "Nhận xét là cần thiết khi họ nói điều gì đó mà mã không nói." Tôi nghĩ rằng nếu mã nói mọi thứ cần thiết thì bạn không cần thêm thông tin trong các bình luận ngay cả khi các bình luận cung cấp thông tin không có trong mã.
Jimmy Hoffa

1
@DanielB - Nhận xét XML trong .NET chủ yếu dành cho các tình huống trong đó người lập trình người dùng cuối của thư viện hoặc dịch vụ không có sẵn mã nguồn cho họ.
jfrankcarr

2
@Lattyware - Nhận xét XML tích hợp hoàn hảo với Intellisense của Visual Studio, một trình tiết kiệm thời gian lớn so với việc tìm kiếm nội dung trong một tài liệu riêng biệt.
jfrankcarr

5

Các bình luận trông vô dụng đối với người dùng có thể đọc mã trở nên khá hữu ích đối với người dùng không có quyền truy cập vào nguồn. Điều này xảy ra khi lớp được sử dụng làm API bên ngoài bởi những người bên ngoài tổ chức của bạn: HTML được tạo từ tài liệu XML của bạn là cách duy nhất để tìm hiểu về các lớp của bạn.

Điều đó nói rằng, một nhận xét nhắc lại tên phương thức có thêm khoảng trắng giữa các từ vẫn vô dụng. Nếu lớp của bạn sẽ được sử dụng bên ngoài tổ chức của bạn, bạn cần ghi lại ít nhất các phạm vi hợp lệ cho các giá trị của bạn. Ví dụ, bạn nên nói rằng thiết lập UnitOfMeasuređể nulllà bất hợp pháp, rằng giá trị cung cấp cho các setter không được chứa khoảng trắng ở đầu hoặc cuối của chuỗi, và vân vân. Bạn cũng nên ghi lại phạm vi LabelSerialNumbernếu nó khác với phạm vi của đồng bằng Int32: có lẽ nó không cho phép số âm *hoặc không cho phép quá bảy chữ số. Người dùng nội bộ của bạn có thể coi đó là điều hiển nhiên, vì họ nhìn vào số sê-ri ngày này qua ngày khác, nhưng người dùng bên ngoài có thể thực sự ngạc nhiên khi thấy một ngoại lệ từ những gì trông giống như một setter vô tội.


* ... trong trường hợp đó uintcó thể là lựa chọn tốt hơn


1
Nó không chỉ dành cho khi bạn không có nguồn. Nếu trình chỉnh sửa của bạn có thể phân tích cú pháp chúng (như Visual Studio thực hiện với Xml Comments), họ có thể cung cấp thông tin dưới dạng di chuột / cửa sổ bật lên mà không yêu cầu bạn điều hướng đến một tệp khác. Trình xác thực phạm vi 1 dòng giới hạn int trong phạm vi hẹp hơn là điều hiển nhiên khi bạn đi đến tệp nơi trình cài đặt được triển khai; nhưng có "FrobableID phải nằm trong khoảng từ 0 đến 1000" xuất hiện khi bạn bắt đầu nhập "myFrobable.Fro ..." và tính năng tự động hoàn thành sẽ nhắc nhở chúng tôi một cách hữu ích.
Dan đang loay hoay bởi Firelight

1

Bạn hoàn toàn đúng về việc tránh những bình luận vô dụng như vậy. Chúng làm cho việc đọc mã trở nên khó khăn hơn thay vì làm cho nó dễ dàng hơn và chiếm quá nhiều không gian.

Trong thực tế của tôi, những người viết bình luận bằng getters / setters, có xu hướng bỏ qua các bình luận khi những điều đó thực sự cần thiết (như xây dựng truy vấn sql 20 dòng cho một thành phần không có tài liệu).

Tôi viết bình luận khi có một số giải pháp rõ ràng khác _ Tôi cho biết tại sao chính xác phương pháp này đã được sử dụng. Hoặc khi khó có được ý tưởng mà không biết tất cả các chi tiết _ Tôi liệt kê ngắn gọn các chi tiết cần thiết để hiểu mã.

Ví dụ bạn đưa ra là viết nhiều bình luận để nói rằng người ta viết bình luận thay vì làm cho cuộc sống của người khác (và của họ cũng) dễ dàng hơn.

BTW bạn có thể cải thiện khả năng viết bình luận bằng cách quay lại mã cũ của mình và cố gắng hiểu nó (thậm chí bạn có thể không nhận ra mã của chính mình sau 2-3 tháng - hoàn toàn giống như đọc mã của người khác). Nếu bạn làm điều này không đau đớn, thì mọi thứ đều ổn.


Tôi không biết bất cứ ai nỗ lực để viết bình luận về getters / setters nữa. Nếu bạn đang sử dụng hầu hết mọi IDE hiện đại (và thậm chí cả trình soạn thảo văn bản nâng cao có thể hỗ trợ điều này thông qua plugin), getters và setters thường có thể được ghi lại rất dễ dàng bằng một cú click chuột hoặc hai hoặc nhấn phím phải (nếu nó được định cấu hình). Đôi khi, chúng được tạo tự động khi bạn tạo mã dựa trên lược đồ cơ sở dữ liệu hoặc WSDL ...
FrustratedWithFormsDesigner

@FrustratedWithFormsDesigner, người mà tôi đang nói đến là rời khỏi công ty và tôi tin rằng tất cả những bình luận về getters / setters đã được thực hiện bởi người đó để cho thấy rằng anh ấy / cô ấy đã nỗ lực để lại một số tài liệu
superM

Có phải tất cả các ý kiến ​​bogo được nhập sau khi người thông báo? Tôi đã thấy mọi người tạo ra các bình luận xml trống rỗng / vô dụng ở khắp mọi nơi như một cách xương cốt để ngăn VS tạo ra bình luận "Thiếu xml về các cảnh báo Foo hiển thị công khai".
Dan đang loay hoay bởi Firelight

@Dan Neely, tôi đoán rằng người đó không thực sự quan tâm và chỉ thêm bình luận để nói rằng bình luận được thêm vào. Chúng ta thường không chú ý nhiều đến các bình luận, nhưng nếu ai đó rời đi và đang làm việc trên một thành phần, thì bắt buộc phải viết mã rõ ràng có thể đọc được.
superM
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.