Nhận xét đơn giản của Getter / Setter


124

Bạn sử dụng quy ước nào để nhận xét getters và setters? Ví dụ: đây là điều mà tôi đã tự hỏi khá lâu:

/**
 * (1a) what do you put here?
 * @param salary (1b) what do you put here?
 */
public void setSalary(float salary);

/*
 * (2a) what do you put here?
 * @return (2b)
 */
public float getSalary();

Tôi luôn thấy mình viết khá nhiều điều giống hệt nhau cho 1a / b và 2a / b, đại loại như 1a) Đặt mức lương của nhân viên, 1b) mức lương của nhân viên. Nó chỉ có vẻ quá thừa. Bây giờ tôi có thể thấy đối với một cái gì đó phức tạp hơn, bạn có thể viết nhiều hơn trong phần (a), để cung cấp ngữ cảnh, nhưng đối với phần lớn các getters / setters ngoài kia, cách diễn đạt gần như giống hệt nhau.

Tôi chỉ tò mò nếu, đối với getters / setters đơn giản, có thể chỉ điền vào phần (a) HOẶC phần (b).

Bạn nghĩ sao?


54
Ngoài ra, xin đừng bao giờ sử dụng float cho bất kỳ khoản tiền nào (chẳng hạn như lương ở đây). Xem ví dụ: stackoverflow.com/questions/965831/…
Jonik

3
Sử dụng BigDecimal để thay thế.
Josep

Câu trả lời:


83

Tôi thường chỉ điền phần tham số cho setters và phần @return cho getters:

/**
 * 
 * @param salary salary to set (in cents)
 */
public void setSalary(float salary);

/**
 * @return current salary (in cents, may be imaginary for weird employees)
 */
public float getSalary();

Bằng cách đó, các công cụ kiểm tra javadoc (chẳng hạn như cảnh báo của Eclipse) sẽ xuất hiện rõ ràng và không có sự trùng lặp.


Bạn có thể sửa lỗi chính tả? "@return part for setters"
Jonik

1
Ngoài ra còn có một lỗi đánh máy trong bình luận của Lương (). Đó không phải là nhận xét JavaDoc.
Fostah

1
Tôi đồng ý rằng đó là cách tiếp cận tốt nhất để tiếp cận bình luận.
Fostah

31
Tôi cảm thấy sai lầm khi thêm nhiễu vào mã của bạn nhằm mục đích tắt tiếng cảnh báo quá ngớ ngẩn từ các công cụ của chúng tôi. Nếu nó không tăng thêm giá trị cho một lập trình viên, thì giải pháp phù hợp sẽ là giảm bớt / sửa độ dài của các công cụ và / hoặc giảm bớt mức độ chúng ta quan tâm đến việc nhảy qua các vòng để các công cụ thưởng cho chúng ta. Các công cụ phân tích được cho là sẽ giúp chúng ta và tiết kiệm công sức chứ không phải tạo ra nhiều tác vụ vô nghĩa cho chúng ta.
Lyle

1
@Lyle Điều đó có thể đúng, nhưng tôi cảm thấy hầu như luôn có một thứ gì đó hữu ích mà một lập trình viên có thể nói, mô tả getter / setter tốt hơn chỉ là chữ ký của phương thức. Vâng, có những trường hợp một lập trình viên lười biếng và chỉ lặp lại chữ ký phương thức trong nhận xét, nhưng tôi nghĩ rằng nói chung, đó là một hành vi hữu ích để buộc.
Matt Vukas

174

Hoàn toàn vô nghĩa - bạn tốt hơn hết nếu không có loại mã này làm lộn xộn mã của bạn:

/**
 * Sets the foo.
 * 
 * @param foo the foo to set
 */
public void setFoo(float foo);

Rất hữu ích, nếu được bảo hành:

/**
 * Foo is the adjustment factor used in the Bar-calculation. It has a default
 * value depending on the Baz type, but can be adjusted on a per-case base.
 * 
 * @param foo must be greater than 0 and not greater than MAX_FOO.
 */
