(Java) paket organizasyonu için en iyi uygulamalar var mı? [kapalı]


201

Kısa bir süre önce, burada java paketlerinin ince taneli organizasyonu ile ilgili bir soru gördüm. Örneğin my.project.util, my.project.factory, my.project.servicevs.

Şimdi bulamıyorum, bu yüzden soruyu da sorabilirim.

Java'da paketlerin organizasyonu ve bunlarda neler olduğuna ilişkin en iyi uygulamalar var mı?

Java projenizde sınıflarınızı nasıl düzenlersiniz?

Örneğin, birkaç kişiyle üzerinde çalıştığım bir projede fasulye adı verilen bir paket var. Basit fasulye içeren bir proje olmaya başladı, ancak her şeyi (neredeyse) içeren (kötü deneyim ve zaman eksikliği ile) sona erdi. Bazı fabrika sınıflarını bir fabrika paketine (fasulye oluşturan statik yöntemlere sahip sınıflar) koyarak biraz temizledim, ancak iş mantığını yapan ve dersleri almak gibi basit işlem yapan (iş mantığıyla değil) diğer sınıflarımız var özellikler dosyasındaki bir kod için bir mesaj.

Düşünceleriniz ve yorumlarınız takdir edilmektedir.


74
Bu sorunun kapanmasına katılmıyorum. En iyi uygulama sorularının neredeyse her zaman deneyime ve düşünceye dayandığını kabul etmiyorum, ancak bu soruların Stack Overflow'da kapatılması gerektiğine katılmıyorum. Bu, iyi programlamanın en önemli noktasıdır, en iyi uygulamaları kullanmak ve en iyi çözümü bulmak bu görüş ve deneyimleri kullanır. Lütfen bu soruyu tekrar açın.
Cyntech

Bunu okumanızı tavsiye ederim: satisfice.com/blog/archives/5164 . TL; DR ... "en iyi uygulamalar" fikri kırıldı. En iyi ihtimalle korkunç bir yanlış isim, en kötü ihtimalle düpedüz zararlı.
Stephen C

Yanıtlar:


175

Paket organizasyonu veya paket yapılandırması genellikle ateşli bir tartışmadır. Aşağıda, paket adlandırma ve yapılandırma için bazı basit yönergeler verilmiştir:

  • Java paketi adlandırma kurallarına uyun
  • Paketlerinizi işlevsel rollerine ve iş rollerine göre yapılandırın
    • Paketlerinizi işlevlerine veya modüllerine göre ayırın. Örneğin com.company.product.modulea
    • Daha fazla bozulma, yazılımınızdaki katmanlara dayalı olabilir. Ancak pakette sadece birkaç dersiniz varsa denize açmayın, pakette her şeyin olması mantıklıdır. mesela com.company.product.module.webya com.company.product.module.utilvs.
    • Yapılandırma ile aşırıya kaçmaktan kaçının, IMO, acil bir ihtiyaç olmadığı sürece istisnalar, fabrikalar vb.İçin ayrı ambalajlardan kaçının.
  • Projeniz küçükse, birkaç paketle basit tutun. ör. com.company.product.modelve com.company.product.utilvb.
  • Apache projelerinde bazı popüler açık kaynaklı projelere göz atın . Çeşitli büyüklükteki projeler için yapılandırmayı nasıl kullandıklarını görün.
  • Ayrıca adlandırma sırasında derlemeyi ve dağıtmayı düşünün (api'nizi veya SDK'nızı farklı bir pakette dağıtmanıza izin verir, bkz. Sunucu uygulaması api)

Birkaç denemeden ve denemeden sonra rahat edebileceğiniz bir yapılanma bulmanız gerekir. Tek bir sözleşmeye sabitlenmeyin, değişikliklere açık olun.


Yanıtınız için teşekkürler. Bu büyük ölçüde kuşatmaya çalıştık, ama sorumuzun geldiği fasulye paketimize bir sürü ilgisiz kod girdi.
Cyntech

