วิธีการห่อหุ้มคลาสภายในใน API ที่เขียนด้วย Java?


9

เราต้องเขียนห้องสมุด โดยปกติมันควรมี API ที่เล็กมาก (กว้างที่สุดเท่าที่จำเป็นเล็กที่สุดเท่าที่จะทำได้) internals ของห้องสมุดค่อนข้างซับซ้อน ดังนั้นพวกเขาต้องการโครงสร้าง

สำหรับโครงสร้างฉันเห็นสองวิธี:

1. ใช้แพ็คเกจ

ข้อดี:ห้องสมุดสามารถจัดโครงสร้างอย่างเรียบร้อย ทุกอย่างในที่ของมัน

ข้อเสีย:การใช้คลาสผ่านขอบแพคเกจจำเป็นต้องใช้คลาสสาธารณะจึงขยาย API ของไลบรารีทั้งหมด

2. ใช้คลาสภายในแบบคงที่ทั้งหมดในแพ็คเกจเดียว

ข้อดี: ต้องการเพียงสิ่งสาธารณะน้อยมาก (คลาส, วิธีการและอื่น ๆ ) ที่จำเป็น

ข้อด้อย:ชั้นเรียนถูกซ่อนไว้เพียงเพื่อจัดโครงสร้างพวกเขา นี่จะเป็นกรณีการใช้งานเพียงไม่กี่กรณีที่มีคลาสภายในแบบสแตติกจำนวนมากใช้อยู่ นักพัฒนาไม่คุ้นเคยกับสิ่งนั้นและอาจมองข้ามพวกเขา


มีวิธีที่ดีกว่าในการบรรลุ API ขนาดเล็กในห้องสมุดที่มีโครงสร้างหรือไม่?

แก้ไข:ฉันลืมพูดถึง: มันเป็นห้องสมุด Android ดังนั้นจึงไม่มี java9


ทำไมคลาสภายในของคุณจำเป็นต้องหยุดนิ่ง
David Arno

ไม่คลาสภายในทำให้โค้ดหน่วยใหญ่ขึ้นใช่ไหม ฉันหมายถึงคลาสที่มีคลาสภายในหลายคลาสอาจยาวมาก
Tulains Córdova

2
@ TulainsCórdovaจุดดีฉันอ่านคำว่า "inner" เป็น "internal" ซึ่งฉันคิดว่า Java เรียกว่า "package-private" วิธีปกติในการสร้าง lib คือการมีหนึ่งแพ็คเกจซึ่งมีคลาสสาธารณะเพียงไม่กี่คลาสโดยมีทุกอย่างที่อยู่ภายใน / แพคเกจส่วนตัว
David Arno

สวัสดี @ frmarkus ฉันพยายามเขียนชื่อคำถามของคุณใหม่ให้เฉพาะเจาะจงมากขึ้นและหลีกเลี่ยง "ไม่ชัดเจนสิ่งที่คุณถาม" ปิดการโหวต อย่าลังเลที่จะแก้ไขอีกครั้งหากคุณคิดว่าคำถามจริงของคุณไม่ถูกต้อง
Andres F.

1
@ TulainsCórdova: ใช่หน่วยรหัสจะได้รับวิธีการที่ยิ่งใหญ่ (3k บรรทัดของรหัสต่อไฟล์) นั่นเป็นปัญหาสำคัญอีกประการหนึ่งของการจัดโครงสร้างแบบนี้
Markus Frauenfelder

คำตอบ:


1

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

มันฉลาดมาก ระวังฉลาด

สิ่งนี้จะบังคับให้คุณติดคลาสหลายคลาสในไฟล์ต้นฉบับเดียวกัน (ซึ่งคุณอาจชอบ) และพา ธ จะมีคำตัวพิมพ์ใหญ่พิเศษ

สิ่งนี้จะบังคับให้คุณเขียนรหัสทดสอบใด ๆ ภายในแพ็คเกจยกเว้นว่าคุณใช้การสะท้อนกลับเพื่อแฮ็กทางจากภายนอก

อื่น ๆ จากนั้นสิ่งนี้จะทำงาน มันจะดูแปลก ๆ

ผู้คนคุ้นเคยกับการใช้คลาสภายในมากขึ้นเช่นEntrySetใน Hashtable มันเป็นแบบส่วนตัวดังนั้นฉันไม่สามารถสร้างมันได้ แต่ใช้อินเทอร์เฟซสาธารณะดังนั้นฉันจึงคุยกับมันผ่านทางอินเทอร์เฟซและมีสิ่งที่ฉันต้องการ

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

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

คุณได้สร้างรูปแบบอื่นที่ทำให้เกิดความบกพร่องในภาษา Java ไม่มีตัวดัดแปลงการเข้าถึงที่ให้สิทธิ์การเข้าถึงกลุ่มของแพ็กเกจ ฉันได้ยินมาว่ามีการเสนอตัวดัดแปลงการเข้าถึง "โมดูล" แต่ไม่เห็นสัญญาณว่าเกิดขึ้น

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

Modifier        Class     Package   Subclass  World
public          Y         Y         Y         Y
protected       Y         Y         Y         N
no modifier     Y         Y         N         N
private         Y         N         N         N 

สิ่งที่คุณต้องการคือการเข้าถึงโมดูล ด้วยวิธีนี้คุณสามารถทำการทดสอบในแพ็คเกจและรหัสอื่นได้ น่าเสียดายที่เราไม่มีใน Java

คนส่วนใหญ่ทำ 1 และขยาย API การใช้อินเตอร์เฟซที่เหมาะสมจะช่วยลดแรงกดดันในการใช้

การแฮ็กสิ่งที่คุณต้องการให้เป็น 1 นั้นน่าเกลียดมาก ดูที่ call stack และโยนข้อยกเว้นเมื่อใดก็ตามที่สิ่งที่เรียกว่าคุณมาจากแพ็คเกจที่คุณไม่ชอบ Eeew


3

แยกรหัสของคุณออกเป็นแพ็คเกจ มันจะไปไกลในการปรับปรุงการบำรุงรักษา

เพื่อป้องกันไม่ให้ผู้ใช้ปลายทางเข้าถึงสิ่งที่ไม่ควรทำคุณต้องแยก API ของคุณออกเป็นส่วนต่อประสานและการใช้งาน

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

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


1
น่าเสียดายที่นี่ไม่เสร็จสมบูรณ์ สิ่งนี้ทำให้ชั้นเรียนสาธารณะจำนวนมาก พวกเขาอาจมีคำแนะนำ (เป็นโรงงานหรือ 'ภายใน') แต่ฉันต้องใช้เครื่องมือเพิ่มเติมกับพวกเขา (กับชั้นสาธารณะทั้งหมด ) นี่ไม่ดี
Markus Frauenfelder

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