Java projelerinde paket adlandırma için hangi stratejiyi kullanıyorsunuz ve neden? [kapalı]


88

Bunu bir süre önce düşündüm ve dükkanım ilk gerçek Java web uygulamasını yaparken yakın zamanda yeniden ortaya çıktı.

Giriş olarak, iki ana paket adlandırma stratejisi görüyorum. (Açık olmak gerekirse, bunun tüm 'domain.company.project' kısmına atıfta bulunmuyorum, bunun altındaki paket kuralından bahsediyorum.) Her neyse, gördüğüm paket adlandırma kuralları aşağıdaki gibidir:

  1. İşlevsel: Paketlerinizi iş alanına göre kimliğinden çok işlevlerine göre mimari olarak adlandırmak. Bunun için başka bir terim de 'katman'a göre isimlendirme olabilir. Yani, bir * .ui paketiniz ve bir * .domain paketiniz ve bir * .orm paketiniz olur. Paketleriniz dikey değil yatay dilimlerdir.

    Bu, mantıksal isimlendirmeden çok daha yaygındır. Aslında, bunu yapan bir proje gördüğüme veya duyduğuma inanmıyorum. Bu tabii ki beni temkinli kılıyor (bir NP problemine bir çözüm bulduğunuzu düşünmek gibi), çünkü çok zeki değilim ve herkesin bu şekilde yapmak için harika nedenleri olduğunu varsayıyorum. Öte yandan, odadaki fili kaçıran insanlara karşı değilim ve bu şekilde paket adlandırma yapmak için gerçek bir tartışma duymadım . Sadece fiili standart gibi görünüyor.

  2. Mantıksal: Paketlerinizi ticari etki alanı kimliklerine göre adlandırmak ve bu dikey işlevsellik dilimiyle ilgili her sınıfı bu pakete koymak.

    Daha önce de bahsettiğim gibi, bunu hiç görmedim veya duymadım, ama bana çok mantıklı geliyor.

    1. Sistemlere yatay yerine dikey olarak yaklaşma eğilimindeyim. Veri erişim katmanını değil, Sipariş İşleme sistemini girmek ve geliştirmek istiyorum. Açıkçası, o sistemin geliştirilmesinde veri erişim katmanına dokunmamın iyi bir şansı var, ama asıl mesele şu ki, ben onu o şekilde düşünmüyorum. Bunun anlamı, elbette, bir değişiklik emri aldığımda veya yeni bir özellik uygulamak istediğimde, ilgili tüm sınıfları bulmak için bir sürü paket içinde balık tutmaya gitmek zorunda kalmamak güzel olurdu. Bunun yerine, X paketine bakıyorum çünkü yaptığım şeyin X ile ilgisi var.

    2. Geliştirme açısından, paketlerinizin mimariniz yerine iş alanınızı belgelemesini büyük bir kazanç olarak görüyorum. Etki alanının, neredeyse her zaman, sistemin mimarisi, özellikle bu noktada, uygulamada neredeyse sıradan hale geldiği için, sistemin daha zor olan parçası olduğunu düşünüyorum. Bu tür bir adlandırma kuralına sahip bir sisteme gelebilmem ve paketlerin isimlendirilmesinden anında bunun siparişlerle, müşterilerle, işletmelerle, ürünlerle vb. İlgilendiğini biliyor olmam oldukça kullanışlı görünüyor.

    3. Görünüşe göre bu, Java'nın erişim değiştiricilerinden çok daha iyi yararlanmanıza izin verecek. Bu, arayüzleri sistemin katmanları yerine alt sistemlere çok daha temiz bir şekilde tanımlamanıza olanak tanır. Dolayısıyla, şeffaf bir şekilde kalıcı olmasını istediğiniz bir sipariş alt sisteminiz varsa, teo katmanında kalıcılık sınıflarına genel arayüzler oluşturmak zorunda kalmayarak ve bunun yerine dao sınıfını paketleyerek, teorik olarak bunun kalıcı olduğunu hiçbir şeyin bilmesine asla izin veremezsiniz. sadece ilgilendiği sınıflarla. Açıkçası, eğer bu işlevselliği ifşa etmek istediği, bunun için bir arayüz sağlamak veya kamu yapabiliriz. Sisteminizin özelliklerinin dikey bir diliminin birden çok pakete bölünmesiyle bunun çoğunu kaybediyorsunuz gibi görünüyor.

    4. Sanırım görebildiğim bir dezavantaj, katmanları biraz daha zorlaştırması. Bir paketi silmek veya yeniden adlandırmak ve ardından alternatif bir teknoloji ile yerine yenisini bırakmak yerine, içeri girip tüm paketlerdeki tüm sınıfları değiştirmeniz gerekir. Ancak, bunun önemli bir şey olduğunu görmüyorum. Tecrübe eksikliğinden kaynaklanıyor olabilir, ancak teknolojilerinizi değiştirdiğiniz zamanların, girdiğiniz ve sisteminizdeki dikey özellik dilimlerini düzenlediğiniz sürelere kıyasla soluklaştığını hayal etmeliyim.

