วิธีแก้ปัญหาการพึ่งพาแพ็คเกจแบบวงกลม


11

ฉันกำลังปรับเปลี่ยน codebase ขนาดใหญ่ที่ชั้นเรียนส่วนใหญ่อยู่ในแพ็คเกจเดียว เพื่อความเป็นโมดูลที่ดีกว่าฉันกำลังสร้างแพ็คเกจย่อยสำหรับแต่ละฟังก์ชั่น

ผมจำได้ว่าการเรียนรู้บางที่กราฟพึ่งพาแพคเกจไม่ควรมีลูป แต่ผมไม่ทราบว่าวิธีการแก้ปัญหาต่อไปนี้: Figureอยู่ในแพคเกจfigure, Layoutอยู่ในแพคเกจlayout, Layoutต้องคิดรูปแบบในการดำเนินการเพื่อให้แพคเกจขึ้นอยู่กับแพคเกจlayout figureแต่ในทางกลับกัน, Figureสามารถมีอื่น ๆ ที่Figureอยู่ข้างในมันมีของตัวเองLayoutซึ่งจะทำให้การจัดแพคเกจขึ้นอยู่กับแพคเกจfigurelayout

ฉันมีวิธีแก้ปัญหาบางอย่างเช่นการสร้างContainerอินเทอร์เฟซที่Figureใช้และวางไว้ในLayoutแพ็คเกจ นี่เป็นทางออกที่ดีใช่ไหม ความเป็นไปได้อื่น ๆ

ขอบคุณ


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

@lorus ดังนั้นนี่ไม่ใช่ปัญหาการออกแบบหรือไม่?
vainolo

2
ไม่มันไม่ใช่. โดยปกติแล้วแพ็คเกจเป็นเพียงเนมสเปซซึ่งอาจมีการเปลี่ยนแปลงเฉพาะเมื่อใช้เพื่อสิ่งอื่นเช่นเปลี่ยนการมองเห็นเนื้อหาในสภาพแวดล้อม OSGi อย่ารบกวนเป็นอย่างอื่น
lorus

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

คำตอบ:


9

คุณควรคิดถึงInversion of Control

คุณพื้นกำหนดอินเตอร์เฟซสำหรับคุณLayoutอยู่ที่ไหนสักแห่งซึ่งตั้งอยู่ใกล้ระดับรูปแบบของคุณในแพคเกจของตัวเองเพื่อให้คุณจะมีแพคเกจการดำเนินงานและแพคเกจอินเตอร์เฟซที่สาธารณะ - สำหรับการโทรเช่นมันLayoutable(ผมไม่ทราบว่าภาษาอังกฤษที่เหมาะสม) ตอนนี้ - เลย์เอาต์จะไม่ใช้อินเทอร์เฟซนั้นยกเว้นFigureคลาส ในทำนองเดียวกันคุณจะสร้างอินเทอร์เฟซสำหรับรูปที่เป็นDrawableตัวอย่าง

ดังนั้น

my.public.package.Layoutable
my.implementation.package.Layout
my.public.package.Drawable
my.implementation.package.Figure

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

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

นั่นคือความคิดคร่าวๆ

แหล่งข้อมูลที่ยอดเยี่ยมสำหรับการแก้ปัญหานี้คือหนังสือJava Application Architectureโดย Kirk Knoernschild


สิ่งนี้ไม่เหมือนกับContainerอินเทอร์เฟซตามที่แนะนำในคำถามหรือไม่
vaughandroid

ใช่ - และไม่ - ฉันจะไม่ใส่ทั้งสองอย่างไว้ในแพ็คเกจเดียวกับที่ฉันระบุ และมีทฤษฎีไม่มากนักที่อยู่เบื้องหลัง และในกรณีนี้มันไม่เพียงพอที่จะทำด้านใดด้านหนึ่งคุณจะต้องทำมันทั้งสองด้าน Alright?
michael_s

โอ๊ะฉันพลาดบิตในคำถามเดิมเกี่ยวกับการไปในแพคเกจเดียวกับContainer Layoutไม่สามารถใช้งานได้ในขณะที่วิธีการแก้ปัญหาของคุณจะ
vaughandroid

อา - โอเค - ฉันดูเหมือนจะพลาดส่วนหนึ่งของคอนเทนเนอร์แม้ว่าเมื่อฉันกำลังแฮ็ค - ควรตั้งชื่อว่า Container;)
michael_s

0

ฉันไม่ชัดเจนเกินไปเกี่ยวกับสิ่งที่Figureเป็น แต่บางทีมันควรจะอยู่ในแพคเกจเดียวกันกับLayout?

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

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

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