Một cách tốt để bình luận if-other-mệnh đề là gì? [đóng cửa]


15

Bất cứ khi nào tôi đang viết một if-other-construc điển hình bằng bất kỳ ngôn ngữ nào, tôi tự hỏi điều gì sẽ là cách tốt nhất (về khả năng đọc và tổng quan) để thêm nhận xét cho nó. Đặc biệt là khi bình luận mệnh đề khác, các bình luận luôn cảm thấy lạc lõng với tôi. Giả sử chúng ta có một cấu trúc như thế này (ví dụ được viết bằng PHP):

if ($big == true) {
    bigMagic();
} else {
    smallMagic()
}

Tôi có thể nhận xét nó như thế này:

// check, what kind of magic should happen
if ($big == true) {
    // do some big magic stuff
    bigMagic();
} else {
    // small magic is enough
    smallMagic()
}

hoặc là

// check, what kind of magic should happen
// do some big magic stuff
if ($big == true) {
    bigMagic();
}
// small magic is enough
else {
   smallMagic()
}

hoặc là

// check, what kind of magic should happen
// if:   do some big magic stuff
// else: small magic is enough
if ($big == true) {
    bigMagic();
} else {
    smallMagic()
}

Ví dụ thực hành tốt nhất của bạn để bình luận này là gì?