Öyleyse sanırım soru size sorulacak, paketlerinizi nasıl adlandırıyorsunuz ve neden? Lütfen burada altın kaz ya da başka bir şeye rastladığımı düşünmediğimi anlayın. Tüm bunlarda oldukça yeniyim ve çoğunlukla akademik deneyimim var. Ancak, muhakememdeki boşlukları göremiyorum, bu yüzden hepinizin görebileceğini umuyorum, böylece devam edebilirim.


Şimdiye kadar duyduğum şeyler bunun bir tür yargılama çağrısı olduğunu gösteriyor. Bununla birlikte, çoğu cevap pratik hususlara odaklanmadı. Daha çok aradığım şey bu. Yine de şimdiye kadarki yardım için teşekkürler!
Tim Visher

Bunun bir yargılama çağrısı olduğunu sanmıyorum. Önce katmana, sonra işlevselliğe göre bölmek kesinlikle doğru yoldur. Cevabımı güncelliyorum.
eljenso

@eljenso: bunu Eclipse adamlarına söyleyin :) Tutulmada ilk bölüm, dağıtım birimleri ve aynı zamanda işlevsellik olan "özellikler" dir. "Özellik" içinde, genellikle katmanlara bölünmüş "eklentiler" vardır - ancak aynı "özellik" içindeki eklentiler her zaman birlikte dağıtılmalıdır. Yalnızca tek bir dağıtım biriminiz varsa, o zaman önce katmana ve yalnızca o zaman işlevselliğe göre bölmek mantıklı olabilir. Birden çok dağıtım birimiyle, yalnızca sunum katmanını dağıtmak istemezsiniz - ek işlevsellik istersiniz.
Peter Štibraný

Bir uygulamanın iş katmanıyla ilgili özel bir sorum var, adlandırma kuralı ne olmalıdır?
Bionix1441

Yanıtlar:


32

Paket tasarımı için önce katmana, sonra başka bir işlevselliğe bölüyorum.

Bazı ek kurallar var:

  1. katmanlar en genelden (alt) en özele (üst) doğru yığınlanır
  2. her katmanın ortak bir arayüzü vardır (soyutlama)
  3. bir katman yalnızca başka bir katmanın genel arayüzüne bağlı olabilir (kapsülleme)
  4. bir katman yalnızca daha genel katmanlara bağlı olabilir (yukarıdan aşağıya bağımlılıklar)
  5. bir katman tercihen doğrudan altındaki katmana bağlıdır

Dolayısıyla, örneğin bir web uygulaması için, uygulama katmanınızda (yukarıdan aşağıya) aşağıdaki katmanlara sahip olabilirsiniz:

  • sunum katmanı: müşteri katmanında gösterilecek kullanıcı arayüzünü oluşturur
  • uygulama katmanı: bir uygulamaya özel, durum bilgisi olan mantığı içerir
  • hizmet katmanı: işlevselliği etki alanına göre gruplandırır, durum bilgisiz
  • entegrasyon katmanı: arka uç katmanına erişim sağlar (db, jms, e-posta, ...)

Ortaya çıkan paket düzeni için, bazı ek kurallar şunlardır:

  • her paket adının kökü <prefix.company>.<appname>.<layer>
  • bir katmanın arayüzü işlevselliğe göre daha da bölünmüştür: <root>.<logic>
  • bir katmanın özel uygulamasının önüne özel: <root>.private

İşte örnek bir düzen.

Sunum katmanı, görünüm teknolojisine ve isteğe bağlı olarak (gruplara) göre bölünmüştür.

com.company.appname.presentation.internal
com.company.appname.presentation.springmvc.product
com.company.appname.presentation.servlet
...

Uygulama katmanı, kullanım durumlarına bölünmüştür.

com.company.appname.application.lookupproduct
com.company.appname.application.internal.lookupproduct
com.company.appname.application.editclient
com.company.appname.application.internal.editclient
...

Hizmet katmanı, arka uç katmanındaki etki alanı mantığından etkilenen iş etki alanlarına bölünmüştür.

com.company.appname.service.clientservice
com.company.appname.service.internal.jmsclientservice
com.company.appname.service.internal.xmlclientservice
com.company.appname.service.productservice
...

Entegrasyon katmanı 'teknolojilere' ve erişim nesnelerine bölünmüştür.

com.company.appname.integration.jmsgateway
com.company.appname.integration.internal.mqjmsgateway
com.company.appname.integration.productdao
com.company.appname.integration.internal.dbproductdao
com.company.appname.integration.internal.mockproductdao
...

Paketleri bu şekilde ayırmanın avantajları, karmaşıklığı yönetmenin daha kolay olması ve test edilebilirliği ve yeniden kullanılabilirliği artırmasıdır. Çok fazla yük gibi görünse de, deneyimlerime göre aslında çok doğal geliyor ve bu yapı (veya benzeri) üzerinde çalışan herkes bunu birkaç gün içinde alıyor.

Dikey yaklaşımın neden o kadar iyi olmadığını düşünüyorum?

