หลักการตั้งชื่อพารามิเตอร์ประเภททั่วไปสำหรับ Java (มีหลายตัวอักษร)?


125

ในบางอินเทอร์เฟซฉันเขียนว่าฉันต้องการตั้งชื่อพารามิเตอร์ประเภททั่วไปที่มีอักขระมากกว่าหนึ่งตัวเพื่อให้โค้ดอ่านง่ายขึ้น

สิ่งที่ต้องการ....

Map<Key,Value>

แทนสิ่งนี้ ...

Map<K,V>

แต่เมื่อพูดถึงวิธีการ type-parameters จะดูเหมือน java-class ซึ่งทำให้สับสนเช่นกัน

public void put(Key key, Value value)

ดูเหมือนว่าคีย์และค่าจะเป็นคลาส ฉันพบหรือนึกถึงสัญกรณ์บางอย่าง แต่ไม่มีอะไรเหมือนกับการประชุมจาก Sun หรือแนวปฏิบัติที่ดีที่สุดทั่วไป

ทางเลือกอื่นที่ฉันเดาหรือพบ ...

Map<KEY,VALUE>
Map<TKey,TValue>

9
ทำไมคุณถึงต้องการสร้างอนุสัญญาใหม่
Amir Afghani

13
@AmirAfghani จากคำถาม: เพื่อให้โค้ดอ่านง่ายขึ้น
SantiBailors

ในทางเทคนิคแล้วเฉดสีที่แตกต่างกันของชื่อสามัญใน IDE ควรเป็นตัวบ่งชี้ที่ดีพอ
Sudix

คำตอบ:


182

Oracle แนะนำสิ่งต่อไปนี้ในJava Tutorials> Generics> Generic types :

พิมพ์ข้อตกลงการตั้งชื่อพารามิเตอร์

ตามแบบแผนชื่อพารามิเตอร์ชนิดเป็นอักษรตัวพิมพ์ใหญ่ตัวเดียว สิ่งนี้มีความแตกต่างอย่างชัดเจนกับรูปแบบการตั้งชื่อตัวแปรที่คุณรู้อยู่แล้วและด้วยเหตุผลที่ดี: หากไม่มีหลักการนี้จะเป็นการยากที่จะบอกความแตกต่างระหว่างตัวแปรประเภทกับคลาสหรือชื่ออินเทอร์เฟซธรรมดา

ชื่อพารามิเตอร์ชนิดที่ใช้บ่อยที่สุด ได้แก่ :

  • E - องค์ประกอบ (ใช้อย่างกว้างขวางโดย Java Collections Framework)
  • K - คีย์
  • N - หมายเลข
  • T - ประเภท
  • V - ค่า
  • S, U, V เป็นต้น - ประเภทที่ 2, 3, 4

คุณจะเห็นชื่อเหล่านี้ที่ใช้ใน Java SE API และส่วนที่เหลือของบทเรียนนี้

ฉันจะปฏิบัติตามเพื่อหลีกเลี่ยงความสับสนระหว่างผู้พัฒนาและผู้ดูแลที่เป็นไปได้


14
เฟรมเวิร์กสตรีมใหม่ยังใช้Rสำหรับผลลัพธ์และAสำหรับตัวสะสม
vandale

32
Blech การตั้งชื่อแบบอักษรตัวเดียว ฉันทำตามการประชุมนี้เพราะการประชุมมีความสำคัญมากกว่าชื่อที่สื่อความหมายได้ แต่มันน่าเศร้าที่นี่เป็นสิ่งที่ดีที่สุดที่พวกเขาจะคิดได้
warbaker

4
@warbaker: ฉันพบว่าเป็นวิธีที่ดีในการแยกแยะประเภทที่กำหนดพารามิเตอร์จากคลาสจริง คุณจะบอกได้อย่างไรว่าเช่นElementในList<Element>เป็นประเภทพารามิเตอร์หรือคลาส?
BalusC

1
ดูเหมือนจะไม่เป็นBiFunction<T, U, R>ไปตามอนุสัญญานี้ BiFunction<T, S, R>ถ้ามันไม่ได้ก็จะเป็น
michaelsnowden

4
เหตุใดจึงต้องกังวลเกี่ยวกับการแยกประเภทพารามิเตอร์จากคลาสจริง พวกเขาเป็นชั้นเรียน ไม่ว่าจะเป็นอย่างไรคุณต้องเลื่อนขึ้นที่ใดที่หนึ่งในไฟล์เพื่อดูว่ามันถูกกำหนดให้เป็นอะไร และจะเป็นประเภทอิมพอร์ตหรือแบบกำหนดพารามิเตอร์
Vectorjohn

47

ผนวก Type

การสนทนาที่ดีสามารถพบได้ในการแสดงความคิดเห็นบนหน้า DZone ที่ตั้งชื่ออนุสัญญาสำหรับประเภท Parameterized

ดูความคิดเห็นโดย Erwin Mueller คำพูดของเขาทำให้ความรู้สึกที่เห็นได้ชัดสมบูรณ์แบบกับฉัน: ต่อท้ายคำว่าType