8
else { // for future reader: sorry, at the moment of writing this I did not have time and skills to come up with a better way to express my logic
gnat

1
Tại sao Bigger tốt hơn / thích hợp / khác biệt? Thấy chưa, tôi không biết.
JeffO

Đây có phải là một chủ đề cho câu hỏi hoặc tranh luận? Ngay cả khi câu hỏi có ý nghĩa tốt, đó là những người bắt đầu chiến tranh.
Độc lập

1
Tôi thấy thú vị khi rất nhiều người đã cảm thấy rằng câu hỏi này đáng để họ trả lời, nhưng không đáng để nâng cao. Trong khi tôi quan tâm đến câu trả lời (của tôi là +1 duy nhất), câu hỏi dường như là một ví dụ điển hình cho vấn đề đổ xe đạp.
canisrufus

1
@canisrufus Nó chỉ có vẻ như vậy với bạn vì số phiếu giảm bù cho số phiếu tăng. Tại thời điểm này, có 6 phiếu tăng và giảm 4 cho mạng +2.
Caleb

Câu trả lời:


34

Tôi thích một trong hai:

if ($magic == big) {
    bigMagic();
}
else {
    smallMagic();
}

hoặc là:

if ($magic == big) {
    // big magic requires a big surprise, so I'm telling you about it here
    surprisingThing();
}
else {
    // give a magical feeling even if $magic is noMagicAtAll
    smallMagic();
}

Có vẻ hơi ngớ ngẩn khi viết một bình luận giải thích những gì tình trạng của bạn kiểm tra trừ khi mã không nêu rõ. Thậm chí sau đó, tốt hơn là viết lại mã để làm cho nó rõ ràng nhất có thể. Điều tương tự cũng xảy ra với các cơ quan của các khối có điều kiện - nếu bạn có thể đưa ra lý do để làm điều gì đó rõ ràng, hãy làm điều đó thay vì bình luận.

Tôi không đăng ký triết lý "không bao giờ viết bình luận", nhưng tôi tin vào việc tránh các bình luận nói những gì mã nên nói. Nếu bạn viết một bình luận như "kiểm tra loại phép thuật nào sẽ xảy ra" khi mã có thể nóiif ($magic == big) {... , người đọc sẽ ngừng đọc bình luận của bạn rất nhanh. Sử dụng ít hơn, các bình luận có ý nghĩa hơn sẽ mang lại cho mỗi bình luận của bạn nhiều giá trị hơn và người đọc có nhiều khả năng chú ý đến những bình luận mà bạn viết.

Chọn tên có ý nghĩa cho các biến và chức năng của bạn là rất quan trọng. Một tên được chọn tốt có thể loại bỏ nhu cầu bình luận giải thích trong toàn bộ mã của bạn. Trong ví dụ của bạn, $magichoặc có thể có $kindOfMagicvẻ như là một cái tên tốt hơn so với $bigví dụ của bạn, đó là "loại phép thuật" đang được thử nghiệm, không phải là "bigness" của một cái gì đó.

Nói càng nhiều càng tốt trong mã. Lưu văn xuôi cho các trường hợp yêu cầu giải thích nhiều hơn bạn có thể viết mã một cách hợp lý.


13
+1 không làm quá nhiều ý kiến, mã rõ ràng không yêu cầu bình luận
ratchet freak

3
@ratchetfreak Có vẻ như chúng ta hầu hết đều đồng ý, nhưng ý kiến ​​thường là cần thiết để làm cho mã rõ ràng. Cung cấp bối cảnh lịch sử, giải thích cho hành vi đáng ngạc nhiên hoặc giải quyết sự mơ hồ được thực hiện tốt nhất với các bình luận.
Caleb

1
Điểm tốt, Caleb. Đúng là mã nên một số loại tự động nhận xét miễn là nó có thể.
acme

7
Những bình luận tốt không giải thích điều gì - "kiểm tra, loại phép thuật nào sẽ xảy ra" - họ giải thích lý do tại sao, "Người dùng có thể chọn loại phép thuật để chạy" hoặc "Dịch vụ sẽ lấp đầy ma thuật lớn nếu họ có sẵn, vì vậy chúng tôi phải kiểm tra loại "hoặc bất cứ điều gì. Cho dù mã hóa của bạn tốt đến đâu, thì những người không quen thuộc với các quy tắc kinh doanh đều không biết.
Bruno Brant

1
Vấn đề là dễ viết mã khó đọc và không bình luận. Việc viết mã khó đọc cũng dễ hơn nhưng bình luận tốt hơn là viết mã liên tục tốt đến mức không cần bình luận.
tăng

11

Hãy thử tên biến giải thích

Nhận xét có thể là tuyệt vời, nhưng khi có thể, làm cho mã tự viết tài liệu. Một cách để làm điều này là với các tên biến giải thích. Ví dụ, thay vì điều này:

if (user.has_sideburns && user.can_gyrate) {
  // This user is a potential Elvis impersonator

}

Tôi muốn một biến được đặt tên:

is_potential_elvis_impersonator = user.has_sideburns && user.can_gyrate

if (is_potential_elvis_impersonator) {
  ...
}

2
Tôi đi thêm một bước nữa và sử dụng : is_potential_elvis_impersonator. (Is / Has / etc. Tiền tố cho biến boolean ..)
Jake Berger

@jberger - Tôi thích nó. Chỉnh sửa câu trả lời cho phù hợp.
Nathan Long

3

Chỉ cần hoàn thành một số ý kiến:

Việc sử dụng đúng các bình luận là để bù đắp cho sự thất bại của chúng tôi trong việc thể hiện chính chúng ta trong mã. Lưu ý rằng tôi đã sử dụng từ thất bại. Ý tôi là thế Bình luận luôn là thất bại. Chúng ta phải có chúng bởi vì chúng ta không thể luôn luôn tìm ra cách thể hiện bản thân mà không có chúng, nhưng việc sử dụng chúng không phải là một nguyên nhân cho lễ kỷ niệm. ( Mã sạch của Robert C. Martin )

BTW: Tôi muốn giới thiệu cuốn sách này.


3

Nhận xét không nên diễn giải mã nhưng giải thích những điều không có trong mã (hình ảnh lớn hơn, tại sao, tại sao một lựa chọn thay thế không được chọn ...) Và các nhận xét ví dụ của bạn chỉ là: diễn giải mã.

Đôi khi bạn có thể cảm thấy rằng một paraphotto là cần thiết khi bắt đầu elsechi nhánh, nhưng đó thường là một dấu hiệu cho thấy thenchi nhánh của bạn quá lớn.


2

Trong ví dụ cụ thể của bạn, các bình luận có lẽ không cần thiết. Như Caleb đã đề cập , nếu mã được viết rõ ràng và các biến có tên ngữ nghĩa, nếu các câu lệnh ít có khả năng cần bình luận.

So sánh đoạn trích của bạn với điều này:

if ($x) {
    func1();
} else {
    func2();
}

Trong trường hợp này, bạn chắc chắn sẽ muốn sử dụng các nhận xét để mô tả những gì x, func1 và func2 đại diện (và tát người đặt tên mọi thứ theo sơ đồ đó, đặc biệt nếu đó là bạn). Bạn thậm chí không thể biết liệu $xcó phải là một boolean hay không. Nhưng đây cũng là trường hợp bạn không nhất thiết cần bình luận, nếu bạn có thể cấu trúc lại và đổi tên.

Nói chung, tôi thích viết bình luận cho các khối logic mô tả những thứ mà mã không thể tự mình làm được. Một dòng lót mỗi ~ 10-20 dòng mô tả những gì các dòng sau đây hoàn thành ở một mức độ trừu tượng cao hơn (ví dụ như ví dụ // Make the right amount of magic happencủa bạn) sẽ giúp bạn định hướng và cung cấp cho người đánh giá mới cái nhìn sâu sắc về những gì bạn đang làm và khi nào .

Tôi thực sự thường viết những lớp lót này trước khi tôi bắt đầu viết mã, để tôi không mất dấu vết của phân đoạn mà lẽ ra phải có.

Cuối cùng, nếu bạn thực sự thích (hoặc có một nhiệm vụ yêu cầu) các mệnh đề bình luận trong một khối if bất kể khả năng đọc của mã, tôi khuyên bạn nên:

// Broad description of block
if (something) {
    //Do this because something
    something();
} else {
    //Do this because !something
    somethingElse();
}

Tôi cảm thấy đó là sạch nhất, bởi vì các bình luận xếp hàng với mã mà nó liên quan. Một bình luận mô tả mã nào nên càng gần với bình luận mà nó mô tả càng tốt.


2
if (IsWeekDay(day))
{// weekday -> alarm at 7am
   ...
}
else if(day == DayOfWeek.Saturday)
{// saturday -> alarm at 11am
   ...
}
else
{// (sunday) -> no alarm
   ...
}

Tôi giữ dấu ngoặc của mình xếp thành hàng và đặt nó ngay sau dấu ngoặc.

[Condition] -> [pseudo-code]

Mặt khác, về mặt kỹ thuật có nghĩa là tất cả các điều kiện khác đều thất bại, vì vậy tôi thường sử dụng dấu ngoặc đơn.

([Condition]) -> [pseudo-code]

Lưu ý: đây là cho C #.


1

Tôi thử và sử dụng các bình luận bên trong khối cho biết khối đó làm gì (mẫu đầu tiên của bạn).

Trường hợp loại này bị hỏng khi sử dụng elseif. Tôi sử dụng Basic để không có khối kết thúc rõ ràng và thường phải nhận xét điều kiện nào đang kiểm tra xem điều gì xảy ra ở dòng trên (dĩ nhiên là ngắt dòng) nếu quá dài.

'Check XYZ
If Condition1 then
  'We need to do T and S
  DoCodeFor1();

'Check ABC
ElseIf Condition1 then
  'This requires something else to be done
  DoCodeFor2()

Else
  'We have no other option than to...
  DoCodeFor3()

End If

Vâng, điều này thực sự hoạt động tốt hơn khi bạn sử dụng ngôn ngữ mà không có dấu ngoặc đơn.
acme

1
  • Giữ khối điều kiện của bạn thực sự ngắn.
  • Gọi một phương thức với một tên mô tả đẹp nếu có vẻ như mã điều kiện của bạn sẽ nhiều hơn một hoặc hai dòng đơn giản.
  • Sử dụng tên mô tả đẹp cho các biến của bạn.
  • Hãy chắc chắn rằng câu lệnh có điều kiện rõ ràng theo nghĩa của nó, và không bị xáo trộn hoặc dài. Sử dụng một phương pháp nếu nó giúp giữ cho mọi thứ sạch sẽ và dễ đọc.

Nếu tất cả các cách trên không thành công, hãy thêm một nhận xét mô tả rất nhỏ trước câu lệnh if, để làm rõ ý định của bạn. Nếu không, thực sự không cần phải bình luận gì cả.


0

Trong C ++ hoặc C #, tôi thường không bình luận các trường hợp đơn giản (khi rõ ràng điều gì đang xảy ra) và sử dụng kiểu này để nhận xét cuối cùng ...

if (pattern == AAA)
{
  DoSomethingAAA();
}
else if (pattern == BBB)
{
  DoSomethingBBB();
}
else // if (pattern == CCC)
{
  DoSomethingCCC();
}

4
Hoặc tốt hơn, "pattern.doSthing ()" và để OO thực hiện công việc của mình.
Paul Tomblin
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.