2
Paketin özelliklerine göre en anlamlı olduğunu kabul ediyorum. Bir zamanlar şirket ofis yapısıyla ilgili büyük bir benzetme duydum. Katmanlı bir yaklaşımda, bir şirketteki seviye başına bireylerin her biri birbiriyle birlikte otururdu; yani Yöneticiler, yöneticiler, yönetici, çalışanlar / işçiler hepsi bir binada ayrı bölümlerde otururlar. Bu yapı muhtemelen bir "özellik" organize yaklaşımı kadar etkili değildir. Yani Satış Yöneticisi, bir Satış Yöneticisi ile oturan Satış çalışanları ile birlikte oturan Satış Müdürü ile birlikte oturuyorsa. Bu şekilde organize edildiğinde bölüm arasında daha iyi uyum sağlar.
alex

Puanlarınızı kabul edin. Sadece bir noktaya şirket adı hakkında vurgulamak için bazen şirket satın alır ürün paketi alır. Yönetim şirket adını kaldırmak istiyor. Havai olabilir.
Tushar D

183

Paketleri desenlere veya uygulama rollerine göre değil, özelliğe göre düzenlerim. Bence paketleri gibi:

  • beans
  • factories
  • collections

yanlış.

Ben tercih ederim, örneğin:

  • orders
  • store
  • reports

böylece paket ayrıntılarını kullanarak uygulama ayrıntılarını gizleyebilirim . Siparişlerin fabrikası orderspakette olmalıdır, böylece siparişin nasıl oluşturulacağı ile ilgili ayrıntılar gizlenir.


10
Bu gönderi, paket görünürlüğü hakkında iyi bir noktaya değiniyor. Java paket kapsamını kullanımda hiç görmedim, ancak doğru paket yapısı geliştiricilerin bundan daha iyi yararlanmasına izin verebilir.
Jpnh

23
Bu kesinlikle doğru, ancak birkaç geliştirici bunu yapıyor. Paketler, bazıları sadece paket içinde görülebilen, uyumlu sınıf koleksiyonları olmalıdır. Bu, farklı özelliklere ait oldukları için birleştirilmemesi gereken sınıflar arasındaki eşleşmeyi en aza indirir. Paket katman yaklaşımı, paket görünürlük değiştiricilerinden faydalanmaz ve böyle bir projedeki paketler düşük bir bütünlüğe ve paketler arasında yüksek derecede bağlantıya sahiptir.
Nate Reed

Bunun bir örneği var mı? Spring-MVC kullanıyorum zor özellik / modül tarafından düzenlemek zor çünkü bahar config xml kullanıyor.
Eric Huang

2
@onof Kodumu özel olarak da düzenlerim, ancak tüm özellikler tarafından paylaşılan temel sınıflar için en iyi uygulamalar nelerdir?
Marc

İlk stili takip ediyordum. ama şimdi sınıflarla çalışırken bir paketten diğerine atlamak zorundayım. gerçekten kötü bir deneyim. Şimdi ikinci stile geçiyorum çünkü ilgili sınıfları birlikte takip etmenin daha kolay olacağını düşünüyorum.
M.kazem Akhgary

40

Kısa cevap: Modül / özellik başına bir paket, muhtemelen alt paketlerle. İlişkili şeyleri aynı pakette bir araya getirin. Paketler arasında dairesel bağımlılıklardan kaçının.

Uzun cevap: Bu makalenin çoğuna katılıyorum


2
alt paketler kapsüllemeyi keser. Bir "alt paket" gerçekten tek başına tamamen bağımsız bir pakettir
Ricardo Gamba

21

