Bagaimana mengatasi dependensi paket melingkar

11

Saya refactoring basis kode besar di mana sebagian besar kelas berada dalam satu paket. Untuk modularitas yang lebih baik, saya membuat sub paket untuk setiap fungsi.

Saya ingat belajar di suatu tempat bahwa grafik dependensi paket tidak boleh memiliki loop, tetapi saya tidak tahu bagaimana menyelesaikan masalah berikut: Figureada dalam paket figure, Layoutada dalam paket layout, Layoutmembutuhkan gambar untuk melakukan tata letak, jadi paket layouttergantung pada paket figure. Tetapi di sisi lain, a Figuredapat berisi Figures lain di dalamnya, memiliki sendiri Layout, yang membuat paket figuretergantung pada paket layout.

Saya memiliki beberapa solusi, seperti membuat Containerantarmuka yang Figuremengimplementasikan dan memasukkannya ke dalam Layoutpaket. Apakah ini solusi yang baik? Ada kemungkinan lain?

Terima kasih

vainolo
sumber
Ini adalah modul (misalnya Stoples yang berbeda) tidak dapat memiliki dependensi melingkar. Paket BISA dan sering MEMILIKI depenensi melingkar, selama mereka milik modul yang sama.
Lorus
@lorus Jadi ini bukan masalah desain?
vainolo
2
Tidak, bukan. Paket biasanya hanya ruang nama. Ini dapat berubah hanya ketika mereka digunakan untuk sesuatu yang lain, misalnya untuk mengubah visibilitas konten mereka di lingkungan OSGi. Jangan repot-repot sebaliknya.
Lorus
1
Perhatikan bahwa banyak pihak berwenang mengutuk ketergantungan siklus, dan kadang-kadang dengan alasan yang baik, tetapi sebelum Anda membabi buta, Anda harus memastikan salah satu alasan itu benar-benar berlaku untuk Anda. Jika struktur paket tidak memberi Anda masalah, dan Anda tidak dapat, dengan hati nurani yang baik, melihat mengapa hal itu terjadi di masa depan, jangan mengubah sesuatu yang begitu mendasar hanya untuk memuaskan nilai-nilai arsitektur abstrak.
Kilian Foth

Jawaban:

9

Anda harus memikirkan Pembalikan Kontrol

Anda pada dasarnya mendefinisikan antarmuka untuk Anda Layoutyang terletak di suatu tempat dekat kelas Layout Anda dalam paket sendiri sehingga Anda akan memiliki paket implementasi dan paket antarmuka publik - misalnya menyebutnya Layoutable(saya tidak tahu apakah itu bahasa Inggris yang tepat). Sekarang - Layout tidak akan mengimplementasikan antarmuka itu kecuali Figurekelas. Demikian juga Anda akan membuat antarmuka untuk Gambar itu Drawablemisalnya.

Begitu

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

Sekarang - Gambar mengimplementasikan Layoutable dan dengan demikian dapat digunakan oleh Layout dan (saya belum yakin apakah itu yang Anda inginkan) - Layout mengimplementasikan Drawable dan dapat digambar dalam Gambar. Intinya adalah, bahwa kelas yang memperlihatkan beberapa layanan membuatnya tersedia oleh antarmuka (di sini: Layout dan Layoutable) - kelas yang ingin menggunakan layanan itu harus mengimplementasikan antarmuka.

Maka Anda akan memiliki sesuatu seperti objek pembuat yang mengikat keduanya. Jadi pencipta akan memiliki ketergantungan terhadap Layoutmaupun untuk Figure, tetapi Layoutdan Figuremereka sendiri akan mandiri.

Itu ide yang kasar.

Sumber yang sangat baik untuk solusi untuk masalah ini adalah buku Java Application Architecture oleh Kirk Knoernschild.

michael_s
sumber
Bukankah ini sama dengan Containerantarmuka seperti yang disarankan dalam pertanyaan?
vaughandroid
Ya - dan tidak - saya tidak akan menempatkan keduanya dalam paket yang sama seperti yang saya nyatakan. Dan tidak ada banyak teori di baliknya. Dan dalam hal ini tidak cukup untuk melakukannya di satu sisi, Anda harus melakukannya di kedua sisi. Baik?
michael_s
Ups, saya melewatkan sedikit pertanyaan awal tentang Containermasuk dalam paket yang sama Layout. Itu tidak akan berhasil, sedangkan solusi Anda akan berhasil.
vaughandroid
ah - ok - Saya sepertinya melewatkan bagian dengan Container meskipun ketika saya meretas - seharusnya menamainya Container;)
michael_s
0

Saya tidak terlalu jelas tentang apa Figureitu, tapi mungkin harus dalam paket yang sama Layout?

ContainerSolusi antarmuka yang Anda usulkan tidak akan berfungsi - kecuali jika Anda menempatkan Containerantarmuka dalam paket ke-3 maka Anda masih akan memiliki ketergantungan melingkar di antara kedua paket tersebut. Lihat jawaban michael_s untuk sesuatu yang akan bekerja.

Hal lain, seperti yang disebutkan orang lain - mungkin tidak akan pernah menjadi masalah. Anda hanya akan mengalami masalah di masa depan jika Figuredan Layoutingin berada di modul terpisah . Anda dapat menangani ini jika dan ketika itu menjadi perlu, tetapi mengingat bahwa kedua kelas tampaknya sangat terkait, ini tampaknya sangat tidak mungkin.

vaughandroid
sumber