public void setFoo(float foo);

Đặc biệt là việc giải thích ý nghĩa thực sự của thuộc tính có thể rất quan trọng trong các mô hình miền. Bất cứ khi nào tôi nhìn thấy một hạt đậu có đầy đủ các thuộc tính với những cái tên khó hiểu mà chỉ các chủ ngân hàng đầu tư, nhà hóa sinh hoặc nhà vật lý lượng tử mới hiểu và các bình luận giải thích rằng phương thức setGobbledygook () "thiết lập gobbledygook", tôi muốn bóp cổ ai đó.


2
Chính xác thì theo quan điểm của tôi, điều tồi tệ nhất là các mô hình miền cụ thể mà chỉ một chuyên gia về miền mới biết thuộc tính có ý nghĩa gì.
ThaDon

7
Ngay cả khi nó hữu ích, bạn sẽ làm gì cho getFoo (). Bạn cũng sẽ sao chép bình luận tương tự cho getFoo () chứ?
Vinoth Kumar CM

3
@cmv: Rõ ràng là phần "param" sẽ không được sao chép. Tôi vẫn chưa quyết định liệu giá trị của việc gắn thông tin vào cả hai trình truy cập có trực tiếp biện minh cho việc sao chép thông tin hay không. Chắc là đúng. Tốt hơn nữa sẽ là một cách để đính kèm một nhận xét cho cả hai; Tôi tin rằng điều này có sẵn trong Project Lombok.
Michael Borgwardt

@VinothKumar: có lẽ sẽ tốt hơn nếu đơn giản giải thích thuộc tính trong getter (như trong "Foo là hệ số điều chỉnh được sử dụng trong tính toán Bar.") Và tác động của việc thay đổi giá trị trong setter (hoặc liệu nó có cần thiết không hoặc không khởi tạo giá trị đó - trong ví dụ của câu trả lời, không cần thiết phải khởi tạo Foo vì "nó có giá trị mặc định tùy thuộc vào kiểu Baz").
freitass

+1 cho "những cái tên khó hiểu mà chỉ các chủ ngân hàng đầu tư, nhà hóa sinh hoặc nhà vật lý lượng tử mới hiểu"
Jackson

36

Nói chung là không có gì, nếu tôi có thể giúp nó. Getters và setters phải tự giải thích.

Tôi biết điều đó nghe có vẻ không phải câu trả lời, nhưng tôi cố gắng sử dụng thời gian của mình để bình luận những điều cần giải thích.


5
Một câu trả lời hợp lệ cùng những dòng này có thể là "thiết kế với getter và setter không hiểu đúng khái niệm về đóng gói" :)
Trejkaz

2
@Trejkaz: Không đúng, bởi vì các phương thức của trình truy cập cho phép các thuộc tính chỉ đọc hoặc chỉ ghi và cho tính đa hình (và như vậy, gói, ủy quyền, v.v.).
Laurent Pireyn

2
Chúng có thể cho phép những điều đó, nhưng thường thì một mẫu trình tạo có thể thay thế các bộ định tuyến (ít thay đổi hơn) hoặc một mẫu khách truy cập có thể thay thế các bộ lấy (linh hoạt hơn.)
Trejkaz

Tôi chắc chắn thích và sử dụng mô hình trình xây dựng, nhưng có rất nhiều hỗ trợ cho POJO (ví dụ như trong Hibernate) khiến người lập trình và người thiết lập vẫn có vị trí rất nổi bật, tốt hơn hoặc xấu hơn. Đó là điều đáng kinh ngạc nhất về Java, IMHO và sau khi viết JavaDocs lặp đi lặp lại trong hơn một thập kỷ, tôi đã sẵn sàng đăng ký lời khuyên của @ sleske.
Michael Scheper

34