Katmanlı modelde, birkaç farklı üst düzey modül aynı alt düzey modülü kullanabilir. Örneğin: aynı uygulama için birden çok görünüm oluşturabilirsiniz, birden çok uygulama aynı hizmeti kullanabilir, birden çok hizmet aynı ağ geçidini kullanabilir. Buradaki hile, katmanlar arasında hareket ederken, işlevsellik seviyesinin değişmesidir. Daha spesifik katmanlardaki modüller, daha genel katmandaki modüllerle 1-1 eşleşmez, çünkü ifade ettikleri işlevsellik seviyeleri 1-1 ile eşleşmez.

Paket tasarımı için dikey yaklaşımı kullandığınızda, yani önce işlevselliğe göre böldüğünüzde, farklı işlevsellik seviyelerine sahip tüm yapı taşlarını aynı 'işlevsellik ceketi'ne zorlarsınız . Genel modüllerinizi daha spesifik olan için tasarlayabilirsiniz. Ancak bu, daha genel katmanın daha spesifik katmanları bilmemesi gerektiği şeklindeki önemli ilkeyi ihlal eder. Örneğin hizmet katmanı, uygulama katmanındaki kavramlardan sonra modellenmemelidir.


"Paketleri bu şekilde ayırmanın avantajları, karmaşıklığı yönetmenin daha kolay olması ve test edilebilirliği ve yeniden kullanılabilirliği artırmasıdır." Bunun neden böyle olduğuna gerçekten girmiyorsunuz.
mangoDrunk

1
Neden böyle olmadığına girmiyorsunuz . Ama her neyse ... örgütleme kuralları oldukça açık ve anlaşılırdır, bu nedenle karmaşıklığı azaltır. Kuruluşun kendisi nedeniyle daha test edilebilir ve yeniden kullanılabilir. Herkes deneyebilir ve daha sonra hemfikir olabilir veya katılmayabiliriz. Dikey yaklaşımın bazı dezavantajlarını kısaca açıklayarak, yatay yaklaşımın neden daha kolay olduğunu düşündüğümün nedenlerini örtük olarak açıklıyorum.
eljenso

8
Bu makale , katman bazında paket yerine özellik paket kullanmanın neden daha iyi olduğunu oldukça güzel bir şekilde açıklıyor .
Tom

@eljenso "Neden böyle olmadığına dair nedenlere girmiyorsunuz", ispat yükünü değiştirmeye mi çalışıyorsunuz? Tom'un gönderdiği makalenin neden tek tek paketin daha iyi olduğunu çok güzel açıkladığını düşünüyorum ve "Bunun bir yargı çağrısı olduğunu düşünmüyorum. Önce katmana, sonra işlevselliğe göre bölmek kesinlikle yol cidden gitmek için.
pka

18

Kendimi Bob Amca'nın ambalaj tasarım ilkelerine bağlı buluyorum . Kısacası, birlikte yeniden kullanılacak ve birlikte değiştirilecek sınıflar (aynı nedenle, örneğin bir bağımlılık değişikliği veya bir çerçeve değişikliği) aynı pakete konulmalıdır. IMO, işlevsel dökümün bu hedeflere ulaşma şansı çoğu uygulamadaki dikey / işletmeye özel çöküşten daha fazla olacaktır.

Örneğin, etki alanı nesnelerinin yatay bir dilimi farklı türde ön uçlar veya hatta uygulamalar tarafından yeniden kullanılabilir ve temel web çerçevesinin değiştirilmesi gerektiğinde web ön ucunun yatay bir diliminin birlikte değişmesi muhtemeldir. Öte yandan, farklı işlevsel alanlardaki sınıflar bu paketlerde gruplandırılırsa, bu değişikliklerin birçok paketteki dalgalanma etkisini hayal etmek kolaydır.

Açıktır ki, her tür yazılım aynı değildir ve belirli projelerde dikey döküm (yeniden kullanılabilirlik ve değişime yakınlık hedeflerine ulaşılması açısından) anlamlı olabilir.


Teşekkürler, bu çok açık.Soruda söylediğim gibi, teknolojileri değiş tokuş etme sayınızın, dikey işlevsellik dilimlerinde kaydıracağınızdan çok daha az olduğunu hissediyorum. Bu senin tecrüben değil mi?
Tim Visher

Bu sadece teknolojilerle ilgili değil. Orijinal gönderinizin 1. noktası, yalnızca dikey dilimler birbirleriyle bazı arayüzler aracılığıyla iletişim kuran bağımsız uygulamalar / hizmetler ise anlamlıdır (dilerseniz SOA). daha fazlası aşağıda ...
Buu Nguyen

Şimdi, kendi kullanıcı arayüzüne / işine / verilerine sahip olan bu ayrıntılı uygulamaların / hizmetlerin her birinin ayrıntılarına girerken, ister teknoloji, bağımlılık, kural / iş akışı, günlüğe kaydetme olsun, dikey bir dilimdeki değişiklikleri hayal edemiyorum. , güvenlik, UI stili, diğer dilimlerden tamamen izole edilebilir.
Buu Nguyen

Ben hakkında görüşlerinizi ilgi olacağını Cevabıma
i3ensays