เรียกแอปเปิ้ลว่าแอปเปิ้ลรถยนต์ ชื่อที่เป็นปัญหาคือชื่อประเภทข้อมูลใช่ไหม (ในOOPคลาสจะกำหนดประเภทข้อมูลใหม่เป็นหลัก) จึงเรียกมันว่า "ประเภท"

ตัวอย่างของ Mueller ดึงมาจากบทความของโพสต์ต้นฉบับ:

public interface ResourceAccessor < ResourceType , ArgumentType , ResultType > {
    public ResultType run ( ResourceType resource , ArgumentType argument );
}

ผนวก T

คำถามที่ซ้ำกันให้คำตอบนี้โดย Andy Thomas หมายเหตุตัดตอนมาจากคู่มือสไตล์ของ Google Tที่แสดงให้เห็นชื่อประเภทตัวอักษรหลายควรจะจบในตัวพิมพ์ใหญ่เพียงครั้งเดียว


3
ฉันชอบคำตอบนี้ การเพิ่ม "ประเภท" มีความชัดเจนและช่วยให้คุณมีชื่อที่สื่อความหมายได้ ฉันเบื่อที่จะมีคนพูดว่า "ทำไปเพราะมันเป็นแบบแผน" โดยไม่มีเหตุผลอื่นใด หากเป็นการประชุมที่ไม่ดีบางทีเราอาจจะต้องสร้างใหม่
ดึง

16

เหตุผลที่หลักการตั้งชื่ออย่างเป็นทางการใช้อักษรตัวเดียวมีดังต่อไปนี้:

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

ฉันคิดว่าด้วย IDE สมัยใหม่เหตุผลนั้นใช้ไม่ได้อีกต่อไปเช่น IntelliJ Idea แสดงพารามิเตอร์ประเภททั่วไปที่มีสีแตกต่างจากคลาสปกติ

รหัสที่มีประเภททั่วไปตามที่แสดงใน IntelliJ Idea 2016.1 รหัสที่มีประเภททั่วไปตามที่แสดงใน IntelliJ Idea 2016.1

เนื่องจากความแตกต่างนั้นฉันจึงใช้ชื่อที่สื่อความหมายที่ยาวกว่าสำหรับประเภททั่วไปของฉันโดยมีรูปแบบเดียวกันกับประเภททั่วไป ฉันหลีกเลี่ยงการเพิ่มคำนำหน้าและคำต่อท้ายเช่น T หรือ Type เนื่องจากฉันคิดว่าเป็นเสียงที่ไม่จำเป็นและไม่จำเป็นต้องแยกแยะประเภททั่วไปด้วยสายตาอีกต่อไป

หมายเหตุ: เนื่องจากฉันไม่ได้เป็นผู้ใช้ Eclipse หรือ Netbeans ฉันจึงไม่รู้ว่าพวกเขามีฟีเจอร์ similliar หรือไม่


ฉันจะไม่ใช้หลักการตั้งชื่อตามความสามารถของเครื่องมือที่แต่ละคนเคยอ่าน / แก้ไขไฟล์เดียวกันนั้น โดยส่วนตัวฉันชอบใช้โปรแกรมแก้ไขข้อความสำหรับการเข้ารหัส (Sublime Text) ซึ่งไม่ใช่ IDE ตัวแก้ไขข้อความในปัจจุบันมักจะมีการระบายสีไวยากรณ์ แต่ไม่เข้าใจอย่างลึกซึ้งเกี่ยวกับโครงสร้างโค้ดที่เป็นพื้นฐานซึ่งฉันคิดว่าจะต้องใช้ชื่อตัวแปรประเภทสีให้ถูกต้อง และการพิจารณาจากข้อโต้แย้งนี้เกี่ยวกับสีนั้นมีไว้สำหรับคนที่มีการมองเห็นสีไม่ดีโดยเนื้อแท้ (ฉันเป็นส่วนหนึ่งของผู้ชาย 8% ที่ตาบอดสีแดง - เขียว)
joonas.fi

1
จุดดีเกี่ยวกับผู้ที่มีการมองเห็นสีไม่ดี เกี่ยวกับการไม่ใช้ IDE - หากผู้คนชอบใช้โปรแกรมแก้ไขข้อความธรรมดาก็ใช้ได้ แต่พวกเขายอมสละคุณสมบัติที่ IDE เสนอให้พวกเขาโดยสมัครใจเพื่อประโยชน์ของเครื่องมือที่มีน้ำหนักเบากว่า นี่อาจเป็นเพียงหนึ่งในคุณสมบัติที่ขาดหายไป ในท้ายที่สุดหากใช้ชื่อที่สื่อความหมายแทนตัวอักษรตัวเดียวคุณควรจะสามารถบอกความหมายตามชื่อที่ไม่มี IDE และไม่มีรหัสสี การเข้ารหัสสีทำให้สิ่งนี้เร็วขึ้น
Vojtech Ruzicka