Tôi muốn nói rằng chỉ lo lắng về việc nhận xét getters và setters nếu chúng có một số loại tác dụng phụ hoặc yêu cầu một số loại điều kiện tiên quyết bên ngoài quá trình khởi tạo (ví dụ: get sẽ xóa một mục khỏi cấu trúc dữ liệu hoặc để thiết lập thứ gì đó bạn cần để có x và y ở vị trí đầu tiên). Nếu không, các ý kiến ​​ở đây là khá thừa.

Chỉnh sửa: Ngoài ra, nếu bạn thấy có nhiều tác dụng phụ liên quan đến getter / setter của mình, bạn có thể muốn thay đổi getter / setter để có một tên phương thức khác (nghĩa là: đẩy và bật cho một ngăn xếp) [Cảm ơn vì bình luận bên dưới]


10
Có thể nói, bạn nên thay đổi tên của getters có tác dụng phụ để rõ ràng hơn, vì không phải tất cả các nhà phát triển sẽ đọc các bình luận.
akf

Điều đó tốt - nhưng điều đó yêu cầu người dùng API của bạn biết rằng, nếu có bất kỳ tác dụng phụ nào, chúng sẽ được ghi lại !
oxbow_lakes

akf, tôi đã nghĩ chính xác điều đó sau khi đăng bài :) Tôi đoán tôi sẽ thêm nó vào câu trả lời của mình.
Gopherkhan

1
nhưng nếu bạn không ghi lại các getters và setters "ngu ngốc" (đó là những gì tôi cũng thích!) - làm cách nào để loại bỏ các cảnh báo Eclipse khi thiếu javadoc? Tôi không muốn lộn xộn không gian làm việc của tôi với lời cảnh báo như thế, nhưng tôi cũng không muốn cảnh báo rằng bị vô hiệu cho tất cả các phương pháp khác ...
Zordid

12

Hãy tự hỏi bản thân xem bạn muốn mọi người thấy gì khi nhận xét được xem dưới dạng JavaDocs (từ trình duyệt). Nhiều người nói rằng tài liệu là không cần thiết vì đó là điều hiển nhiên. Điều này sẽ không giữ nếu trường là riêng tư (trừ khi bạn bật JavaDocs cho các trường riêng tư một cách rõ ràng).

Trong trường hợp của bạn:

public void setSalary(float s)
public float getSalary()

Không rõ lương được thể hiện bằng gì. Nó là xu, đô la, bảng Anh, RMB?

Khi lập tài liệu setters / getters, tôi muốn tách những gì ra khỏi bảng mã. Thí dụ:

/**
 * Returns the height.
 * @return height in meters
 */
public double getHeight()

Dòng đầu tiên cho biết nó trả về chiều cao. Tham số trả về ghi lại chiều cao tính bằng mét.


1
trong khi tôi đồng ý với bạn, tôi nghĩ rằng người ta phải đảm bảo rằng các bình luận của hàm không tạo ra một tên hàm được chọn xấu, không rõ ràng.
karlipoppins

Tôi là một người ủng hộ lớn của JavaDocs, nhưng cũng là một người ủng hộ lớn đối với mã tự lập tài liệu. Vì vậy, đối với người thiết lập ít nhất, tôi sẽ làm một cái gì đó như public void setSalary(float aud)(hoặc thực tế hơn, public void setSalary(BigDecimal aud)). Tốt hơn, thuộc tính phải là loại abstract class CurrencyAmount, do đó có các thuộc tính java.util.Currency currencyjava.math.BigDecimal amount. Hầu hết các nhà phát triển mà tôi đã làm việc cùng cực kỳ lười biếng với JavaDoc, nhưng việc thực thi API như thế này giúp điều này ít gặp vấn đề hơn.
Michael Scheper

Nếu đơn vị là một đơn vị SI như mét / giây, sẽ có ít nhu cầu tài liệu, nếu nó không phải là một đơn vị Si sau đó nó phải được lập hồ sơ hoặc tốt hơn được đặt tên để bao gồm các đơn vị phi tiêu chuẩn, ví dụ như heightFeet
AlexWien

8

