Apakah ada praktik terbaik untuk organisasi paket (Java)? [Tutup]

201

Beberapa waktu yang lalu, saya melihat sebuah pertanyaan dijawab di sini mengenai organisasi paket java yang berbutir halus. Sebagai contoh, my.project.util, my.project.factory, my.project.service, dll

Saya tidak dapat menemukannya sekarang, jadi saya mungkin juga mengajukan pertanyaan.

Apakah ada praktik terbaik terkait dengan pengorganisasian paket di Jawa dan apa yang terjadi di dalamnya?

Bagaimana Anda mengatur kelas Anda di proyek Java Anda?

Misalnya, proyek yang sedang saya kerjakan dengan beberapa orang memiliki paket yang disebut kacang. Awalnya adalah proyek yang mengandung kacang sederhana, tetapi berakhir (melalui pengalaman yang buruk dan kurangnya waktu) yang berisi semuanya (hampir). Saya sudah membersihkannya sedikit, dengan meletakkan beberapa kelas pabrik dalam paket pabrik (kelas dengan metode statis yang menghasilkan kacang) tetapi kami memiliki kelas lain yang melakukan logika bisnis dan yang lain yang melakukan pemrosesan sederhana (bukan dengan logika bisnis) seperti mengambil pesan untuk kode dari file properti.

Pikiran dan komentar Anda dihargai.

Cyntech
sumber
74
Saya tidak setuju dengan penutupan pertanyaan ini. Saya tidak setuju bahwa pertanyaan praktik terbaik hampir selalu didasarkan pada pengalaman dan pendapat, namun, saya tidak setuju bahwa pertanyaan ini harus ditutup pada Stack Overflow. Ini adalah inti dari pemrograman yang baik, menggunakan praktik terbaik dan menemukan solusi terbaik menggunakan pendapat dan pengalaman ini. Harap buka kembali pertanyaan ini.
Cyntech
Saya sarankan Anda membaca ini: satisfice.com/blog/archives/5164 . TL; DR ... seluruh gagasan "praktik terbaik" rusak. Paling-paling itu adalah keliru yang mengerikan, paling buruk itu benar-benar berbahaya.
Stephen C

Jawaban:

174

Organisasi paket atau penataan paket biasanya merupakan diskusi yang hangat. Berikut adalah beberapa panduan sederhana untuk penamaan dan penataan paket:

  • Ikuti konvensi penamaan paket java
  • Strukturkan paket Anda sesuai dengan peran fungsionalnya dan juga peran bisnisnya
    • Hancurkan paket Anda sesuai dengan fungsionalitas atau modulnya. misalnya com.company.product.modulea
    • Perincian lebih lanjut dapat didasarkan pada lapisan dalam perangkat lunak Anda. Tapi jangan berlebihan jika Anda hanya memiliki beberapa kelas dalam paket, maka masuk akal untuk memiliki semua yang ada di paket. misalnya com.company.product.module.webatau com.company.product.module.utillain - lain
    • Hindari berlebihan dengan penataan, IMO menghindari pengemasan terpisah untuk pengecualian, pabrik, dll. Kecuali ada kebutuhan mendesak.
  • Jika proyek Anda kecil, tetap sederhana dengan beberapa paket. mis com.company.product.modeldan com.company.product.util, dll.
  • Lihatlah beberapa proyek open source yang populer di luar sana pada proyek Apache . Lihat bagaimana mereka menggunakan penataan, untuk berbagai proyek ukuran.
  • Juga pertimbangkan membangun dan distribusi saat penamaan (memungkinkan Anda untuk mendistribusikan api atau SDK Anda dalam paket yang berbeda, lihat servlet api)

Setelah beberapa percobaan dan uji coba, Anda harus dapat membuat struktur yang Anda sukai. Jangan terpaku pada satu konvensi, terbuka untuk perubahan.

