การแยกโปรเจ็กต์ java


12

ฉันมีโปรเจ็กต์ java ขนาดใหญ่และเราใช้ maven สำหรับวงรอบการสร้างของเรา โครงการนี้มีการใช้อย่างกว้างขวาง - ในโครงการอื่น ๆ ในแอปพลิเคชั่นต่าง ๆ ซึ่งบางส่วนอยู่ในนั้นและบางส่วนอยู่ที่อื่น ... พูดตามตรงแล้วมันเป็นระเบียบนิดหน่อย วัตถุประสงค์) และฉันต้องการทำความสะอาดสักหน่อย นอกจากนี้ยังไม่ผ่านการทดสอบอย่างสมบูรณ์ (มีการเพิ่มบิตจำนวนมากโดยไม่มีหน่วยที่เหมาะสมและการทดสอบการรวม) และมีการทดสอบบางอย่างที่ใช้เวลานานในการรันหรือไม่ผ่านจริง ... (uh-oh) - ดังนั้น การทดสอบจะถูกปิดในวงจรสร้าง maven (อีกครั้ง uh-oh)

ฉันกำลังคิดที่จะแยกโครงการขนาดใหญ่นี้ออกเป็นโครงการขนาดเล็กโดยเฉพาะเช่นโครงการย่อย 'สุดท้าย' (หรือโครงการย่อยหลายโครงการ) จะรับโครงการย่อยต่าง ๆ ที่มันต้องการ

ความคิดของฉันเป็นดังนี้:

  • ถ้าฉันแยกโครงการใหญ่ออกเป็นโครงการย่อยต่าง ๆ นี่จะทำให้ชัดเจนว่าความรับผิดชอบของแต่ละโครงการคืออะไร
  • โดยแยกเป็นโครงการย่อยฉันสามารถล้างการทดสอบของแต่ละโครงการย่อยทีละรายการและเปิดการทดสอบสำหรับโครงการย่อยนั้นในวงจรการสร้าง maven

ฉันกังวลเล็กน้อยเกี่ยวกับผลกระทบที่อาจเกิดขึ้นกับเวลาสร้าง

  • การวางโครงสร้างในโครงการขนาดใหญ่ (เช่นเป็นโครงการย่อยขนาดเล็ก) จะทำให้คอมไพเลอร์ช้าลงหรือไม่

นอกจากนี้ฉันมีข้อกังวลเล็กน้อยเกี่ยวกับผลกระทบที่อาจเกิดขึ้นกับการแก้ไขเวลาใน IDEs (เราใช้ Intellij เป็นหลัก) Intellij ดูเหมือนว่าจะสร้างแต่ละโครงการผ่านแผนผังการพึ่งพา - เช่นถ้า C ขึ้นอยู่กับ B ขึ้นอยู่กับ A และฉันเปลี่ยน A มันจะไม่พยายามสร้าง B ยกเว้นการคอมไพล์และอื่น ๆ อาจเป็นข้อได้เปรียบ แต่ฉันพบว่าถ้า - ตัวอย่างเช่นฉันเปลี่ยนอินเทอร์เฟซใน A ที่ใช้กันอย่างแพร่หลายใน B และ C มันต้องใช้เวลาพอสมควรในการแก้ไขข้อผิดพลาดทั้งหมดจากการเปลี่ยนแปลงนั้น ...

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

ในขณะนี้ทั้งหมดอยู่ในโครงการขนาดใหญ่ แต่ฉันคิดว่าการเปลี่ยนไปใช้โครงการย่อยฉันสามารถพัฒนาโครงการใหม่สำหรับการใช้รหัสภายนอกใหม่ตรวจสอบให้แน่ใจว่าโครงการย่อยทำงานได้อย่างสมบูรณ์และผ่านการทดสอบและ จากนั้นสลับคลาส dependencies / factory ในโครงการผู้ใช้ อย่างไรก็ตามสิ่งนี้มีความซับซ้อนมากขึ้นโดยการใช้อินเทอร์เฟซที่ครอบคลุมทั่วทั้งโครงการขนาดใหญ่ ตัวอย่างเช่น

  • sub-project A - ประกอบด้วยอินเตอร์เฟส
  • sub-project B - ขึ้นอยู่กับ A สำหรับอินเตอร์เฟสและ jar ภายนอกเก่า
  • sub-project C - ขึ้นอยู่กับ B (และ A และขวดภายนอกเก่า) และมีคลาส Factory ที่ใช้อินเตอร์เฟสของ B

