Dairesel paket bağımlılıkları nasıl çözülür?


11

Sınıfların çoğu tek bir pakette bulunan büyük bir kod temeli refactoring. Daha iyi modülerlik için, her işlevsellik için alt paketler oluşturuyorum.

Bir yere bir paket bağımlılık grafiğinin döngüler olmaması gerektiğini öğrendiğimi hatırlıyorum, ancak aşağıdaki sorunun nasıl çözüleceğini bilmiyorum: Figurepakette figure, Layoutpakette layout, Layoutdüzenin gerçekleştirilmesi için figür gerekiyor, bu yüzden paket pakete layoutbağlı figure. Ancak öte yandan, a kendi içinde olan ve paketi pakete bağımlı kılan Figurediğer maddeleri içerebilir .FigureLayoutfigurelayout

Gerçi uygulayan bir Containerarayüz oluşturmak Figureve Layoutpakete koymak gibi bazı çözümlerim var . Bu iyi bir çözüm mü? Başka olasılıklar var mı?

Teşekkürler


Modüller (örn. Farklı Kavanozlar) dairesel bağımlılıklara sahip olamaz. Paketler aynı modüle ait oldukları sürece CAN ve genellikle dairesel bağımlılıklara sahip olabilirler.
lorus

@lorus Yani bu bir tasarım sorunu değil mi?
vainolo

2
Hayır öyle değil. Paketler normalde yalnızca bir ad alanıdır.Bu yalnızca başka bir şey için kullanıldıklarında değişebilir, örneğin OSGi ortamında içerik görünürlüğünü değiştirmek için. Aksi halde rahatsız etme.
lorus

1
Birçok otoritenin döngüsel bağımlılıkları kınadığını ve bazen iyi bir nedenden ötürü, ancak körü körüne refactor olmadan önce, bu nedenlerden birinin sizin için geçerli olduğundan emin olmalısınız. Paket yapısı size sorun çıkarmıyorsa ve iyi vicdanla, gelecekte neden olacağını göremezsiniz, sadece soyut mimari değerleri tatmin etmek için bu kadar temel bir şeyi değiştirmeyin.
Kilian Foth

Yanıtlar:


9

Kontrolün İnversiyonu hakkında düşünmelisiniz

Temel olarak sizin Layoutiçin bir uygulama paketi ve bir genel arabirim paketiniz olacak şekilde Layout sınıfınızın yakınında bir yerde bulunan bir arabirimi tanımlarsınız - örneğin onu çağırın Layoutable(bunun doğru İngilizce olup olmadığını bilmiyorum). Şimdi - Layout o arayüzü değil Figuresınıfı uygular . Aynı şekilde Drawable, örneğin Şekil için bir arayüz oluşturacaksınız .

Yani

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

Şimdi - Şekil Layoutable uygular ve böylece Layout tarafından kullanılabilir ve (henüz istediğin bu olup olmadığından emin değilim) - Layout Drawable'ı uygular ve bir Şekilde çizilebilir. Mesele şu ki, bazı hizmetleri ortaya çıkaran sınıf bir arabirim tarafından kullanılabilir duruma getirilir (burada: Layout ve Layoutable) - bu hizmeti kullanmak isteyen sınıf arabirimi uygulamak zorundadır.

Sonra, her ikisini de birbirine bağlayan bir yaratıcı nesne gibi bir şeye sahip olursunuz. Yaratıcısı için bir bağımlılık olurdu Yani Layoutyanı sıra Figure, ancak Layoutve Figurekendilerini bağımsız olacak.

Bu kaba bir fikir.

Bu sorunların çözümü için mükemmel bir kaynak Kirk Knoernschild'in Java Uygulama Mimarisi'dir .


Bu Container, soruda önerilen arayüzle aynı değil mi?
vaughandroid

Evet - ve hayır - ikisini de belirttiğim gibi aynı pakete koymam. Ve arkasında çok fazla teori yoktu. Ve bu durumda bir tarafı yapmak yeterli değildir, her iki tarafta da yapmanız gerekir. Peki?
michael_s

Hata, asıl sorudaki Containerile aynı pakete girme konusunda biraz özledim Layout. Bu işe yaramazken çözümünüz işe yaradı.
vaughandroid

ah - ok - Ben hack yaparken ben Konteyner ile kısmı kaçırmış gibi görünüyordu - bunu Konteyner olmalı;)
michael_s

0

A'nın ne Figureolduğu konusunda çok net değilim , ama belki de aynı pakette olmalı Layout?

Önerilen Containerarabirim çözümünüz işe yaramaz - Containerarabirimi 3. bir pakete koymazsanız , iki paket arasında hala dairesel bir bağımlılığa sahip olursunuz. Çalışacak bir şey için michael_s'ın cevabına bakın .

Başka bir şey, diğerlerinin de belirttiği gibi - muhtemelen asla bir sorun olmayacaktır. Gelecekte sadece ayrı modüllerde olmak Figureve Layoutistiyorsanız, sorun yaşayacaksınız . Bu gerekli olduğunda ve ne zaman başa çıkabilirsiniz, ancak iki sınıfın oldukça yakından ilişkili olduğu göz önüne alındığında, bu oldukça olası görünmemektedir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.