เหตุใดแพ็คเกจและโมดูลจึงเป็นแนวคิดแยกต่างหากใน Java 9


21

Java 9 จะมีโมดูลเพิ่มเติมจากแพ็คเกจ ภาษามักจะมีอย่างใดอย่างหนึ่ง และโปรแกรมเมอร์ส่วนใหญ่รับรู้ศัพท์สองคำว่าเป็นคำพ้องความหมาย โมดูลถูกสร้างขึ้นบนบรรจุภัณฑ์โดยถือเป็นโมดูลดั้งเดิม รูปแบบคอมโพสิตแนะนำให้รักษาแบบดั้งเดิมและคอมโพสิตอย่างสม่ำเสมอ สิ่งที่ไม่ดีจะเกิดขึ้น ตัวอย่างเช่นดูโครงการ Valhalla ที่พวกเขาพยายามติดตั้ง supertype ทั่วไปสำหรับประเภทดั้งเดิม (ค่า) และประเภทการอ้างอิง

โมดูลและแพคเกจเป็นตัวแทนของความคิดแยกความหมายหรือไม่ หมายความว่ามีเหตุผลที่จะต้องมีทั้งภาษาใด ๆ (แยกความกังวล) หรือ Java จะต้องมีทั้งคู่เป็นส่วยให้เข้ากันได้ย้อนหลัง?

ทำไมแนะนำแนวคิดใหม่แทนที่จะเพิ่มแนวคิดที่มีอยู่


JSR 376 : "Java ระบบโมดูลแพลตฟอร์ม" ดำเนินการภายในโครงการจิ๊กซอว์

ตามSOTMS

โมดูลคือชุดของโค้ดและข้อมูลที่อธิบายตนเอง รหัสของมันถูกจัดระเบียบเป็นชุดของแพคเกจที่ประกอบด้วยชนิดเช่นคลาส Java และอินเตอร์เฟส ข้อมูลรวมถึงทรัพยากรและข้อมูลคงที่ประเภทอื่น ๆ

JLS ระมัดระวังหลีกเลี่ยงการกำหนดสิ่งที่เป็นแพคเกจ จากวิกิพีเดีย :

แพคเกจ Java เป็นเทคนิคสำหรับการจัดคลาส Java เป็นเนมสเปซที่คล้ายกับโมดูลของ Modula โดยให้การเขียนโปรแกรมแบบแยกส่วนใน Java

ฉันรู้ว่าการอ้างถึงวิกิพีเดียเป็นการปฏิบัติที่ไม่ดี แต่สะท้อนถึงความเข้าใจร่วมกัน จากรายการในการเขียนโปรแกรมแบบแยกส่วน:

บางครั้งคำว่าแพ็คเกจใช้แทนโมดูล (เช่นใน Dart, Go หรือ Java) ในการนำไปใช้อื่น ๆ นี่เป็นแนวคิดที่แตกต่าง ใน Python แพคเกจคือชุดของโมดูลในขณะที่ใน Java 9 ที่กำลังจะมีการแนะนำแนวคิดของโมดูลใหม่


3
ฉันคิดว่าคุณกำลังถามคำถามมากมายด้วยกันที่นี่ใช่ไหม 1) โมดูลและแพ็กเกจเป็นแนวคิดทางความหมายเดียวกันหรือไม่ 2) (ถ้าไม่ใช่ 1) jigsawโมดูลสไตล์เป็นเพียงการปรับปรุงทางเทคนิคเหนือแพ็คเกจหรือไม่ 3) (ถ้าไม่ใช่ 1 และถ้า 2) เป็นเพียง Java (หรือดูเหมือน) เพื่อรักษาแนวคิดทั้งสองเพื่อความเข้ากันได้ย้อนหลัง คำถามเหล่านี้บางคำถามสามารถตอบคำถามได้บางคำถามเป็นคำถามเชิงความคิดเห็นเป็นหลัก ฉันคิดว่าการแก้ไขที่ทำให้คำอธิบายที่ต้องการนั้นง่ายขึ้น
Tersosauros

1
@Tersosauros คุณได้จัดทำคำถาม "บางส่วน" เป็นนอกหัวข้อ แต่ไม่ได้ติดป้ายกำกับว่าคำถามใด ฉันเห็นว่าเป็นคำถามเดียวเท่านั้น (1) อื่น ๆ จะได้รับการแก้ไขโดยอัตโนมัติ ความเข้ากันได้ย้อนหลังสำหรับ java ไม่ใช่คำถาม ดังนั้นจาวาแนะนำโมดูลเพื่อแก้ไขข้อบกพร่องการออกแบบแพคเกจหรือสองความคิดเป็นความกังวลอย่างแท้จริง และความสับสนเกิดจากการตั้งชื่อไม่ดี
user2418306

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