หากฉันต้องการเปลี่ยนไหภายนอกของ B ฉันสามารถ:

  • สร้างโครงการย่อย B_ii - อีกครั้งขึ้นอยู่กับ A และตอนนี้ jar ภายนอกใหม่
  • เมื่อทำงานได้อย่างสมบูรณ์ฉันสามารถเพิ่มการพึ่งพาของ C เป็น B_ii และเปลี่ยนคลาสของโรงงานให้ใช้อินเทอร์เฟซการปรับใช้ใหม่
  • เมื่อใช้งานได้ทั้งหมดฉันสามารถลบการอ้างอิงของ C ไปเป็นต้นฉบับ B และหากต้องการให้ลบโครงการย่อย B

  • นั่นเป็นวิธีที่สมเหตุสมผลในเรื่องนี้หรือไม่?

ดังนั้นโดยทั่วไปคำถามของฉันคือ:

  • ใครบ้างมีประสบการณ์ในการแตกโครงการขนาดใหญ่หรือไม่? มีเคล็ดลับ / กลอุบายที่คุณต้องการแบ่งปันหรือไม่?
  • สิ่งนี้มีผลกระทบต่อการพัฒนาและเวลาสร้างของคุณอย่างไร
  • คุณสามารถให้คำแนะนำเกี่ยวกับการจัดโครงสร้างของโครงการดังกล่าวได้อย่างไร

โปรดทราบว่าคุณสามารถสร้างโครงการหลักที่มี A, B และ C แยกออกจากกันติดกัน สิ่งนี้ช่วยให้เช่น IntelliJ มีหน่วยความจำทั้งสามในเวลาเดียวกันและทำการปรับโครงสร้างข้ามขอบเขตของโมดูล
Thorbjørn Ravn Andersen

คำตอบ:


10

ฉันจะตัดอย่างรวดเร็วก่อนนี้ (ยอดเยี่ยม BTW!):

การวางโครงสร้างในโครงการขนาดใหญ่ (เช่นเป็นโครงการย่อยขนาดเล็ก) จะทำให้คอมไพเลอร์ช้าลงหรือไม่

ไม่เพียงพอที่มันสำคัญค่าใช้จ่ายจริงใน Maven invocations

นอกจากนี้ฉันมีข้อกังวลเล็กน้อยเกี่ยวกับผลกระทบที่อาจเกิดขึ้นกับการแก้ไขเวลาใน IDEs (เราใช้ Intellij เป็นหลัก) Intellij ดูเหมือนว่าจะสร้างแต่ละโครงการผ่านแผนผังการพึ่งพา - เช่นถ้า C ขึ้นอยู่กับ B ขึ้นอยู่กับ A และฉันเปลี่ยน A มันจะไม่พยายามสร้าง B ยกเว้นการคอมไพล์และอื่น ๆ อาจเป็นข้อได้เปรียบ แต่ฉันพบว่าถ้า - ตัวอย่างเช่นฉันเปลี่ยนอินเทอร์เฟซใน A ที่ใช้กันอย่างแพร่หลายใน B และ C มันต้องใช้เวลาพอสมควรในการแก้ไขข้อผิดพลาดทั้งหมดจากการเปลี่ยนแปลงนั้น ...

IDEs ที่แตกต่างกันมีจุดแข็งที่แตกต่างกันโดยขึ้นอยู่กับการผูก Maven และการจัดการการพึ่งพา สถานะการเล่นในปัจจุบันดูเหมือนว่าส่วนใหญ่จะใช้งานได้กับ Eclipse ล่าสุด, Netbeans และ IntelliJ เท่านั้น - แต่คุณจะต้องสอนนักพัฒนาของคุณเกี่ยวกับปัญหาที่เกิดขึ้นสองครั้งในกรณี "Refresh source files จากดิสก์และสร้างโครงการ maven ที่เกี่ยวข้องทั้งหมด"

ฉันพบว่าฉันต้องทำอย่างนั้นวันนี้น้อยลง การมีไดรฟ์ SSD สร้างความแตกต่างอย่างมากที่นี่ BTW

ตัดคลาสย่อหน้าของโรงงาน

การจัดการการพึ่งพาเป็นสิ่งสำคัญอย่างยิ่งโดยไม่คำนึงว่าจะใช้เทคโนโลยีใด (Maven / Ivy / อะไรก็ตาม) เพื่อช่วยให้คุณสามารถนำไปใช้งานได้

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

