Struktur aplikasi Java: Pemisah horizontal vs vertikal

15

Memiliki sedikit perdebatan tentang struktur proyek awal (menggunakan Maven / Eclipse) untuk aplikasi Java besar.

Pilihan 1:

entities (i.e. the whole database using Hibernate classes-first)
services (i.e. sets of read/write operations on the entities)
app (perhaps split up more further down the line)

Pilihan 2:

area1-entities
area1-services
area1-app
area2-entities
area2-services
area2-app
...
(where area1, area2 etc. are functional areas of the system)

Opsi 2 jelas akan menghasilkan lebih banyak proyek / modul Maven dan berarti kelas-kelas yang akan menghasilkan basis data didistribusikan di antara beberapa proyek. Adakah yang bisa menyarankan pro / kontra dari setiap pendekatan?

Steve Chambers
sumber
3
Tidak juga. IMHO (kita mulai) kita harus berhenti dengan memisahkan pada lapisan teknis yang hanya mengarah ke bola besar lumpur. Sebagai gantinya paket fungsional. Hanya area1 / area2 yang harus berisi inti dari aplikasi Anda (entitas, layanan (terbelah dalam antarmuka publik dan paket implementasi pribadi), repositori (jika perlu). Sekarang Anda harus menghubungkan web / layer / pesan Anda ke inti itu. ingin melihatnya di sini dan di sini
Itu masih dikomentari :). Tapi saya akan melakukan pemolesan untuk menjawabnya.
Anda mungkin ingin memeriksa stackoverflow.com/questions/11733267/…
Terima kasih tetapi pertanyaan ini adalah tentang struktur proyek daripada struktur paket
Steve Chambers

Jawaban:

29

Saya sarankan tidak melakukan keduanya.

Mencoba untuk menerapkan pelapisan teknis dengan struktur paket menyebabkan banyak keterjeratan dalam aplikasi Anda. Belum lagi fakta bahwa kami berusaha sangat keras untuk menyembunyikan segala sesuatu di balik antarmuka layanan dan hal pertama yang kami lakukan (kebanyakan karena pengemasan) adalah membuat semuanya menjadi public class. Ini menjadi menyakitkan ketika ada pemisahan teknis antara a x.y.z.servicedan x.y.z.repositorypaket, sekarang semuanya dapat mengakses repositori. Boom ada enkapsulasi Anda di dalam lapisan layanan.

Sebaliknya Anda harus mengikuti pendekatan yang lebih fungsional dan berbasis bawang merah ( arsitektur bersih , arsitektur heksagonal ). Ini juga sejalan dengan Prinsip Tanggung Jawab Tunggal (bila diterapkan pada suatu paket) dan juga sesuai dengan prinsip pengemasan

  1. Hal-hal yang berubah bersama dikemas bersama
  2. Benda-benda yang digunakan bersama dikemas bersama

Oliver Gierke telah menulis posting yang bagus tentang komponen pengemasan bersama di Jawa. Simon Brown telah menulis cerita yang lebih umum tentang masalah ini.

Saya akan berusaha keras untuk struktur paket inti seperti berikut ini untuk menampung inti aplikasi Anda:

x.y.z.area1
x.y.z.area2

Sekarang jika Anda memiliki antarmuka web yang Anda tambahkan, misalnya, websub paket, untuk layanan web wsataurest paket hanya untuk menampungnya. Ini pada dasarnya terhubung ke inti.

x.y.z.area1.web
x.y.z.area1.ws
x.y.z.area2.rest

Sekarang Anda dapat mempertimbangkan menggunakan kembali objek dari dalam inti Anda ke dalam lapisan lain, tetapi IMHO lebih baik menggunakan domain tertentu untuk lapisan itu. Seperti, seperti halnya dengan Object to SQL mapping ada (sering) ketidaksesuaian dalam apa yang ingin kita tampilkan di layar atau gunakan sebagai XML dalam layanan web dan bagaimana logika bisnis diimplementasikan. Bergantung pada kompleksitas bisnis dan domain web, Anda dapat menganggapnya sebagai domain masalah terpisah untuk dipecahkan yang perlu dihubungkan, pada dasarnya 2 berbeda konteks terikat yang berbeda .

Untuk menggunakan penawaran dari sumber CQRS

Tidak mungkin untuk membuat solusi optimal untuk mencari, melaporkan, dan memproses transaksi menggunakan model tunggal.

Jangan mencoba memasukkan semuanya ke dalam satu model (domain), pisahkan tanggung jawab. Anda mungkin berakhir dengan lebih banyak kelas (lebih kecil) tetapi pemisahan yang lebih bersih antara lapisan aplikasi Anda.

Catatan Akhir

Ingat, menciptakan arsitektur adalah menentukan timbal balik dari satu solusi ke solusi lainnya. Ini sangat tergantung pada kompleksitas domain dan terutama harus didorong oleh persyaratan fungsional aplikasi Anda. Namun itu dipengaruhi oleh kendala non-fungsional (kinerja, keamanan) dan lingkungan (bahasa untuk digunakan, platform, pengalaman). Dan arsitektur, seperti pengkodean, tidak pernah selesai setiap persyaratan baru dapat (dan mungkin harus?) Mengarah pada desain ulang aplikasi.

Penolakan

Ya saya juga mencoba untuk meletakkan semuanya dalam satu model, dan ya saya juga mencoba menggunakan pemisahan teknis dalam aplikasi saya. Namun setelah beberapa tahun pengalaman dalam membuat layering aplikasi terjerat (pada awalnya sepertinya ide yang baik, maka aplikasi mulai tumbuh ...) Saya pikir pasti ada cara lain.

Tautan

  1. Arsitektur Bersih, Paman Bob Martin
  2. Arsitektur Heksagonal (alias Port dan Adaptor), Alistair Cockburn
  3. Ups ke mana arsitektur saya pergi, Oliver Gierke
  4. Prinsip OOD, Paman Bob Martin
  5. Kesalahan saat menerapkan DDD, Udi Dahan
  6. Konteks Terikat, Martin Fowler
  7. Gaya Pengodean Arsitektur yang Jelas, Simon Brown

Buku

  1. Tumbuh Perangkat Lunak Berorientasi Objek, Dipandu oleh Tes
  2. Arsitektur Aplikasi Java: Pola Modularitas dengan Contoh Menggunakan OSGi (Robert C. Martin Series)
  3. Desain Berbasis Domain: Menangani Kompleksitas di Jantung Perangkat Lunak
  4. Arsitektur Perangkat Lunak untuk Pengembang
  5. Menerapkan Desain Berbasis Domain
M. Deinum
sumber
1
Jawaban yang bagus :) Saya akan menambahkan yang harus dibaca untuk mengatasi masalah ini: amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/…
Mik378
1
Bagus, menambahkan beberapa lagi ke jawaban asli saya.
1
Sejauh ini buku terbaik tentang desain yang pernah saya baca;) Anda dapat menyebutkan buku Vaughn Vernon, sangat bagus juga: amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/…
Mik378
@ M.Deinum +1 Bagus untuk referensi!
1
@ Mik378 Saya memiliki kedua buku di perpustakaan digital saya, di antara banyak buku lainnya.