naikus
sumber
Terimakasih atas tanggapan Anda. Ini sebagian besar yang telah kami coba jangkau, tetapi banyak kode yang tidak terkait masuk ke paket kacang kami, dari situlah pertanyaan saya berasal.
Cyntech
2
Saya setuju paket dengan fitur masuk akal. Saya mendengar analogi yang hebat sekali terkait dengan struktur kantor perusahaan. Dalam pendekatan berlapis, masing-masing individu per level dalam perusahaan akan duduk bersama satu sama lain yaitu Eksekutif, manajer, admin, karyawan / pekerja semua duduk di bagian terpisah di sebuah gedung. Struktur ini kemungkinan tidak seefektif pendekatan terorganisir "fitur". Yaitu jika Eksekutif Penjualan duduk dengan Manajer Penjualan yang duduk dengan karyawan Penjualan yang semuanya duduk dengan Admin Penjualan. Ini memberikan kohesi yang lebih baik antara departemen ketika diatur dengan cara ini.
alex
Setuju dengan poin Anda. Hanya satu poin untuk menyoroti tentang nama perusahaan dalam paket beberapa kali perusahaan mendapatkan produk yang dijual. Manajemen ingin menghapus nama perusahaan. Itu bisa di atas kepala.
Tushar D
183

Saya mengatur paket berdasarkan fitur , bukan oleh pola atau peran implementasi. Saya pikir paket-paket seperti:

  • beans
  • factories
  • collections

salah.

Saya lebih suka, misalnya:

  • orders
  • store
  • reports

jadi saya bisa menyembunyikan detail implementasi melalui visibilitas paket . Pabrik pesanan harus ada dalam orderspaket sehingga detail tentang cara membuat pesanan disembunyikan.

onof
sumber
10
Posting ini membuat poin bagus tentang visibilitas paket. Saya belum pernah melihat lingkup paket Java yang digunakan, tetapi struktur paket yang tepat dapat memungkinkan pengembang untuk mengambil keuntungan lebih baik dari itu.
Jpnh
23
Ini memang benar, tetapi beberapa pengembang melakukan ini. Paket harus merupakan kumpulan kelas yang kohesif, beberapa di antaranya hanya terlihat di dalam paket. Itu akan meminimalkan kopling antara kelas yang tidak boleh ditambah karena mereka berkaitan dengan fitur yang berbeda. Pendekatan paket demi lapis, tidak memanfaatkan pengubah visibilitas paket, dan paket dalam proyek semacam itu memiliki kohesi yang rendah dan tingkat keterikatan yang tinggi antar paket.
Nate Reed
Apakah Anda punya contohnya? Saya menggunakan Spring-MVC saya merasa sulit untuk mengaturnya dengan fitur / modul karena spring menggunakan config xml.
Eric Huang
2
@pada saya juga mengatur kode saya berdasarkan fitur tetapi apa praktik terbaik untuk kelas dasar dibagi oleh semua fitur?
Marc
Saya mengikuti gaya pertama. tetapi sekarang saya harus melompat dari satu paket ke paket lainnya ketika bekerja dengan kelas. itu benar-benar membuat pengalaman buruk. Saya sekarang beralih ke gaya kedua karena saya pikir akan lebih mudah untuk mengikuti kelas terkait bersama.
M.kazem Akhgary
40

Jawaban singkat: Satu paket per modul / fitur, mungkin dengan sub-paket. Masukkan hal-hal yang berkaitan erat dalam paket yang sama. Hindari ketergantungan melingkar antar paket.

Jawaban panjang: Saya setuju dengan sebagian besar artikel ini

Peter Tseng
sumber
2
sub paket memecah enkapsulasi. "Sub-paket" sebenarnya adalah paket yang sepenuhnya independen dengan sendirinya
Ricardo Gamba
21