@BuuNguyen Paket tasarım ilkelerine olan bağlantı koptu.
johnnieb

5

Genellikle her iki bölüm seviyesi de mevcuttur. Yukarıdan dağıtım birimleri var. Bunlar 'mantıksal' olarak adlandırılır (sizin terimlerinize göre Eclipse özelliklerini düşünün). Dağıtım biriminin içinde, işlevsel paket bölümünüz vardır (Eclipse eklentilerini düşünün).

Örneğin, bir özelliktir com.featureve bu oluşur com.feature.client, com.feature.coreve com.feature.uieklentileri. Eklentiler içinde, diğer paketlere çok az bölünmem var, ancak bu da sıra dışı değil.

Güncelleme: Btw, Juergen Hoeller tarafından InfoQ'da kod organizasyonu hakkında harika bir konuşma var: http://www.infoq.com/presentations/code-organization-large-projects . Juergen, Bahar'ın mimarlarından biridir ve bu konuda çok şey biliyor.


Tam olarak takip etmiyorum. Genellikle com.apache.wicket.x'i görebilirsiniz, burada x işlevsel veya mantıksaldır. Genellikle com.x'i görmüyorum. Sanırım bir com.company.project.feature.layer yapısıyla gideceğinizi söylüyorsunuz? Nedenleriniz var mı
Tim Visher

Nedeni, "com.company.project.feature" dağıtım birimidir. Bu seviyede, bazı özellikler isteğe bağlıdır ve atlanabilir (yani konuşlandırılamaz). Bununla birlikte, özellik içi şeyler isteğe bağlı değildir ve genellikle hepsini istersiniz. Burada katmanlara bölmek daha mantıklı.
Peter Štibraný

4

Üzerinde çalıştığım çoğu java projesi java paketlerini önce işlevsel, sonra mantıksal olarak dilimleyin.

Genellikle parçalar yeterince büyüktür ki, temel işlevleri bir kavanoza, apileri diğerine, web ön uç öğelerini bir savaş dosyasına vb. Koyabileceğiniz ayrı yapı yapılarına bölünürler.


Bu neye benzeyebilir? domain.company.project.function.logicalSlice?
Tim Visher

hemen hemen! egdcpweb.profiles, dcpweb.registration, dcpapis, dcppersistence vb. genellikle oldukça iyi çalışır, kilometreniz değişebilir. aynı zamanda etki alanı modellemesi kullanıp kullanmadığınıza da bağlıdır - birden fazla etki alanınız varsa, önce etki alanına göre bölmek isteyebilirsiniz.
Ben Hardy

Ben şahsen bunun tersini tercih ediyorum, mantıklı, sonra işlevsel. apple.rpc, apple.model ve ardından banana.model, banana.store
mP.

Tüm elma öğelerini bir arada gruplayabilmenin, tüm web öğelerini bir arada gruplandırmaktan daha fazla değeri vardır.
mP.

3

Paketler bir birim olarak derlenecek ve dağıtılacaktır. Bir pakette hangi sınıfların ait olduğu düşünüldüğünde, kilit kriterlerden biri bağımlılıklarıdır. Bu sınıf başka hangi paketlere (üçüncü taraf kitaplıkları dahil) bağlıdır. İyi organize edilmiş bir sistem, benzer bağımlılıklara sahip sınıfları bir pakette kümelendirecektir. Bu, bir kitaplıktaki bir değişikliğin etkisini sınırlar çünkü yalnızca birkaç iyi tanımlanmış paket buna bağlı olacaktır.

Mantıksal, dikey sisteminiz çoğu pakette bağımlılıkları "lekeleme" eğiliminde olabilir. Diğer bir deyişle, her özellik dikey bir dilim olarak paketlenmişse, her paket kullandığınız her üçüncü taraf kitaplığına bağlı olacaktır. Bir kitaplıkta yapılan herhangi bir değişiklik, muhtemelen tüm sisteminizde dalgalanma yaratacaktır.


Ah. Yani, yatay dilimler yapmanın yaptığı bir şey, sizi kullandığınız kitaplıklardaki gerçek yükseltmelerden korumaktır. Dikey dilimlerin, sisteminizin her pakette sahip olduğu her bağımlılığı lekelediğinde haklısınız. Bu niye bu kadar büyük bir mesele?
Tim Visher

Bir "özellik" için o kadar da önemli değil. Daha değişken olma eğilimindedirler ve yine de daha fazla bağımlılığa sahiptirler. Öte yandan, bu "müşteri" kodu düşük yeniden kullanılabilirliğe sahip olma eğilimindedir. Yeniden kullanılabilir bir kitaplık olmayı amaçladığınız bir şey için, müşterileri her küçük değişiklikten ayırmak harika bir yatırımdır.
erickson

3

Ben kişisel olarak sınıfları mantıksal olarak gruplamayı tercih ederim, daha sonra bunun içinde her işlevsel katılım için bir alt paket içerir.

Ambalajın hedefleri