การอัพเกรด JAR ภายนอกควรทำเป็น mini-project ที่เหมาะสมเสมอ ประเมินสาเหตุที่คุณกำลังอัพเกรดแก้ไขซอร์สโค้ดเพื่อใช้ประโยชน์จากฟีเจอร์ใหม่ / การแก้ไขข้อผิดพลาดอื่น ๆ เพียงแค่ชนรุ่นที่ไม่มีการวิเคราะห์นี้และการทำงานจะทำให้คุณเดือดร้อน

ดังนั้นโดยทั่วไปคำถามของฉันคือ:

ใครบ้างมีประสบการณ์ในการแตกโครงการขนาดใหญ่หรือไม่? มีเคล็ดลับ / เทคนิคที่คุณต้องการแบ่งปันหรือไม่?

  • การเชื่อมต่อและการพึ่งพาการพึ่งพาเป็นเพื่อนของคุณ
  • หนังสือของ Michael Feather เกี่ยวกับการจัดการกับรหัสมรดกอย่างมีประสิทธิภาพเป็นสิ่งที่ต้องอ่าน
  • การทดสอบการรวมเป็นเพื่อนของคุณ
  • การแยกโครงการย่อยเป็น foo-api (ส่วนต่อประสานเท่านั้น!) และ foo-core และการมีโมดูลขึ้นอยู่กับ foo-api เท่านั้นช่วยได้มากและบังคับใช้การแยก
  • โมดูล Jboss และ / หรือ OSGi สามารถช่วยบังคับใช้การแยกแบบสะอาดได้

สิ่งนี้มีผลกระทบต่อการพัฒนาและเวลาสร้างของคุณอย่างไร

ส่งผลกระทบน้อยมากต่อการพัฒนาและสร้างครั้ง - กำไรมหาศาลในเวลาสำหรับการจัดส่งโดยรวมที่ต่อเนื่องของเรา

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

ทำสิ่งเล็ก ๆ น้อย ๆ ให้ถูกต้องและสิ่งที่ยิ่งใหญ่มักจะตกลงมาอย่างหมดจดในภายหลัง ดังนั้นแยกสิ่งต่าง ๆ ทีละเล็กทีละน้อย - อย่าทำการปรับโครงสร้างขนาดใหญ่ของล็อตทั้งหมดเว้นแต่ว่าคุณจะได้รับความครอบคลุมในระดับสูงด้วยการทดสอบการรวมระบบของคุณ

เขียนการทดสอบการรวมก่อนการแยก - คุณควรได้รับผลลัพธ์มากขึ้นหรือน้อยลงหลังจากการแยก

วาดไดอะแกรมของโมดูลที่คุณมีอยู่ตอนนี้และที่ที่คุณต้องการไป ออกแบบขั้นตอนกลาง

อย่ายอมแพ้ - โกนหนวดของจามรีบางตัวสร้างรากฐานสำหรับความสามารถในการ "สร้างและปรับโครงสร้างอย่างรวดเร็วโดยไม่ต้องกลัว" ปลั๊กไร้ยางอาย -> จากเบ็นและฉันเป็นผู้พัฒนา Java ที่มีเหตุผลดี

ขอให้โชคดี!


0

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

  • เมื่อสิ่งประดิษฐ์แตกต่างกัน (เช่นอย่าสร้าง EAR, WAR, JAR, Integration-testing-jar ในโครงการเดียวกัน)
  • เมื่อในระหว่างการแยกคุณสังเกตเห็นว่าบางรหัสจำเป็นต้องมีอยู่ในสิ่งประดิษฐ์มากกว่าหนึ่งสิ่ง refactor พวกเขาเป็นใหม่
  • เมื่อมีโครงการอื่นนอกทีมของคุณต้องการใช้สิ่งที่คุณมีในโครงการ

เหตุผลหนึ่งคือนักพัฒนาต้องจัดการกับหลายโครงการและพยายามที่จะคิดออกว่าสิ่งที่แพคเกจ Java เป็นสิ่งที่มันควรเป็นโครงการ ฉันอยู่ในโครงการที่มันกลายเป็นโลหิตจางและมีโครงการที่เพิ่งมีสี่คลาสที่ใช้ฟังก์ชันเดียวเพราะนั่นคือทิศทางสถาปัตยกรรม สิ่งนี้ก็ย้อนกลับไปก่อนที่ Maven จะได้รับความนิยมดังนั้นเส้นทางของชั้นเรียนและสิ่งที่ไม่จำเป็นต้องตั้งค่าบนทั้ง IDE และสคริปต์ Ant

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

การปรับโครงสร้างใหม่นั้นง่ายกว่าภายในโครงการแทนที่จะข้ามโครงการ

หากเวลาในการสร้างเป็นปัญหากรุณาให้ฮาร์ดแวร์ที่ดีกว่า

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