Saya lebih suka fitur sebelum lapisan, tapi saya kira itu tergantung pada proyek Anda. Pertimbangkan kekuatan Anda:

  • Ketergantungan
    Cobalah meminimalkan ketergantungan paket, terutama antar fitur. Ekstrak API jika perlu.
  • Organisasi tim
    Dalam beberapa organisasi tim bekerja pada fitur dan lainnya di lapisan. Ini memengaruhi cara kode diatur, menggunakannya untuk memformalkan API atau mendorong kerja sama.
  • Penempatan dan
    pembuatan versi Menempatkan semuanya ke dalam modul membuat penerapan dan pembuatan versi menjadi lebih mudah, tetapi memperbaiki bug lebih sulit. Memisahkan hal-hal memungkinkan kontrol yang lebih baik, skalabilitas, dan ketersediaan.
  • Menanggapi perubahan
    Kode yang terorganisasi dengan baik jauh lebih mudah untuk diubah daripada bola lumpur yang besar.
  • Ukuran (orang dan garis kode)
    Semakin besar perlu diformalkan / distandarkan.
  • Pentingnya / kualitas
    Beberapa kode lebih penting daripada yang lain. API harus lebih stabil daripada implementasinya. Karena itu perlu dipisahkan dengan jelas.
  • Tingkat abstraksi dan titik masuk
    Seharusnya mungkin bagi orang luar untuk mengetahui tentang apa kode itu, dan di mana harus mulai membaca dari melihat pohon paket.

Contoh:

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

Ini hanya sebuah contoh. Itu cukup formal. Sebagai contoh, ia mendefinisikan 2 antarmuka untuk feature1 . Biasanya itu tidak diperlukan, tetapi bisa menjadi ide yang baik jika digunakan secara berbeda oleh orang yang berbeda. Anda dapat membiarkan API internal memperluas publik.

Saya tidak suka nama 'impl' atau 'support', tetapi mereka membantu memisahkan hal-hal yang kurang penting dari yang penting (domain dan API). Ketika berbicara tentang penamaan, saya ingin menjadi sekonkret mungkin. Jika Anda memiliki paket yang disebut 'utils' dengan 20 kelas, pindah StringUtilske support / string, HttpUtilke support / http dan seterusnya.

ThomasGran
sumber
13

Apakah ada praktik terbaik terkait dengan pengorganisasian paket di Jawa dan apa yang terjadi di dalamnya?

Tidak juga. Ada banyak ide, dan banyak pendapat, tetapi "praktik terbaik" sesungguhnya adalah menggunakan akal sehat Anda!

(Harap baca Tidak Ada Praktik terbaik untuk perspektif tentang "praktik terbaik" dan orang-orang yang mempromosikannya.)

Namun, ada satu kepala sekolah yang mungkin memiliki penerimaan luas. Struktur paket Anda harus mencerminkan struktur modul (informal) aplikasi Anda, dan Anda harus berusaha meminimalkan (atau idealnya sepenuhnya menghindari) setiap dependensi siklus antar modul.

(Ketergantungan siklik antara kelas dalam satu paket / modul baik-baik saja, tetapi siklus antar paket cenderung membuat sulit memahami arsitektur aplikasi Anda, dan dapat menjadi penghalang untuk menggunakan kembali kode. Secara khusus, jika Anda menggunakan Maven Anda akan menemukan bahwa siklus tersebut dependensi antar-paket / antar-modul berarti bahwa seluruh kekacauan yang saling berhubungan harus menjadi satu artefak Maven.)

Saya juga harus menambahkan bahwa ada adalah salah satu diterima secara luas praktek terbaik untuk nama paket. Dan itu adalah bahwa nama paket Anda harus dimulai dengan nama domain organisasi Anda dalam urutan terbalik. Jika Anda mengikuti aturan ini, Anda mengurangi kemungkinan masalah yang disebabkan oleh nama kelas Anda (penuh) yang berbenturan dengan orang lain.

Stephen C
sumber
9

