คอมเมนต์ Getter / Setter ง่ายๆ


125

คุณใช้หลักการใดในการแสดงความคิดเห็นผู้รับและผู้ตั้งถิ่นฐาน? นี่เป็นสิ่งที่ฉันสงสัยมาระยะหนึ่งแล้วเช่น:

/**
 * (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();

ฉันมักจะพบว่าฉันมักจะเขียนสิ่งเดียวกันสำหรับ 1a / b และ 2a / b เช่น 1a) กำหนดเงินเดือนของพนักงาน 1b) เงินเดือนของพนักงาน ดูเหมือนซ้ำซ้อนมาก ตอนนี้ฉันเห็นบางอย่างที่ซับซ้อนกว่านี้คุณอาจเขียนเพิ่มเติมในส่วน (a) เพื่อให้บริบท แต่สำหรับ getters / setters ส่วนใหญ่คำพูดนั้นเกือบจะเหมือนกันทุกประการ

ฉันแค่อยากรู้ว่าสำหรับ getters / setters แบบธรรมดามันตกลงที่จะกรอกเฉพาะส่วน (a) หรือส่วน (b)

คุณคิดอย่างไร?


54
นอกจากนี้โปรดอย่าใช้ float สำหรับสิ่งที่เป็นตัวเงิน (เช่นเงินเดือนที่นี่) เลยทีเดียว ดูเช่นstackoverflow.com/questions/965831/…
Jonik

3
ใช้ BigDecimal แทน
Josep

คำตอบ:


84

ฉันมักจะเติมส่วนพารามิเตอร์สำหรับ setters และส่วน @return สำหรับ 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();

ด้วยวิธีนี้เครื่องมือตรวจสอบ javadoc (เช่นคำเตือนของ Eclipse) จะออกมาสะอาดและไม่มีการทำซ้ำ


คุณสามารถแก้ไขคำผิดได้หรือไม่? "@return part for setters"
Jonik

1
นอกจากนี้ยังมีการพิมพ์ผิดในความคิดเห็นของเงินเดือน () ไม่ใช่ความคิดเห็น JavaDoc
Fostah

1
ฉันยอมรับว่าวิธีนี้เป็นวิธีที่ดีที่สุดในการแสดงความคิดเห็น
Fostah

31
การเพิ่มเสียงรบกวนลงในโค้ดของคุณเพื่อปิดเสียงเตือนจากเครื่องมือของเราที่อวดรู้มากเกินไป หากไม่ได้เพิ่มมูลค่าให้กับโปรแกรมเมอร์วิธีแก้ปัญหาที่เหมาะสมคือการลด / แก้ไขความฟุ่มเฟื่อยของเครื่องมือและ / หรือผ่อนปรนว่าเราสนใจแค่ไหนในการกระโดดผ่านห่วงเพื่อให้เครื่องมือตอบแทนเรา เครื่องมือวิเคราะห์ควรจะช่วยเราและประหยัดความพยายามไม่ใช่สร้างงานที่ไร้เหตุผลให้เรามากขึ้น
Lyle

1
@Lyle นั่นอาจจะจริง แต่ฉันรู้สึกว่ามีบางอย่างที่มีประโยชน์เกือบตลอดเวลาที่โปรแกรมเมอร์สามารถพูดได้ซึ่งอธิบายถึง getter / setter ได้ดีกว่าแค่ลายเซ็นวิธีอย่างเดียว ใช่มีหลายกรณีที่โปรแกรมเมอร์ขี้เกียจและเพียงแค่ทำซ้ำลายเซ็นของวิธีการในความคิดเห็น แต่ฉันคิดว่าโดยทั่วไปแล้วการบังคับใช้พฤติกรรมที่เป็นประโยชน์
Matt Vukas

174

ไม่มีจุดหมายอย่างแน่นอน - คุณจะดีกว่าโดยไม่มีอึแบบนี้มาเกะกะรหัสของคุณ:

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

มีประโยชน์มากหากได้รับการรับรอง:

/**
 * 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);

โดยเฉพาะอย่างยิ่งคำอธิบายเกี่ยวกับความหมายของคุณสมบัติที่แท้จริงอาจมีความสำคัญอย่างยิ่งในโมเดลโดเมน เมื่อใดก็ตามที่ฉันเห็นถั่วที่เต็มไปด้วยคุณสมบัติที่มีชื่อคลุมเครือซึ่งมีเพียงวาณิชธนกิจนักชีวเคมีหรือนักฟิสิกส์ควอนตัมเท่านั้นที่เข้าใจและความคิดเห็นอธิบายว่าวิธี setGobbledygook () "กำหนด gobbledygook" ฉันต้องการบีบคอใครบางคน


2
ความรู้สึกของฉันที่แย่ที่สุดคือแบบจำลองเฉพาะโดเมนซึ่งมีเพียงผู้เชี่ยวชาญโดเมนเท่านั้นที่รู้ว่าคุณสมบัตินี้หมายถึงอะไร
ท่าดอน

7
แม้ว่าจะมีประโยชน์ในสิ่งที่คุณจะทำสำหรับ getFoo () คุณจะคัดลอกความคิดเห็นเดียวกันสำหรับ getFoo () ด้วยหรือไม่?
Vinoth Kumar CM

3
@cmv: แน่นอนว่าจะไม่มีการคัดลอกส่วน "param" ฉันไม่แน่ใจว่าคุณค่าของการแนบข้อมูลกับผู้เข้าถึงทั้งสองนั้นเป็นเหตุให้ข้อมูลซ้ำซ้อนโดยตรงหรือไม่ อาจจะใช่. ที่ดีไปกว่านั้นคือวิธีการแนบความคิดเห็นหนึ่งกับทั้งสอง; ฉันเชื่อว่าสิ่งนี้มีอยู่ในโครงการลอมบอก
Michael Borgwardt

@VinothKumar: อาจจะดีกว่าที่จะอธิบายคุณสมบัติใน getter (เช่นเดียวกับใน "Foo คือปัจจัยการปรับที่ใช้ในการคำนวณบาร์") และผลของการเปลี่ยนค่าใน setter (หรือว่าจำเป็น หรือไม่เริ่มต้นค่านั้น - ในตัวอย่างของคำตอบไม่จำเป็นต้องเริ่มต้น Foo เนื่องจาก "มีค่าเริ่มต้นขึ้นอยู่กับประเภท Baz")
freitass

+1 สำหรับ "ชื่อที่คลุมเครือซึ่งมีเพียงวาณิชธนกิจนักชีวเคมีหรือนักฟิสิกส์ควอนตัมเท่านั้นที่เข้าใจ"
Jackson

36

โดยทั่วไปไม่มีอะไรถ้าฉันสามารถช่วยได้ ผู้รับและผู้ตั้งค่าควรเป็นผู้อธิบายตนเอง

ฉันรู้ว่าฟังดูเหมือนไม่ใช่คำตอบ แต่ฉันพยายามใช้เวลาแสดงความคิดเห็นในสิ่งที่ต้องการคำอธิบาย


5
อีกคำตอบที่ถูกต้องตามบรรทัดเหล่านี้อาจเป็น "การออกแบบด้วยตัวรับและตัวตั้งค่าไม่เข้าใจแนวคิดของการห่อหุ้ม" :)
Trejkaz

2
@Trejkaz: ไม่เป็นความจริงเนื่องจากวิธีการเข้าถึงอนุญาตสำหรับคุณสมบัติอ่านอย่างเดียวหรือเขียนอย่างเดียวและสำหรับความหลากหลาย (และการตัดการพร็อกซีและอื่น ๆ )
Laurent Pireyn

2
พวกเขาอาจอนุญาตสำหรับสิ่งเหล่านั้น แต่บ่อยครั้งที่รูปแบบตัวสร้างสามารถแทนที่ตัวตั้งค่าได้ (เปลี่ยนแปลงน้อยลง) หรือรูปแบบผู้เยี่ยมชมสามารถแทนที่ getters ได้ (ยืดหยุ่นกว่า)
Trejkaz

แน่นอนว่าฉันชอบและใช้รูปแบบตัวสร้าง แต่มีการสนับสนุน POJO มากมาย (เช่นใน Hibernate) ที่ตัวรับและตัวตั้งค่ายังคงมีตำแหน่งที่โดดเด่นมากไม่ว่าจะดีขึ้นหรือแย่ลง เป็นเรื่องที่น่ากลัวที่สุดเกี่ยวกับ Java, IMHO และหลังจากเขียน JavaDocs ซ้ำ ๆ มานานกว่าทศวรรษฉันก็พร้อมที่จะสมัครรับคำแนะนำของ @ sleske
Michael Scheper

34

ฉันจะบอกว่าเพียงกังวลเกี่ยวกับการแสดงความคิดเห็น getters และ setters หากมีผลข้างเคียงบางอย่างหรือต้องการเงื่อนไขเบื้องต้นบางอย่างนอกเหนือจากการเริ่มต้น (เช่นการรับจะลบรายการออกจากโครงสร้างข้อมูลหรือเพื่อกำหนดสิ่งที่คุณต้องการ ให้มี x และ y อยู่ในตำแหน่งก่อน) มิฉะนั้นความคิดเห็นที่นี่จะค่อนข้างซ้ำซ้อน

แก้ไข: นอกจากนี้หากคุณพบว่ามีผลข้างเคียงมากมายที่เกี่ยวข้องกับ getter / setter ของคุณคุณอาจต้องการเปลี่ยน getter / setter ให้มีชื่อวิธีการอื่น (เช่น push and pop สำหรับ stack) [ขอบคุณสำหรับ ความคิดเห็นด้านล่าง]


10
เนื้อหาคุณควรเปลี่ยนชื่อ getters ที่มีผลข้างเคียงให้ชัดเจนยิ่งขึ้นเนื่องจากนักพัฒนาบางคนไม่ได้อ่านความคิดเห็น
akf

ไม่เป็นไร - แต่นั่นต้องการให้ผู้ใช้ API ของคุณรู้ว่ามีผลข้างเคียงใด ๆ พวกเขาจะได้รับการบันทึกไว้ !
oxbow_lakes

akf ฉันคิดอย่างนั้นหลังจากโพสต์ :) ฉันเดาว่าฉันจะเพิ่มมันลงในคำตอบของฉัน
Gopherkhan

1
แต่ถ้าคุณไม่ได้จัดทำเอกสาร getters และ setters "โง่" (ฉันก็ชอบเหมือนกัน!) - คุณจะกำจัดคำเตือน Eclipse เกี่ยวกับ javadoc ที่หายไปได้อย่างไร? ฉันไม่ต้องการเกะกะพื้นที่ทำงานของฉันด้วยคำเตือนแบบนั้น แต่ฉันก็ไม่ต้องการให้คำเตือนนั้นถูกปิดใช้งานสำหรับวิธีการอื่น ๆ ทั้งหมด ...
Zordid

12

ถามตัวเองว่าคุณต้องการให้คนอื่นเห็นอะไรเมื่อความคิดเห็นถูกมองว่าเป็น JavaDocs (จากเบราว์เซอร์) หลายคนบอกว่าเอกสารไม่จำเป็นเนื่องจากชัดเจน สิ่งนี้จะไม่ถือหากฟิลด์นั้นเป็นแบบส่วนตัว (เว้นแต่คุณจะเปิด JavaDocs สำหรับฟิลด์ส่วนตัวไว้อย่างชัดเจน)

ในกรณีของคุณ:

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

ยังไม่ชัดเจนว่าเงินเดือนที่แสดงเป็นเซนต์ดอลลาร์ปอนด์ RMB?

เมื่อจัดทำเอกสาร setters / getters ฉันต้องการแยกสิ่งที่ออกจากการเข้ารหัส ตัวอย่าง:

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

บรรทัดแรกบอกว่าจะคืนค่าความสูง พารามิเตอร์การส่งคืนเอกสารที่ความสูงเป็นเมตร


1
ในขณะที่ฉันเห็นด้วยกับคุณฉันคิดว่าเราต้องตรวจสอบให้แน่ใจว่าความคิดเห็นของฟังก์ชันนั้นไม่ได้สร้างชื่อฟังก์ชันที่ไม่ชัดเจนและไม่ชัดเจน
karlipoppins

ฉันเป็นผู้สนับสนุนรายใหญ่ของ JavaDocs แต่ยังเป็นผู้สนับสนุนรายใหญ่ในการจัดทำโค้ดด้วยตนเอง อย่างน้อยสำหรับผู้ตั้งค่าฉันจะทำบางสิ่งบางอย่างเช่นpublic void setSalary(float aud)(หรือตามความเป็นจริงมากขึ้นpublic void setSalary(BigDecimal aud)) ยังดีกว่าทรัพย์สินที่ควรจะเป็นประเภทabstract class CurrencyAmountซึ่งจะมีคุณสมบัติและjava.util.Currency currency java.math.BigDecimal amountนักพัฒนาส่วนใหญ่ที่ฉันเคยทำงานด้วยนั้นขี้เกียจมากกับ JavaDoc แต่การบังคับใช้ API เช่นนี้ทำให้ปัญหานี้น้อยลง
Michael Scheper

หากหน่วยเป็นหน่วย SI เช่นเมตร / วินาทีมีความจำเป็นในการจัดทำเอกสารน้อยลงหากไม่ใช่หน่วย Si จะต้องจัดทำเป็นเอกสารหรือตั้งชื่อให้ดีขึ้นเพื่อรวมหน่วยที่ไม่ได้มาตรฐานเช่น heightFeet
AlexWien

8

ทำไมพวกเขาไม่เพียงแค่ใส่แท็กอ้างอิงเพื่อให้คุณสามารถแสดงความคิดเห็นค่าฟิลด์และข้อมูลอ้างอิงจาก getters และ setters

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

public String getFoo() {
  return foo;
}

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

เพื่อให้เอกสารนำไปใช้กับ getter และ setter ตลอดจนฟิลด์ (ถ้าเปิด javadocs ส่วนตัวอยู่)


ฉันเห็นด้วย. แล้วฉันก็รู้ว่าทำไมต้องเขียนหนังสือสำเร็จรูปทั้งหมดนี้? ดูคำตอบของฉันเกี่ยวกับโครงการลอมบอก
Michael Scheper

7

ชนิดของต้นแบบนี้สามารถหลีกเลี่ยงโดยใช้โครงการลอมบอก เพียงแค่บันทึกตัวแปรฟิลด์แม้ว่าจะเป็นprivateและปล่อยให้คำอธิบายประกอบ Lombok สร้างตัวรับและตัวตั้งค่าที่มีการบันทึกไว้อย่างถูกต้อง

สำหรับผมได้รับประโยชน์นี้เพียงอย่างเดียวมีมูลค่าค่าใช้จ่าย


4

ฉันผิดหวังมากกับคำตอบโดยทั่วไปที่บอกว่าการจัดทำเอกสารที่ครอบคลุมนั้นเสียเวลา วิธีการที่ลูกค้าของ API ของคุณควรจะรู้ว่าวิธีการที่เรียกว่าsetXเป็นมาตรฐานคุณสมบัติหมา JavaBeanเว้นแต่คุณพูดอย่างชัดเจนในเอกสาร ?

หากไม่มีเอกสารผู้โทรจะไม่รู้ว่าวิธีการนี้มีผลข้างเคียงใด ๆ นอกเหนือจากการข้ามนิ้วของพวกเขาเกี่ยวกับการประชุมที่ชัดเจนที่กำลังจะตามมา

ฉันแน่ใจว่าฉันไม่ใช่คนเดียวที่นี่ที่มีความโชคร้ายในการค้นหาวิธีที่ยากที่วิธีการที่เรียกว่าsetXทำอะไรได้มากกว่าการตั้งค่าคุณสมบัติ


11
หากไม่มีเอกสารผู้โทรทุกคนจะคิดว่าเมธอดที่เรียกว่า setX เซ็ต X ตามนั้นถ้า setX ตั้งค่า X จริงโดยไม่ต้องทำอะไรที่สำคัญคุณก็ไม่จำเป็นต้องใช้เอกสาร
mqp

เยี่ยมมาก! ตอนนี้ บริษัท CrudTech ซึ่งมี API ที่ฉันกำลังเข้ารหัสอยู่ทำตามอนุสัญญาของคุณหรือไม่หรือเป็นไปตามของคนอื่นในหัวข้อนี้ อืม
oxbow_lakes

5
ไม่มีประเด็นในการเขียน "กำหนดราคา" ในเอกสาร setPrice หากวิธีการเพียงแค่ตั้งค่าสำหรับคุณสมบัติราคา แต่ถ้ายังเช่นอัปเดตคุณสมบัติ totalPrice และคำนวณภาษีใหม่พฤติกรรมดังกล่าวควรได้รับการบันทึกไว้อย่างชัดเจน
João Marcus

8
ดูเหมือนคุณกำลังขอเอกสารประกอบเพื่อระบุว่า "นี่คือสิ่งที่คุณคาดหวัง" ซึ่งเหมือนกับการเขียน "ข้อควรระวัง: HOT" บนถ้วยกาแฟ ในโลกที่สมบูรณ์แบบไม่จำเป็นต้องพูดแบบนั้น
Kevin Panko

1
ใช่ - เมื่อใช้ API ซึ่งวิธีการที่เรียกว่าสิ่งต่างๆเช่นsetXมีผลข้างเคียงนอกเหนือจากที่คาดไว้ฉันสามารถระบุได้อย่างมั่นใจว่านี่ไม่ใช่โลกที่สมบูรณ์แบบ
oxbow_lakes

4

หากไม่มีการดำเนินการพิเศษใน getter / setter ฉันมักจะเขียน:

ด้วย Javadoc (พร้อมตัวเลือกส่วนตัว):

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

และ / หรือ

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

ด้วย Doxygen (พร้อมตัวเลือกสารสกัดส่วนตัว):

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

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

2
ปัญหาของแนวทางนี้คือ Javadoc ไม่สร้างเอกสารส่วนตัวตามค่าเริ่มต้น! ในกรณีนั้นแท็กอ้างอิง{@see #salary}ไม่ถูกต้องในเอกสารที่สร้างขึ้น
Jarek Przygódzki

1

ผู้เข้าถึงการแสดงความคิดเห็นโดยเฉพาะอย่างยิ่งหากพวกเขาไม่ได้ดำเนินการใด ๆ ที่ใดก็ไม่จำเป็นและสิ้นเปลืองปลายนิ้ว

หากมีคนอ่านรหัสของคุณไม่เข้าใจว่าperson.getFirstName()ส่งคืนชื่อของบุคคลคุณควรพยายามทำทุกอย่างเพื่อให้เขาถูกไล่ออก หากใช้เวทมนตร์ในฐานข้อมูลให้โยนลูกเต๋าสองสามลูกเรียกเลขาธิการแห่งชื่อเพื่อรับชื่อจริงมันปลอดภัยที่จะถือว่าเป็นการดำเนินการที่ไม่สำคัญและบันทึกไว้อย่างดี

ถ้าในทางกลับกันคุณperson.getFirstName()ไม่คืนชื่อของบุคคลนั้น ... ดีไม่ไปที่นั่นเราจะ?


6
จะเกิดอะไรขึ้นถ้า getFirstName () ส่งกลับค่า null? เอกสารนั้นจะเก็บไว้ที่ไหน?
Steve Kuo

แล้ว security.getFinalMaturity () ล่ะ? ไม่ใช่ทุกชื่อคุณสมบัติที่มีความหมายที่เข้าใจได้ทันที คุณต้องการที่จะถูกไล่ออกเพราะไม่รู้ว่ามันหมายถึงอะไร?
Michael Borgwardt

จะเกิดอะไรขึ้นถ้าวิธีนี้ถูกนำไปใช้โดย swizzling? คุณจะรู้ได้อย่างไรว่าเว้นแต่จะได้รับการบันทึกไว้อย่างชัดเจน คุณควรรู้ได้อย่างไรว่าเป็นตัวกำหนดมาตรฐานเว้นแต่เอกสารจะระบุว่าเป็น
oxbow_lakes

2
get / set ในความคิดของฉันควรถูกสงวนไว้สำหรับ getters และ setters การค้นหาฐานข้อมูลควรตั้งชื่อว่า "lookupPerson" หรือมากกว่านั้น
Thorbjørn Ravn Andersen

1

อย่าใส่อะไรเลยหากชื่อฟิลด์นั้นสื่อความหมายได้อย่างชัดเจนถึงเนื้อหา

โดยทั่วไปให้รหัสมีจุดยืนในตนเองและหลีกเลี่ยงการแสดงความคิดเห็นหากเป็นไปได้ อาจต้องมีการปรับโครงสร้างใหม่

แก้ไข: ข้างต้นหมายถึง getters และ setters เท่านั้น ฉันเชื่อว่าอะไรก็ตามที่ไม่สำคัญควรได้รับการ javadoc'ed อย่างถูกต้อง


1
มีความแตกต่างระหว่างการแสดงความคิดเห็นและการจัดทำเอกสาร
Tom Hawtin - แทคไลน์

1
จริงแท้แน่นอน. ดังนั้นจึงเป็นเหตุผลว่าทำไมฉันไม่แสดงความคิดเห็น getters และ setters ควรอธิบายตนเองและการเพิ่มความคิดเห็นบ่งชี้ว่ารหัสนี้ไม่สามารถอธิบายตนเองได้
Thorbjørn Ravn Andersen

0

คุณสามารถกรอกข้อมูลในส่วน (b) ได้โดยเฉพาะอย่างยิ่งถ้าคุณใส่ความคิดเห็นในการประกาศเขตข้อมูลที่ระบุว่าฟิลด์นั้นเกี่ยวกับอะไร


ไม่ดี - คนไม่อ่านความคิดเห็นของสนาม Javadoc ไม่ได้สร้างเอกสารส่วนตัวตามค่าเริ่มต้นและ IDE จะไม่แสดงเอกสารฟิลด์เมื่อคุณใช้ความช่วยเหลือด่วนในการเรียกใช้เมธอด
Trejkaz

ผู้คนไม่อ่านความคิดเห็นในสนามเว้นแต่ว่าพวกเขาจำเป็นต้องอ่าน เมื่อมีความต้องการข้อมูลก็จะยิ่งดีขึ้น
akf


0

ฉันมักจะกรอกทั้งสองอย่าง เวลาที่ใช้ในการพิมพ์เพิ่มเติมนั้นน้อยมากและโดยทั่วไปแล้วข้อมูลจะดีกว่าน้อยกว่า


พวกเขาจะอธิบายตัวเองได้ก็ต่อเมื่อคุณพูดว่า "นี่คือตัวกำหนดคุณสมบัติ" มิฉะนั้นไคลเอนต์ของ API จะไม่รู้ว่าเกิดอะไรขึ้นในวิธีการจริง
oxbow_lakes

1
ใครพูดอะไรเกี่ยวกับการอธิบายตัวเอง?
Paul Sonier
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.