Tại sao họ không chỉ bao gồm một thẻ tham chiếu để cho phép bạn nhận xét giá trị trường và tham chiếu từ getters và setters.

/**
* The adjustment factor for the bar calculation.
* @HasGetter
* @HasSetter
*/
private String foo;

public String getFoo() {
  return foo;
}

public void setFoo() {
  this foo = foo;
}

Để tài liệu áp dụng cho getter và setter cũng như trường (nếu javadocs riêng được bật thì đó là).


Tôi đồng ý. Và sau đó tôi nhận ra, tại sao lại viết tất cả các bản soạn thảo này? Xem câu trả lời của tôi về Dự án Lombok.
Michael Scheper

7

Bạn có thể tránh được loại bảng ghi này bằng cách sử dụng Project Lombok . Chỉ cần ghi lại biến trường, ngay cả khi nó là private, và để các chú thích của Lombok tạo ra các getters và setters được lập tài liệu đúng cách.

Đối với tôi, lợi ích này chỉ là giá trị chi phí .


4

Tôi thực sự thất vọng về các câu trả lời về cơ bản nói rằng việc lập tài liệu toàn diện là một sự lãng phí thời gian. Làm thế nào mà các khách hàng của API của bạn phải biết rằng một phương thức được gọi setXlà bộ thiết lập thuộc tính JavaBean tiêu chuẩn trừ khi bạn nói rõ ràng như vậy trong tài liệu ?

Nếu không có tài liệu hướng dẫn, người gọi sẽ không biết phương pháp này có tác dụng phụ gì không, ngoại trừ việc họ khoanh tay về quy ước rõ ràng đang được tuân thủ.

Tôi chắc rằng mình không phải là người duy nhất ở đây gặp bất hạnh khi tìm ra cách khó mà một phương thức được gọi là setXkhông chỉ đặt một thuộc tính.


11
Nếu không có tài liệu hướng dẫn, bất kỳ người gọi nào cũng sẽ cho rằng một phương thức có tên setX đặt X. Điều đó xảy ra nếu setX thực sự đặt X mà không cần làm bất kỳ điều gì quan trọng khác, thì bạn không cần tài liệu.
mqp

Thật tuyệt! Bây giờ công ty CrudTech này, API mà tôi đang mã hóa, tuân theo quy ước của bạn hay nó tuân theo quy ước của người khác trên chuỗi này? Hmmmm
oxbow_lakes

5
Không có lý do gì khi viết "đặt giá" trong tài liệu setPrice nếu phương thức chỉ đặt giá trị cho thuộc tính price, nhưng nếu nó cũng như cập nhật thuộc tính totalPrice và tính toán lại thuế, hành vi đó rõ ràng phải được ghi lại.
João Marcus

8
Có vẻ như bạn đang yêu cầu tài liệu cho biết "Điều này thực hiện những gì bạn mong đợi." Nó hơi giống như viết "Thận trọng: NÓNG" trên một tách cà phê. Trong một thế giới hoàn hảo, sẽ không cần thiết phải nói những điều như vậy.
Kevin Panko

1
Có - đã sử dụng các API nơi các phương pháp được gọi là những thứ như setXcó tác dụng phụ khác với mong đợi, tôi thực sự có thể tự tin tuyên bố rằng đây không phải là một thế giới hoàn hảo.
oxbow_lakes

4

Nếu không có thao tác đặc biệt nào trong getter / setter, tôi thường viết:

Với Javadoc (với tùy chọn riêng tư):

/** Set {@see #salary}. @param {@link #salary}. */
public void setSalary(float salary);

và / hoặc

/** 
 * Get {@see #salary}.
 * @return {@link #salary}.
 */
public float salary();

Với Doxygen (với tùy chọn trích xuất riêng tư):

/** @param[in] #salary. */
public void setSalary(float salary);

/** @return #salary. */
public float salary();