Saya telah melihat beberapa orang mempromosikan 'paket berdasarkan fitur' lebih dari 'paket per lapisan' tetapi saya telah menggunakan beberapa pendekatan selama bertahun-tahun dan menemukan 'paket per lapisan' jauh lebih baik daripada 'paket dengan fitur'.

Lebih jauh dari itu saya telah menemukan bahwa sebuah hybrid: strategi 'paket per modul, lapisan kemudian fitur' bekerja sangat baik dalam praktik karena memiliki banyak keuntungan dari 'paket berdasarkan fitur':

  • Mempromosikan pembuatan kerangka kerja yang dapat digunakan kembali (perpustakaan dengan kedua model dan aspek UI)
  • Mengizinkan implementasi layer plug and play - secara virtual tidak mungkin dengan 'package by feature' karena ia menempatkan implementasi layer dalam paket / direktori yang sama dengan kode model.
  • Masih banyak lagi...

Saya jelaskan secara mendalam di sini: Struktur dan Organisasi Nama Paket Java tetapi struktur paket standar saya adalah:

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

Dimana:

revdomain Reverse domain misalnya com.mycompany

moduleType [app * | framework | util]

moduleName misalnya myAppName jika jenis modul adalah aplikasi atau 'keuangan' jika kerangka akuntingnya

lapisan [model | ui | kegigihan | keamanan dll,]

layerImpl misalnya., wicket, jsp, jpa, jdo, hibernate (Catatan: tidak digunakan jika layer adalah model)

fitur mis., keuangan

subfeatureN misalnya., akuntansi

subfeatureN + 1 mis., penyusutan

* Terkadang 'aplikasi' ditinggalkan jika moduleType adalah aplikasi tetapi meletakkannya di sana membuat struktur paket konsisten di semua jenis modul.

Volksman
sumber
5

Saya tidak mengetahui praktik standar untuk organisasi paket. Saya biasanya membuat paket yang mencakup beberapa spektrum yang cukup luas, tetapi saya dapat membedakan dalam suatu proyek. Misalnya, proyek pribadi yang sedang saya kerjakan memiliki paket yang ditujukan untuk kontrol UI khusus saya (penuh dengan kelas-kelas yang mengelompokkan kelas-kelas ayunan). Saya punya paket yang ditujukan untuk hal-hal manajemen database saya, saya punya paket untuk satu set pendengar / acara yang saya buat, dan sebagainya.

Di sisi lain saya punya rekan kerja membuat paket baru untuk hampir semua yang dia lakukan. Setiap MVC berbeda yang ia inginkan memiliki paket sendiri, dan sepertinya satu set MVC adalah satu-satunya pengelompokan kelas yang diizinkan berada dalam paket yang sama. Saya ingat pada satu titik dia memiliki 5 paket berbeda yang masing-masing memiliki satu kelas di dalamnya. Saya pikir metodenya sedikit ekstrim (dan tim memaksanya untuk mengurangi jumlah paket ketika kami tidak bisa mengatasinya), tetapi untuk aplikasi nontrivial, jadi akan meletakkan semuanya dalam paket yang sama. Ini adalah titik keseimbangan yang harus Anda dan rekan tim Anda temukan sendiri.

Satu hal yang dapat Anda lakukan adalah mencoba melangkah mundur dan berpikir: jika Anda adalah anggota baru yang diperkenalkan pada proyek, atau proyek Anda dirilis sebagai open source atau API, seberapa mudah / sulit untuk menemukan apa yang Anda inginkan? Karena bagi saya, itulah yang saya inginkan dari paket: organisasi. Mirip dengan bagaimana saya menyimpan file dalam folder di komputer saya, saya berharap dapat menemukannya lagi tanpa harus mencari seluruh drive saya. Saya berharap dapat menemukan kelas yang saya inginkan tanpa harus mencari daftar semua kelas dalam paket.

Brian S
sumber