16

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

สิ่งนี้แตกต่างจากการประชุมที่ซันแนะนำโดยมีการเปิดตัวยาชื่อสามัญในปี 2547 อย่างไรก็ตาม:

  • มีมากกว่าหนึ่งอนุสัญญา
  • ชื่อหลายตัวละครที่มีความสอดคล้องกับรูปแบบ Java อื่น ๆ เช่นรูปแบบของ Google สำหรับ Java
  • ชื่อที่อ่านได้นั้น (แปลกใจ!) อ่านได้มากขึ้น

การอ่าน

ในบางอินเทอร์เฟซฉันเขียนว่าฉันต้องการตั้งชื่อพารามิเตอร์ประเภททั่วไปที่มีอักขระมากกว่าหนึ่งตัวเพื่อให้โค้ดอ่านง่ายขึ้น

การอ่านเป็นสิ่งที่ดี

เปรียบเทียบ:

    public final class EventProducer<L extends IEventListener<E>,E> 
            implements IEventProducer<L,E> {

ถึง:

    public final class EventProducer<LISTENER extends IEventListener<EVENT>,EVENT> 
           implements IEventProducer<LISTENER, EVENT> {

หรือด้วยแบบแผนหลายอักขระของ Google:

    public final class EventProducer<ListenerT extends IEventListener<EventT>,EventT> 
           implements IEventProducer<ListenerT, EventT> {

    public final class EventProducer<ListenerT extends IEventListener<EventT>,EventT> 
           implements IEventProducer<ListenerT, EventT> {

สไตล์ Google

คู่มือสไตล์ Google Javaช่วยให้ทั้งชื่อตัวอักษรเดียวและชั้นเหมือนตัวอักษรหลายชื่อที่ลงท้ายด้วย T.

5.2.8 พิมพ์ชื่อตัวแปร

ตัวแปรแต่ละประเภทมีชื่อหนึ่งในสองสไตล์:

  • จดหมายทุนเดียวตามด้วยเลขเดียว (เช่นE, T, X, T2)

  • ชื่อในแบบฟอร์มที่ใช้สำหรับคลาส (ดูหัวข้อ 5.2.2 ชื่อคลาส ) ตามด้วยอักษรตัวใหญ่ T (ตัวอย่าง: RequestT, FooBarT)

ประเด็น

“ หากไม่มีหลักการนี้จะเป็นการยากที่จะบอกความแตกต่างระหว่างตัวแปร type กับคลาสหรือชื่ออินเตอร์เฟสธรรมดา” - จากบทช่วยสอนของ Oracle "ประเภททั่วไป"

ชื่ออักขระเดี่ยวไม่ใช่วิธีเดียวในการแยกแยะพารามิเตอร์ประเภทจากชื่อคลาสดังที่เราได้เห็นข้างต้น

ทำไมไม่เพียงแค่บันทึกความหมายของพารามิเตอร์ type ใน JavaDoc?

เป็นความจริงที่@paramองค์ประกอบ JavaDoc สามารถให้คำอธิบายที่ยาวขึ้นได้ แต่ก็เป็นความจริงเช่นกันที่ JavaDocs ไม่จำเป็นต้องมองเห็นได้ (ตัวอย่างเช่นมีเนื้อหาช่วยใน Eclipse ที่แสดงชื่อพารามิเตอร์ชนิด)

ชื่อพารามิเตอร์ชนิดหลายอักขระไม่เป็นไปตามข้อตกลงของ Oracle!

อนุสัญญาดั้งเดิมของ Sun หลายฉบับปฏิบัติตามเกือบทั่วโลกในการเขียนโปรแกรม Java

อย่างไรก็ตามอนุสัญญาเฉพาะนี้ไม่ได้

ทางเลือกที่ดีที่สุดในการประชุมที่แข่งขันกันเป็นเรื่องของความคิดเห็น ผลของการเลือกอนุสัญญาอื่นที่ไม่ใช่ของ Oracle ในกรณีนี้มีน้อย คุณและทีมของคุณสามารถเลือกการประชุมที่ตรงกับความต้องการของคุณมากที่สุด


15

คุณสามารถใช้ javadoc เพื่อให้เบาะแสแก่ผู้ใช้คลาสทั่วไปของคุณเป็นอย่างน้อย ฉันยังไม่ชอบ (ฉันเห็นด้วยกับ @ chaper29) แต่เอกสารช่วยได้

เช่น,

/**
 * 
 * @param <R> - row
 * @param <C> - column
 * @param <E> - cell element
 */
public class GenericTable<R, C, E> {

}

สิ่งอื่น ๆ ที่ฉันรู้ว่าทำคือใช้ IDE ของฉันเพื่อ refactor คลาสที่ทำลายอนุสัญญา จากนั้นทำงานกับรหัสและ refactor กลับเป็นตัวอักษรเดี่ยว ทำให้ง่ายขึ้นสำหรับฉันถ้าใช้พารามิเตอร์หลายประเภท


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