Sonuçta paketler, bir şeyleri bir araya getirmekle ilgilidir - ilgili sınıflar birbirine yakın yaşarlar. Aynı pakette yaşıyorlarsa, görünürlüğü sınırlandırmak için özel paketten yararlanabilirler. Sorun, tüm görüşünüzü ve azminizi tek bir pakette toplamak, birçok sınıfın tek bir pakette karıştırılmasına yol açabilir. Bir sonraki mantıklı şey, bu nedenle görünüm oluşturmak, süreklilik oluşturmak, alt paketleri ve buna göre yeniden düzenleme sınıflarını kullanmaktır. Ne yazık ki korumalı ve paket özel kapsam belirleme, mevcut paket ve alt paket konseptini desteklemiyor çünkü bu, bu tür görünürlük kurallarının uygulanmasına yardımcı olacaktır.

Şimdi işlevsellik yoluyla ayırmada değer görüyorum çünkü görünümle ilgili tüm şeyleri gruplamak için hangi değer var. Bu adlandırma stratejisindeki şeyler, görünümdeki bazı sınıflarla bağlantısız hale gelirken diğerleri ısrarla vb.

Mantıksal paketleme yapıma bir örnek

Örnekleme amacıyla iki modülü adlandıralım - ad modülünü, sınıfları bir paket ağacının belirli bir dalı altında gruplayan bir kavram olarak kullanalım.

apple.model apple.store banana.model banana.store

Avantajlar

Banana.store.BananaStore'u kullanan bir istemci, yalnızca kullanılabilir hale getirmek istediğimiz işlevselliğe maruz kalır. Hazırda bekletme sürümü, depolama işlemlerine dağınıklık ekledikçe farkında olmaları ve bu sınıfları görmeleri gerekmeyen bir uygulama ayrıntısıdır.

Diğer Mantıksal v İşlevsel avantajlar

Köke doğru ne kadar yukarı çıkarsa, kapsam o kadar geniş olur ve bir pakete ait şeyler, kendi modüllerine ait olan şeylere giderek daha fazla bağımlılık sergilemeye başlar. Örneğin, "muz" modülü incelenecek olsaydı, bağımlılıkların çoğu bu modül ile sınırlı olacaktır. Aslında "muz" altındaki çoğu yardımcıya bu paket kapsamı dışında hiç atıfta bulunulmayacaktır.

Neden işlevsellik?

İşlevselliğe dayalı olarak bir şeyleri bir araya getirerek elde edilen değer nedir? Böyle bir durumda çoğu sınıf, paket özel yöntemlerden veya sınıflardan yararlanmaya çok az ihtiyaç duyarak veya hiç yararlanmadan birbirinden bağımsızdır. Bunları kendi alt paketlerinde yeniden düzenlemek çok az kazanç sağlar ancak karmaşayı azaltmaya yardımcı olur.

Sistemde geliştirici değişiklikleri

Geliştiricilere önemsiz olmaktan biraz daha fazla değişiklik yapma görevi verildiğinde, potansiyel olarak paket ağacının tüm alanlarından dosyaları içeren değişikliklerin olması aptalca görünüyor. Mantıksal yapılandırılmış yaklaşımla, değişiklikleri paket ağacının aynı bölümünde daha yereldir ki bu doğru görünüyor.


"Geliştiriciler [...] paket ağacının tüm alanlarından dosyalar." Bunun aptalca göründüğünü söylerken haklısın. Bu doğru tabakaların noktası tam olarak Çünkü: değişiklikler yapma uygulamanın tüm yapı boyunca dalgalanma.
eljenso

Tavsiye için teşekkürler. Seni net olarak anladığımdan emin değilim. Mantıksal paketleri tartışmaya çalıştığınıza inanıyorum, nedenini tam olarak bilmiyorum. Cevabınızı biraz daha net, muhtemelen yeniden ifade etmeye çalışabilir misiniz? Teşekkürler!
Tim Visher

3

Paketlemeye yönelik hem işlevsel (mimari) hem de mantıksal (özellik) yaklaşımların bir yeri vardır. Birçok örnek uygulama (ders kitaplarında vb. Bulunanlar) sunum, iş hizmetleri, veri haritalama ve diğer mimari katmanları ayrı paketlere yerleştirmenin işlevsel yaklaşımını izler. Örnek uygulamalarda, her pakette genellikle yalnızca birkaç veya yalnızca bir sınıf bulunur.

Bu ilk yaklaşım iyidir, çünkü uydurulmuş bir örnek genellikle: 1) sunulan çerçevenin mimarisini kavramsal olarak haritalandırır, 2) tek bir mantıksal amaçla yapılır (örneğin, bir klinikten evcil hayvan ekleme / kaldırma / güncelleme / silme) . Sorun, birçok okuyucunun bunu sınır tanımayan bir standart olarak almasıdır.

Bir "iş" uygulaması, daha fazla özelliği içerecek şekilde genişledikçe, işlevsel yaklaşımı takip etmek bir yük haline gelir. Mimari katmana dayalı türleri nerede arayacağımı bilmeme rağmen (örneğin, bir "web" veya "ui" paketi altındaki web denetleyicileri, vb.), Tek bir mantıksal özellik geliştirmek birçok paket arasında gidip gelmeyi gerektirmeye başlar. Bu en azından külfetli, ama bundan daha kötü.