Katmanlardan önce özelliği tercih ediyorum, ama sanırım projenize bağlı. Güçlerinizi düşünün:

  • Bağımlılıklar
    Özellikle özellikler arasındaki paket bağımlılıklarını en aza indirmeyi deneyin. Gerekirse API'ları çıkarın.
  • Takım organizasyonu
    Bazı organizasyonlarda takımlar özellikler üzerinde, bazılarında katmanlar üzerinde çalışır. Bu, kodun nasıl organize edildiğini etkiler, API'ları resmileştirmek veya işbirliğini teşvik etmek için kullanın.
  • Dağıtım ve sürüm oluşturma
    Her şeyi bir modülün içine yerleştirmek dağıtım ve sürüm oluşturmayı kolaylaştırır, ancak hata düzeltmeyi zorlaştırır. Öğeleri bölmek daha iyi kontrol, ölçeklenebilirlik ve kullanılabilirlik sağlar.
  • Değişime cevap verin
    İyi organize edilmiş kodu değiştirmek büyük bir çamur topundan çok daha basittir.
  • Boyut (insanlar ve kod satırları)
    Ne kadar büyük olursa o kadar resmi / standart hale gelmesi gerekir.
  • Önemi / kalitesi
    Bazı kodlar diğerlerinden daha önemlidir. API'lar uygulamadan daha kararlı olmalıdır. Bu nedenle açıkça ayrılması gerekir.
  • Soyutlama seviyesi ve giriş noktası
    Bir yabancının kodun ne hakkında olduğunu ve paket ağacına bakarak nereden okumaya başlayacağını bilmesi mümkün olmalıdır.

Misal:

com/company/module
  + feature1/
    - MainClass          // The entry point for exploring
    + api/               // Public interface, used by other features
    + domain/
      - AggregateRoot
      + api/             // Internal API, complements the public, used by web
      + impl/ 
    + persistence/       
    + web/               // presentation layer 
    + services/          // Rest or other remote API 
    + support/            
  + feature2/
  + support/             // Any support or utils used by more than on feature
    + io
    + config
    + persistence
    + web

Bu sadece bir örnek. Oldukça resmi. Örneğin, feature1 için 2 arabirim tanımlar . Normalde bu gerekli değildir, ancak farklı insanlar tarafından farklı şekilde kullanılırsa iyi bir fikir olabilir. Dahili API'nın herkesi genişletmesine izin verebilirsiniz.

'Impl' veya 'destek' adlarını sevmiyorum, ancak daha az önemli şeyleri önemli olandan (alan adı ve API) ayırmaya yardımcı oluyorlar. İsimlendirmeye gelince, olabildiğince somut olmayı seviyorum. 20 sınıflı 'utils' adlı bir paketiniz varsa, StringUtilssupport / string'e, HttpUtilsupport / http'ye vb. Geçin.


13

Java'da paketlerin organizasyonu ve bunlarda neler olduğuna ilişkin en iyi uygulamalar var mı?

Gerçekten hayır. Çok fazla fikir ve çok fikir var, ama gerçek "en iyi uygulama" sağduyunuzu kullanmaktır!