อ่าฉันเข้าใจความสับสน ฉันคิดว่าคำถาม # 1 สามารถตอบได้ (คำตอบนั้นคือ "ใช่ แต่ไม่ใช่" - ซึ่งเป็นที่ # 3 เข้ามา) ฉันเห็นด้วยกับ # 3 เห็นได้ชัดว่า Java ไม่เกี่ยวกับการเปลี่ยนแปลงสิ่งที่คำหลักภาษาเช่นpackage/ ทำ / หมายถึงและพวกเขาจะไม่เปลี่ยนเป็นระบบ classpath ในระบบ JRE คำถาม # 2 ผมรู้สึกเป็นส่วนใหญ่มีความคิดเห็นเชิง (ก็ตอบแต่คำตอบของฉันและคนอื่นอาจแตกต่างกันและเราไม่จำเป็นจะผิด)
Tersosauros

1
ลองถามคำถามที่ชัดเจนล่วงหน้าแล้วจัดหาวัสดุที่สนับสนุน
Jay Elston

คำตอบ:


22

แนวคิดของโมดูลจะแตกต่างจากการเริ่มของแนวคิดว่า

Java มีโมดูลเสมอ เมธอดคือโมดูลดังนั้นคลาสจึงเป็นแพ็กเกจ โมดูลคือหน่วยขององค์กรที่รายละเอียดภายในถูกซ่อนไว้และสื่อสารกับโมดูลอื่นผ่านสัญญาที่ตกลงกันไว้ ตัวอย่างเช่นวิธีการเป็นโมดูลเพราะมันมี internals ที่ซ่อนอยู่ (รหัสและตัวแปรท้องถิ่น) และสัญญา (พารามิเตอร์และประเภทผลตอบแทน) โมดูลสามารถประกอบด้วยโมดูลระดับล่างได้เช่นคลาสมีเมธอด

สิ่งที่ขาดหายไปใน core Java (pre-9) เป็นโมดูลที่ปรับใช้ได้ โมดูลประเภทข้างต้นทั้งหมดไม่สามารถปรับใช้หน่วยที่สามารถคัดลอกได้ Java มีส่วนที่สามารถนำไปใช้งานได้ที่เรียกว่าไฟล์ JAR แต่สิ่งเหล่านี้ไม่ใช่โมดูลเนื่องจากไม่มีการห่อหุ้มหรือสัญญา: ไฟล์ JAR ขณะรันไทม์หายไปทั้งหมดรวมเข้าด้วยกันเป็น "classpath" เดียว

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

Java 9 เน้นการขาดโมดูลที่ปรับใช้งานได้ในลักษณะที่คล้ายคลึงกับ OSGi เนื้อหานี้ไม่จำเป็นอย่างสมบูรณ์เพราะ OSGi มีอยู่และทำงานได้ แต่นั่นเป็นการสนทนาที่แตกต่างกันโดยสิ้นเชิง ...

น่าเสียดายที่ Java 9 ทำให้โคลนโดยการตั้งชื่อแนวคิดโมดูลใหม่เพียงแค่ "โมดูล" นี่ไม่ได้หมายความว่าวิธีการเรียนและแพคเกจหยุดเป็นโมดูล! J9 "โมดูล" เป็นเพียงการเริ่มของโมดูลอื่นแนวคิด เช่นเดียวกับบันเดิล OSGi โมดูล J9 ทำจากแพ็คเกจและเป็นวัตถุทางกายภาพ (โดยปกติคือไฟล์ JAR อีกครั้ง) ที่สามารถคัดลอกได้ ระบบรันไทม์เข้าใจและกลับมาใช้ใหม่

สรุป: ใช่โมดูล J9 และแพ็คเกจเป็นความคิดแยกกัน เห็นได้ชัดว่า Java ต้องรักษาแนวคิดแพคเกจที่มีอยู่ไว้เพื่อให้เข้ากันได้ โปรดทราบว่าคำว่า "แพ็คเกจ" นั้นใช้ใน Java ค่อนข้างแตกต่างจากภาษาอื่น ๆ หรือในระบบการจัดการแพ็กเกจเช่น RPM โมดูล J9 ใหม่ (และบันเดิล OSGi) เป็นเหมือนแพ็คเกจใน RPM มากกว่าแพ็คเกจ Java ที่เคยมีมา