2
Vấn đề với phương pháp này là Javadoc không tạo tài liệu riêng theo mặc định! Trong trường hợp đó, thẻ tham chiếu {@see #salary}không hợp lệ trong tài liệu đã tạo.
Jarek Przygódzki

1

Nhận xét người truy cập, đặc biệt nếu họ không thực hiện bất kỳ thao tác nào ở bất kỳ đâu, là không cần thiết và lãng phí đầu ngón tay.

Nếu ai đó đọc mã của bạn không thể hiểu được person.getFirstName()trả lại tên đầu tiên của một người, bạn nên thử mọi cách trong khả năng của mình để đuổi anh ta. Nếu nó thực hiện một số phép thuật cơ sở dữ liệu, ném một vài con xúc xắc, gọi Thư ký của Tên để lấy tên đầu tiên, Thật an toàn khi cho rằng đó là một hoạt động không tầm thường và ghi lại nó tốt.

Mặt khác, nếu bạn person.getFirstName()không trả lại tên của một người ... thì, chúng ta đừng đến đó, phải không?


6
Điều gì sẽ xảy ra nếu getFirstName () trả về null? Điều đó sẽ được ghi lại ở đâu?
Steve Kuo

Còn về security.getFinalMaturity () thì sao? Không phải tất cả các tên tài sản đều có ý nghĩa dễ hiểu ngay lập tức. Bạn có muốn bị sa thải vì không biết điều đó có nghĩa là gì không?
Michael Borgwardt

Điều gì sẽ xảy ra nếu phương pháp được thực hiện bằng cách swizzling? Làm thế nào bạn có thể biết điều đó trừ khi nó được ghi lại rõ ràng? Làm thế nào bạn có thể biết nó là một bộ định mức tiêu chuẩn trừ khi bác sĩ cho biết nó là?
oxbow_lakes

2
get / set theo ý kiến ​​của tôi nên được dành riêng cho getters và setters. Tra cứu cơ sở dữ liệu nên được đặt tên như "lookupPerson" hoặc tương tự.
Thorbjørn Ravn Andersen

1

Đừng đặt bất cứ điều gì nếu tên trường mô tả thành thạo nội dung.

Nói chung, hãy để mã tự đứng và tránh bình luận nếu có thể. Điều này có thể yêu cầu cấu trúc lại.

CHỈNH SỬA: Ở trên chỉ đề cập đến getters và setters. Tôi tin rằng bất cứ điều gì không tầm thường nên được javadoc'ed đúng cách.


1
Có một sự khác biệt giữa bình luận và tài liệu.
Tom Hawtin - tắc bóng vào

1
Rất đúng. Do đó, chính xác là lý do tại sao tôi không nhận xét getters và setters. Chúng phải tự giải thích và việc thêm nhận xét cho biết rằng mã không phải là mã tự giải thích.
Thorbjørn Ravn Andersen

0

bạn có thể điền vào phần (b), đặc biệt nếu bạn đặt một chú thích ở phần khai báo trường cho biết nội dung của trường.


Không tốt - mọi người không đọc các bình luận về lĩnh vực này. Javadoc thậm chí không tạo tài liệu riêng theo mặc định và các IDE không hiển thị cho bạn tài liệu trường khi bạn sử dụng trợ giúp nhanh về cuộc gọi phương thức.
Trejkaz 21/10/10

mọi người không đọc các nhận xét trường trừ khi họ cần. Khi đã có nhu cầu, càng nhiều thông tin càng tốt.
akf 22/10/10

0

Nếu javadoc không thêm bất cứ điều gì, tôi xóa javadoc và sử dụng các bình luận được tạo tự động.


0

Tôi luôn điền vào cả hai. Thời gian bổ sung dành cho việc đánh máy là không đáng kể và nhìn chung thì nhiều thông tin hơn là ít hơn.


Chúng chỉ tự giải thích nếu bạn nói "đây là người thiết lập tài sản". Nếu một khách hàng của API không có ý tưởng nào những gì đang thực sự xảy ra bên trong các phương pháp
oxbow_lakes

1
Ai nói gì về sự tự giải thích?
Paul Sonier
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.