Mantıksal olarak ilgili türler birlikte paketlenmediğinden, API fazlasıyla duyurulur; mantıksal olarak ilişkili türler arasındaki etkileşim, türlerin içe aktarılabilmesi ve birbirleriyle etkileşime girebilmesi için 'genel' olmaya zorlanır (varsayılan / paket görünürlüğünü en aza indirme yeteneği kaybolur).

Bir çerçeve kitaplığı oluşturuyorsam, kesinlikle paketlerim işlevsel / mimari bir paketleme yaklaşımını izleyecektir. API tüketicilerim, içe aktarma ifadelerinin mimarinin adını taşıyan sezgisel paket içerdiğini bile takdir edebilirler.

Tersine, bir iş uygulaması oluştururken özelliğe göre paketleyeceğim. Widget, WidgetService ve WidgetController'ı aynı " com.myorg.widget. " Paketine yerleştirip ardından varsayılan görünürlüğün avantajından yararlanarak (ve paketler arası bağımlılıkların yanı sıra daha az içe aktarma ifadesine sahip olmak) sorun yaşamıyorum .

Bununla birlikte, çapraz durumlar vardır. WidgetService hizmetim birçok mantıksal etki alanı (özellikler) tarafından kullanılıyorsa, bir " com.myorg.common.service. " Paketi oluşturabilirim. Ayrıca, özelliklerde yeniden kullanılabilir olma ve " com.myorg.common.ui.helpers. " Ve " com.myorg.common.util. " Gibi paketler elde etme niyetiyle sınıflar oluşturmam da büyük bir şans . Hatta daha sonraki tüm bu "ortak" sınıfları ayrı bir projede taşıyabilir ve bunları bir myorg-commons.jar bağımlılığı olarak iş uygulamama dahil edebilirim.


2

Mantıksal süreçlerinizin ayrıntı düzeyine mi bağlı?

Bağımsızlarsa, genellikle yeni bir paket yerine kaynak kontrolünde onlar için yeni bir projeniz olur.

Şu anda üzerinde olduğum proje mantıksal bölünmeye doğru ilerliyor, jython yönü için bir paket var, bir kural motoru için bir paket, foo, bar, binglewozzle için paketler, vb. XML'e özgü ayrıştırıcılara sahip olmaya bakıyorum. / Yazarlar, bir XML paketine sahip olmak yerine (daha önce yaptığım) bu paketteki her modül için, ancak yine de paylaşılan mantığın gittiği bir çekirdek XML paketi olacak. Ancak bunun bir nedeni, genişletilebilir (eklentiler) olabilmesidir ve bu nedenle her eklentinin XML (veya veritabanı, vb.) Kodunu da tanımlaması gerekir, böylece bunu merkezileştirmek daha sonra sorunlara yol açabilir.

Sonunda, belirli bir proje için en mantıklı görünen şey gibi görünüyor. Bununla birlikte, tipik proje katmanlı diyagramı doğrultusunda paketlemenin kolay olduğunu düşünüyorum. Mantıksal ve işlevsel bir paketlemeyle sonuçlanacaksınız.

İhtiyaç duyulan şey etiketli ad alanlarıdır. Bazı Jython işlevleri için bir XML ayrıştırıcı, birini veya diğerini seçmek zorunda kalmadan hem Jython hem de XML olarak etiketlenebilir.

Ya da belki oynuyorum.


Demek istediğini tam olarak anlamıyorum. Sanırım, söylediğiniz, projeniz için en mantıklı olanı yapmanız gerektiğidir ve sizin için bu mantıklı ve biraz işlevsel olarak atılır. Bunun belirli pratik nedenleri var mı?
Tim Visher

Dediğim gibi, yerleşik işlevselliği artırmak için eklentilerim olacak. Bir eklentinin XML'ini ayrıştırıp (ve sonunda DB'ye) yazabilmesi ve ayrıca işlevsellik sağlaması gerekecektir. Bu nedenle com.xx.feature.xml veya com.xx.xml.feature'm var mı? İlki daha düzgün görünüyor.
JeeBee

2

Paket yapılarını öyle bir şekilde tasarlamaya çalışıyorum ki, bir bağımlılık grafiği çizersem, mümkün olduğunca az döngüsel referansla tutarlı bir modeli takip etmek ve kullanmak kolay olurdu.

Benim için bu, yataydan ziyade dikey bir adlandırma sisteminde bakımı ve görselleştirmesi çok daha kolay. component1.display, component2.dataaccess'e bir referansa sahipse, display.component1'in veri erişimine bir referansı olmasından daha fazla uyarı çanı atar. bileşen2.

Elbette, her ikisi tarafından paylaşılan bileşenler kendi paketlerinde yer alır.


Sizi anladığım kadarıyla, dikey adlandırma kuralını savunuyorsunuz. Birden fazla dilimde bir sınıfa ihtiyacınız olduğunda * .utils paketi bunun için olduğunu düşünüyorum.
Tim Visher

2