แพ็คเกจไม่เป็นไปตามข้อกำหนดของโมดูล เนื่องจากการห่อหุ้มที่อ่อนแอและขาดวิธีการรวมแพ็คเกจอื่น ๆ และปรับแต่งการมองเห็นของพวกเขา คลาสสามารถมีคลาสหรือฟิลด์ที่ซ้อนกัน วิธีการอาจมีการปิดหรือเรียกวิธีการอื่น แพ็คเกจไม่สามารถ "สื่อสาร" กับแพ็คเกจอื่นได้
user2418306

ฉันไม่เห็นด้วย. แพคเกจมีการซ่อนข้อมูล (ชนิดการเข้าถึงเริ่มต้นวิธีการและเขตข้อมูล aka แพคเกจส่วนตัว) แพคเกจแน่นอน "สื่อสาร" เพราะรหัสภายในแพ็คเกจสามารถเรียกใช้รหัสในแพ็คเกจอื่น ๆ สิ่งนี้กระทำได้กับการทำสัญญาคือประเภทสาธารณะและวิธีการของแพ็คเกจอื่น ๆ
Neil Bartlett

โปรดทราบว่าความสามารถในการรวมส่วนโมดูลาร์ในระดับเดียวกัน (เช่นวิธีการที่ประกอบด้วยการปิดคลาสที่มีคลาสที่ซ้อนกัน) ไม่ได้เป็นส่วนหนึ่งของคำจำกัดความของโมดูล หากคุณคิดว่านี่เป็นส่วนที่จำเป็นของคำนิยามโมดูลดังนั้น "โมดูล Java 9" ไม่ใช่โมดูลเช่นกัน
Neil Bartlett

ผมไม่ปฏิเสธว่าแพคเกจที่มีที่หลบซ่อนข้อมูล ฉันบอกว่ามันไม่เพียงพอ importสามารถแพคเกจคู่ แต่ไม่มีวิธีการจัดโครงสร้างแพ็คเกจเป็นพลเมืองชั้นหนึ่ง ข้อบกพร่องเหล่านั้น (และข้อ จำกัด ของ OSGi) มีการอธิบายไว้ใน JSR 376
2418306

คุณช่วยอธิบายได้ไหมว่าทำไมโมดูล Java 9 ถึงไม่ใช่โมดูลเช่นกัน ?
user2418306

10

ให้ฉันได้คำตอบที่เป็นอันตรายถึงแม้ว่ามันอาจจะเป็นข้อสันนิษฐาน / การแยกผม / คุยโวเป็นต้น

พวกเขาเป็นสิ่งเดียวกันหรือไม่ ก็ใช่และไม่ใช่

จากบทความ JavaWorld นี้เกี่ยวกับ "Modularity in Java 9" :

แพ็คเกจเป็นโซลูชันแบบแยกส่วน

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

ในฐานะที่เป็น@ user2418306 (OP)พูดเป็นนัย" โมดูลแพคเกจทำถูกต้อง " โมดูลและแพ็คเกจใน Java (เหมือนของ Java 9, ชัด) คือ (ตาม OP ถาม) ความหมายในสิ่งเดียวกัน นั่นคือพวกเขามีคอลเลกชันของก่อนรวบรวม JVM bytecode, กับเมตาดาต้าอื่น ๆ - เป็นหลักพวกเขามีห้องสมุด

ความแตกต่างคืออะไร?

อย่างไรก็ตามความแตกต่างนั้นอยู่ในข้อมูลเมตาภายในแต่ละรายการ Java packagemanifests หรือ JAR ไม่ปรากฏบ่อยนักโดยนักพัฒนาห้องสมุดและพวกเขาก็ไม่ได้ทำสัญญาใด ๆ กับ JAR / แพ็คเกจ ตามที่อธิบายไว้ที่นี่ (บทความ JavaWorld อีกครั้ง) :

ไฟล์ JAR ไม่เพียงพอหรือไม่

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


พูดจาโผงผางเกี่ยวกับภาษา / สภาพแวดล้อมอื่น ๆ ฯลฯ

พื้นที่อื่นที่กล่าวถึงในบทความนั้นคือระบบเช่นMavenซึ่งจัดการการพึ่งพาสำหรับคุณเป็นส่วนหนึ่งของกระบวนการสร้าง จากหน้านี้ในเว็บไซต์ Apache Maven :

การจัดการการพึ่งพา:

Maven ส่งเสริมการใช้พื้นที่เก็บข้อมูลกลางของ JARs และการอ้างอิงอื่น ๆ Maven มาพร้อมกับกลไกที่ลูกค้าของโครงการของคุณสามารถใช้เพื่อดาวน์โหลด JARs ใด ๆ ที่จำเป็นสำหรับการสร้างโครงการของคุณจากที่เก็บ JAR ส่วนกลางเหมือนกับ CPAN ของ Perl สิ่งนี้จะช่วยให้ผู้ใช้ Maven สามารถนำ JAR กลับมาใช้ซ้ำในโครงการต่างๆและสนับสนุนการสื่อสารระหว่างโครงการเพื่อให้แน่ใจว่าจะจัดการกับปัญหาความเข้ากันได้แบบย้อนหลังได้