(Lütfen "en iyi uygulamalar" ve onları tanıtan kişiler hakkında bir perspektif için En iyi Uygulama Yok'u okuyun .)

Ancak, muhtemelen geniş kabul gören bir müdür vardır. Paket yapınız uygulamanızın (gayri resmi) modül yapısını yansıtmalı ve modüller arasındaki döngüsel bağımlılıkları en aza indirmeyi (veya ideal olarak tamamen önlemeyi) hedeflemelisiniz.

(Bir paketteki / modüldeki sınıflar arasındaki döngüsel bağımlılıklar gayet iyi, ancak paketler arası döngüler uygulamanızın mimarisini anlamayı zorlaştırıyor ve kodun yeniden kullanılmasına engel olabilir. Özellikle Maven kullanıyorsanız bu döngüyü bulacaksınız paketler arası / modüller arası bağımlılıklar, birbirine bağlı karışıklığın bir Maven artefaktı olması gerektiği anlamına gelir.)

Ben de oradaki eklemek gerekir ise paket adları için tek yaygın olarak kabul en iyi uygulama. Bu, paket adlarınızın kuruluşunuzun etki alanı adıyla ters sırada başlaması gerektiğidir. Bu kurala uyarsanız, (tam) sınıf isimlerinizin diğer insanlarla çatışmasına neden olma olasılığını azaltırsınız.


9

Bazı insanların 'pakete göre' üzerinden 'katmana göre paketi' tanıttığını gördüm, ancak uzun yıllar boyunca birkaç yaklaşım kullandım ve 'pakete göre' özelliğini 'pakete göre' paketinden çok daha iyi buldum.

Bunun yanı sıra, 'özelliğe göre paketle' nin birçok avantajı olduğu için, 'modül, katman, sonra özellik' stratejisinin pratikte son derece iyi çalıştığını gördüm:

  • Yeniden kullanılabilir çerçevelerin oluşturulmasını teşvik eder (hem model hem de UI özellikli kütüphaneler)
  • Katman uygulamalarını model koduyla aynı pakete / dizine yerleştirdiği için tak ve çalıştır katman uygulamalarına izin verir - 'özelliğe göre paketle' ile neredeyse imkansızdır.
  • Çok daha fazlası ...

Burada derinlemesine açıklayacağım: Java Paket Adı Yapısı ve Organizasyonu ancak standart paket yapım:

revdomain.moduleType.moduleName.layer. [layerImpl] .feature.subfeatureN.subfeatureN + 1 ...

Nerede:

revdomain Ters alan adı ör. com.mycompany

moduleType [app * | framework | util]

moduleName örneğin myAppName, modül türü bir uygulama ise veya bir muhasebe çerçevesi ise 'finans' ise

katman [model | ui | süreklilik | güvenlik vb.]

layerImpl örn., küçük kapı, jsp, jpa, jdo, hazırda bekletme (Not: katman modelse kullanılmaz)

özellik ör., finans

alt özellikN örn., muhasebe

alt özellik N + 1 örn., amortisman

* Bazen 'app' moduleType bir uygulama ise, oraya koymak paket yapısını tüm modül türlerinde tutarlı hale getirir.


5

Paket organizasyonu için standart uygulamaların farkında değilim. Genellikle oldukça geniş bir yelpazeyi kapsayan paketler oluştururum, ancak bir proje içinde farklılaşabilirim. Örneğin, şu anda üzerinde çalıştığım kişisel bir projede, özelleştirilmiş UI denetimlerime (sınıfların alt sınıflarını değiştirme sınıflarıyla dolu) ayrılmış bir paket var. Veritabanı yönetimi şeylerime ayrılmış bir paketim var, oluşturduğum bir dizi dinleyici / etkinlik için bir paketim var, vb.

Öte yandan, bir iş arkadaşının yaptığı hemen hemen her şey için yeni bir paket oluşturmasını sağladım. İstediği her farklı MVC kendi paketine sahipti ve bir MVC seti aynı pakette olmasına izin verilen tek sınıf grubu gibi görünüyordu. Bir noktada, her birinin içinde tek bir sınıf olduğu 5 farklı paketi olduğunu hatırlıyorum. Ben onun yöntemi biraz aşırı olduğunu düşünüyorum (ve takım biz sadece halledemediğimizde paket sayısını azaltmak için zorladı), ama önemsiz bir uygulama için, her şeyi aynı pakete koymak olurdu. Bu sizin ve takım arkadaşlarınızın kendiniz bulmak zorunda olduğu bir denge noktası.

Yapabileceğiniz bir şey geri adım atmayı ve düşünmeyi denemektir: projeye tanıtılan yeni bir üye olsaydınız veya projeniz açık kaynak veya API olarak yayınlandıysa, istediğinizi bulmak ne kadar kolay / zor olurdu? Çünkü benim için paketlerden gerçekten istediğim şey bu: organizasyon. Dosyaları bilgisayarımdaki klasörde nasıl depoladığım gibi, tüm sürücümü aramak zorunda kalmadan dosyaları tekrar bulabilmeyi bekliyorum. Paketteki tüm sınıfların listesini aramak zorunda kalmadan istediğim sınıfı bulabilmeyi bekliyorum.

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.