Mantıksal ("özelliğe göre") organizasyonu tamamen takip ediyor ve öneriyorum! Bir paket, "modül" kavramını olabildiğince yakından takip etmelidir. İşlevsel organizasyon, bir modülü bir projeye yayabilir, bu da daha az kapsülleme ile sonuçlanır ve uygulama ayrıntılarında değişikliklere yatkın hale gelebilir.

Örneğin bir Eclipse eklentisini ele alalım: Tüm görünümleri veya eylemleri tek bir pakete koymak karışıklık olur. Bunun yerine, bir özelliğin her bileşeni, özelliğin paketine gitmeli veya çok sayıda varsa, alt paketlere (özellikA işleyicileri, özellikA tercihleri ​​vb.)

Elbette sorun, her yerde ortaya çıksalar da, ortogonal endişelerin ele alınmasını imkansız veya en azından çok zor hale getiren hiyerarşik paket sisteminde (Java'nın sahip olduğu) yatıyor!


1

Kişisel olarak işlevsel adlandırma için giderdim. Kısa neden: kod tekrarını veya bağımlılık kabusunu önler.

Biraz detaylandırmama izin verin. Kendi paket ağacına sahip harici bir jar dosyası kullandığınızda ne olur? (Derlenmiş) kodu etkin bir şekilde projenize ve onunla birlikte (işlevsel olarak ayrılmış) bir paket ağacına aktarıyorsunuz. İki adlandırma kuralını aynı anda kullanmak mantıklı olur mu? Hayır, sizden saklanmadıkça. Ve eğer projeniz yeterince küçükse ve tek bir bileşeni varsa. Ancak birkaç mantıksal biriminiz varsa, veri dosyası yükleme modülünü, diyelim ki yeniden uygulamak istemezsiniz. Bunu mantıksal birimler arasında paylaşmak, mantıksal olarak ilgisiz birimler arasında yapay bağımlılıklara sahip olmamak ve bu paylaşılan aracı hangi birime koyacağınızı seçmek zorunda kalmamak istiyorsunuz.

Sanırım bu nedenle, belirli bir boyuta ulaşan veya ulaşması amaçlanan projelerde işlevsel adlandırma en çok kullanılır ve sınıf adlandırma kurallarında mantıksal adlandırma, belirli bir rolü takip etmek için, bir paketi.

Mantıksal adlandırma konusundaki puanlarınızın her birine daha kesin bir şekilde yanıt vermeye çalışacağım.

  1. Planlarınızda değişiklik olduğunda işlevsellikleri değiştirmek için eski sınıflarda balık tutmaya gitmeniz gerekiyorsa, bu kötü bir soyutlamanın işaretidir: tek bir kısa cümlede tanımlanabilen, iyi tanımlanmış bir işlevsellik sağlayan sınıflar oluşturmalısınız. Yalnızca birkaç üst düzey sınıf, tüm bunları iş zekanızı yansıtacak şekilde bir araya getirmelidir. Bu şekilde, daha fazla kodu yeniden kullanabilecek, daha kolay bakıma sahip olacak, daha net belgelere sahip olacak ve daha az bağımlılık sorunu yaşayacaksınız.

  2. Bu, esas olarak projenizi nasıl salladığınıza bağlıdır. Mantıksal ve işlevsel görüş kesinlikle ortogonaldir. Dolayısıyla, bir adlandırma kuralı kullanırsanız, bir sırayı korumak için diğerini sınıf adlarına uygulamanız veya bir adlandırma kuralından diğerine bir derinlikte çatal atmanız gerekir.

  3. Erişim değiştiriciler, işlemenizi anlayan diğer sınıfların sınıfınızın iç kısımlarına erişmesine izin vermenin iyi bir yoludur . Mantıksal ilişki, algoritmik veya eşzamanlılık kısıtlamalarının anlaşılması anlamına gelmez. İşlevsel olmasa da olabilir. Genel ve özel dışındaki erişim değiştiricilerden çok yoruldum, çünkü genellikle uygun mimari ve sınıf soyutlamasının eksikliğini gizliyorlar.

  4. Büyük, ticari projelerde, değişen teknolojiler sandığınızdan daha sık gerçekleşir. Örneğin, XML ayrıştırıcıyı 3 kez, 2 kez önbellekleme teknolojisini ve 2 kez coğrafi konumlandırma yazılımını değiştirmek zorunda kaldım. İyi ki, tüm cesur ayrıntıları özel bir pakette saklamıştım ...


1
Hatalıysam beni affet, ama bana daha çok birçok insan tarafından kullanılması amaçlanan bir çerçeve geliştirmekten bahsediyormuşsun gibi geliyor. Bence kurallar bu tür geliştirme ve gelişen son kullanıcı sistemleri arasında değişiyor. Yanlış mıyım?
Tim Visher

Dikey dilimlerin çoğu tarafından kullanılan ortak sınıflar için, utilspaket gibi bir şeye sahip olmanın mantıklı olduğunu düşünüyorum . Ardından, ihtiyacı olan herhangi bir sınıf bu pakete bağlı olabilir.
Tim Visher

Bir kez daha, boyut önemlidir: Bir proje yeterince büyüdüğünde, birkaç kişi tarafından desteklenmesi gerekir ve bir tür uzmanlaşma meydana gelir. Etkileşimi kolaylaştırmak ve hataları önlemek için, projeyi parçalara ayırmak hızla gerekli hale gelir. Ve gereçler paketi yakında devasa olacak!
Varkhan

1

Paketleri hiç kullanmamak ilginç bir deneydir (kök paket hariç.)

O zaman ortaya çıkan soru, paketleri tanıtmanın ne zaman ve neden mantıklı olduğudur. Muhtemelen cevap, projenin başında cevaplayacağınız cevaptan farklı olacaktır.

Sorunuzun ortaya çıktığını varsayıyorum, çünkü paketler kategoriler gibidir ve bazen birine veya diğerine karar vermek zordur. Bazen etiketler, bir sınıfın birçok bağlamda kullanılabilir olduğunu iletmek için daha fazla takdir edilecektir.


0

Tamamen pratik bir bakış açısından, java'nın görünürlük yapıları, aynı paketteki sınıfların yöntemlere ve özelliklere protectedve defaultgörünürlük ile erişmesine vepublic . Tamamen farklı bir kod katmanından halka açık olmayan yöntemleri kullanmak kesinlikle büyük bir kod kokusu olacaktır. Bu yüzden aynı katmandaki sınıfları aynı pakete koyma eğilimindeyim.

Bu korumalı veya varsayılan yöntemleri başka yerlerde sık sık kullanmıyorum - muhtemelen sınıf için birim testleri dışında - ama kullandığımda, her zaman aynı katmanda bir sınıftan


Her zaman bir sonraki katmana bağımlı olmak çok katmanlı sistemlerin doğasında bir şey değil mi? Örneğin, kullanıcı arabirimi, etki alanı katmanınıza vb. Bağlı olan hizmetler katmanınıza bağlıdır. Dikey dilimlerin birlikte paketlenmesi, paketler arası aşırı bağımlılıklara karşı koruma sağlıyor gibi görünüyor, değil mi?
Tim Visher

Neredeyse hiçbir zaman korumalı ve varsayılan yöntemler kullanmıyorum. % 99'u kamuya açık veya özeldir. Bazı istisnalar: (1) yalnızca birim testleri tarafından kullanılan yöntemler için varsayılan görünürlük, (2) yalnızca soyut temel sınıftan kullanılan korumalı soyut yöntem.
Esko Luontola

1
Tim Visher'a göre, bağımlılıklar her zaman aynı yönü gösterdiği ve bağımlılık grafiğinde döngü olmadığı sürece paketler arasındaki bağımlılıklar sorun değildir.
Esko Luontola

0

Değişir. Benim işimde, paketleri bazen işlevlere (veri erişimi, analitik) veya varlık sınıfına (kredi, hisse senetleri, faiz oranları) göre ayırıyoruz. Takımınız için en uygun yapıyı seçin.


Her iki şekilde de gitmek için herhangi bir sebep var mı?
Tim Visher

Varlık sınıfına göre bölme (daha genel olarak: iş alanına göre), yeni insanların kodda yollarını bulmalarını kolaylaştırır. İşleve göre bölme, kapsülleme için iyidir. Benim için Java'daki "paket" erişimi, C ++ 'daki bir "arkadaş" a benzer.
quant_dev

@quant_dev "..by işlevi kapsülleme için iyidir" fikrine katılmıyorum. Sanırım tam tersinin doğru olduğunu söylüyorsunuz. Ayrıca, sadece "kolaylık" ı seçmeyin. Her biri için bir durum var (cevabıma bakın).
i3ensays

-3

Tecrübelerime göre, yeniden kullanılabilirlik çözmekten daha fazla sorun yaratır. En yeni ve ucuz işlemciler ve bellekle, yeniden kullanmak için sıkı bir şekilde entegre etmek yerine kodun kopyalanmasını tercih ederim.


5
Kodun yeniden kullanımı, donanımın fiyatı değil, kod bakım maliyetleri ile ilgilidir.
user2793390

1
Kabul ediyorum, ancak basit bir modülde bir şeyi düzeltmek kodun tamamını etkilememelidir. Hangi bakım maliyetlerinden bahsediyorsunuz?
Raghu Kasturi

1
Bir modüldeki bir hata düzeltmesi tüm uygulamayı etkilemelidir. Aynı hatayı neden birden çok kez düzeltmek istersiniz?
user2793390

Kodunuzu yazdıktan yıllar sonra korumak zorunda mıydınız? Benden önce gelen, bilgisayar programlamaya bu kadar saçma bir yaklaşım sergileyenlere lanet okuyorum. Yineleme nedeniyle kodunuzu defalarca düzeltmek için zamanımı harcamak hem verimsiz hem de sinir bozucu. 18 yıl sonra kendi kodum üzerinde çalışmak zorunda kaldım ve yaptığım her ametur hatası hayatı benim için çok daha zor hale getirdi. Artıklık, sonunda ödediğim korkunç hatalardan biridir.
David Rector
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.