ตอนนี้พูดถึงอนาคตราวกับว่าฉันอยู่ที่นั่น

ตามที่กล่าวถึงหน้าภาษาอื่น ๆ (เช่น Perl) มีที่เก็บแพ็กเกจ (เช่นCPAN ) นี่คือแนวโน้มที่เพิ่มขึ้น (ฉันพูดเพราะฉันรู้สึกว่ามันไม่มีข้อพิสูจน์ที่ชัดเจนใด ๆ ) ในช่วงทศวรรษที่ผ่านมา เครื่องมือเช่นอัญมณีของ Ruby , PyPiของ Python และNode package manager ( npm)สร้างขึ้นเพื่อให้วิธีการที่สอดคล้องกันในการกำหนดค่าสภาพแวดล้อม (ทั้งการพัฒนาการสร้างการทดสอบหรือการรันไทม์ ฯลฯ ) ด้วยสิ่งที่ถูกต้อง(แพ็คเกจโมดูล อัญมณีของ gizmo ฯลฯ ) แนวคิด (ฉันรู้สึก) คือ" ยืม"จากระบบจำหน่าย Linux เช่น abian's apt , RedHat'srpmฯลฯ (แม้ว่าเห็นได้ชัดว่ามีการพัฒนาอย่างน้อยหนึ่งรุ่นและทำให้สิ่งเหล่านี้ทั้งหมดดีกว่า)


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


1
บทความมีอายุเพียง 1 ปีและยังล้าสมัยไปแล้ว มันอาศัยอยู่ว่าการกำหนดเวอร์ชันเป็นคุณสมบัติพื้นฐานของโมดูล โมดูลตัวต่อจะไม่มีข้อมูลรุ่น ไม่มีสิ่งใดในขอบเขตของการจัดการการพึ่งพาที่จะเปลี่ยนแปลงสำหรับผู้ใช้ปลายทาง สำหรับการสร้างเครื่องมือสิ่งต่าง ๆ จะยิ่งยากขึ้นในความเป็นจริง ขณะที่พวกเขาจำเป็นต้อง suport ความเป็นจริงขนานของและclasspath modulepathและกระโดดผ่านห่วงเพื่อสนับสนุนการทดสอบหน่วย ตั้งสมมติฐานว่าแนวคิดสองแนวคิดนั้นเทียบเท่ากันเพราะเป็นตัวแทนของสิ่งต่าง ๆ รวมทั้งข้อมูลเมตาที่กล้าหาญเกินกว่าที่ฉันจะยอมรับได้ บวกกึ่งกลางคุณก็แทนที่ไหสำหรับแพ็คเกจ
user2418306

ฉันไม่ได้พูดว่า " สองแนวคิดเทียบเท่ากัน " ฉันบอกว่ามันเป็น "ความหมายเหมือนกัน" - ซึ่งเป็นสิ่งที่คุณถาม นอกจากนี้คุณยังได้แก้ไขคำถามตั้งแต่ฉันตอบจะกล่าวถึงเฉพาะ JSR-376เป็นคัดค้านเพื่อจิ๊กซอว์ซึ่งเป็นสิ่งที่ถูกกล่าวว่าก่อนหน้านี้: - /
Tersosauros

จิ๊กซอว์บนโลกไซเบอร์ (ดำเนินการ) JSR-376 คำถามยังคงเชื่อมโยงกับทั้งคู่ดังนั้นจึงไม่มีอันตรายใด ๆ เกิดขึ้น พจนานุกรมกำหนดความเทียบเท่าเป็นคุณภาพหรือสถานะของการมีความหมายเดียวกัน และความหมาย - โดยคำนึงถึงความหมาย ฉันขอโทษ แต่คุณอวดความเห็นเกี่ยวกับรายละเอียดที่ผิดที่นี่ คุณเคยบอกว่ามันเทียบเท่ากัน แต่คุณไม่ได้ให้เหตุผลใด ๆ แต่คุณอ้างถึงบทความที่อธิบายว่าแพคเกจและขวดล้มเหลวในการเป็นโมดูล แต่โมดูลที่กำลังจะมาไม่เป็นโมดูลจากบทความด้วย การอ้างความเท่าเทียมกันแล้วให้ความแตกต่างระหว่าง 2 (3) นั้นขัดแย้งกับตนเอง
2418306

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