Mari berbagi arsitektur aplikasi web berbasis Java!
Ada banyak arsitektur berbeda untuk aplikasi web yang akan diimplementasikan menggunakan Java. Jawaban atas pertanyaan ini dapat berfungsi sebagai perpustakaan berbagai desain aplikasi web dengan pro dan kontra mereka. Sementara saya menyadari bahwa jawabannya akan subyektif, mari kita coba untuk seobjektif mungkin dan memotivasi pro dan kontra yang kita daftarkan.
Gunakan level detail yang Anda inginkan untuk menggambarkan arsitektur Anda. Agar jawaban Anda bernilai apa pun, setidaknya Anda harus menggambarkan teknologi dan gagasan utama yang digunakan dalam arsitektur yang Anda gambarkan. Dan yang tak kalah pentingnya, kapan kami harus menggunakan arsitektur Anda?
Saya akan mulai...
Tinjauan arsitektur
Kami menggunakan arsitektur 3-tier berdasarkan pada standar terbuka dari Sun seperti Java EE, Java Persistence API, Servlet dan Java Server Pages.
- Kegigihan
- Bisnis
- Presentasi
Kemungkinan arus komunikasi antar lapisan diwakili oleh:
Persistence <-> Business <-> Presentation
Yang misalnya berarti bahwa lapisan presentasi tidak pernah memanggil atau melakukan operasi kegigihan, itu selalu melakukannya melalui lapisan bisnis. Arsitektur ini dimaksudkan untuk memenuhi permintaan aplikasi web ketersediaan tinggi.
Kegigihan
Melakukan operasi membuat, membaca, memperbarui, dan menghapus ( CRUD ) persistensi. Dalam kasus kami, kami menggunakan ( Java Persistence API ) JPA dan kami saat ini menggunakan Hibernate sebagai penyedia ketekunan kami dan menggunakan EntityManager-nya .
Lapisan ini dibagi menjadi beberapa kelas, di mana setiap kelas berurusan dengan jenis entitas tertentu (yaitu entitas yang terkait dengan keranjang belanja mungkin ditangani oleh kelas persistensi tunggal) dan digunakan oleh satu dan hanya satu manajer .
Selain itu lapisan ini juga menyimpan entitas JPA yang merupakan hal-hal seperti Account
, ShoppingCart
dll.
Bisnis
Semua logika yang terkait dengan fungsionalitas aplikasi web terletak di lapisan ini. Fungsionalitas ini dapat memulai transfer uang untuk pelanggan yang ingin membayar produk secara online menggunakan kartu kreditnya. Bisa juga menciptakan pengguna baru, menghapus pengguna atau menghitung hasil pertempuran dalam game berbasis web.
Lapisan ini dibagi menjadi beberapa kelas dan masing-masing kelas ini dianotasi dengan @Stateless
menjadi Bean Sesi Stateless (SLSB). Setiap SLSB disebut manajer dan misalnya seorang manajer bisa menjadi kelas yang dijelaskan sebagaimana disebut AccountManager
.
Ketika AccountManager
perlu melakukan operasi CRUD, ia membuat panggilan yang sesuai ke instance AccountManagerPersistence
, yang merupakan kelas di lapisan persistensi. Sketsa kasar dari dua metode di AccountManager
dapat:
...
public void makeExpiredAccountsInactive() {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
// Calls persistence layer
List<Account> expiredAccounts = amp.getAllExpiredAccounts();
for(Account account : expiredAccounts) {
this.makeAccountInactive(account)
}
}
public void makeAccountInactive(Account account) {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
account.deactivate();
amp.storeUpdatedAccount(account); // Calls persistence layer
}
Kami menggunakan transaksi manajer kontainer sehingga kami tidak perlu melakukan demarkasi transaksi sendiri. Apa yang pada dasarnya terjadi di bawah kap adalah kami melakukan transaksi ketika memasuki metode SLSB dan melakukan itu (atau mengembalikannya) segera sebelum keluar dari metode. Ini adalah contoh konvensi tentang konfigurasi, tetapi kami belum membutuhkan apa pun kecuali yang standar, Diperlukan, belum.
Inilah cara Tutorial Java EE 5 dari Sun menjelaskan atribut transaksi yang Diperlukan untuk Enterprise JavaBeans (EJB):
Jika klien berjalan dalam transaksi dan memanggil metode perusahaan kacang, metode dijalankan dalam transaksi klien. Jika klien tidak terkait dengan transaksi, wadah memulai transaksi baru sebelum menjalankan metode.
Atribut yang diperlukan adalah atribut transaksi implisit untuk semua metode bean perusahaan yang berjalan dengan demarkasi transaksi yang dikelola oleh kontainer. Anda biasanya tidak menetapkan atribut yang diperlukan kecuali Anda perlu mengganti atribut transaksi lainnya. Karena atribut transaksi bersifat deklaratif, Anda dapat dengan mudah mengubahnya nanti.
Presentasi
Lapisan presentasi kami bertanggung jawab atas ... presentasi! Ini bertanggung jawab untuk antarmuka pengguna dan menunjukkan informasi kepada pengguna dengan membangun halaman HTML dan menerima input pengguna melalui permintaan GET dan POST. Kami saat ini menggunakan kombinasi + Java Server Pages ( JSP ) Servlet lama .
Lapisan memanggil metode di manajer lapisan bisnis untuk melakukan operasi yang diminta oleh pengguna dan untuk menerima informasi untuk ditampilkan di halaman web. Terkadang informasi yang diterima dari lapisan bisnis adalah tipe yang tidak terlalu kompleks seperti String
's dan int
eger, dan di lain waktu entitas JPA .
Pro dan kontra dengan arsitekturnya
Pro
- Memiliki semua yang terkait dengan cara tertentu untuk melakukan kegigihan di lapisan ini hanya berarti kita dapat bertukar dari menggunakan JPA menjadi sesuatu yang lain, tanpa harus menulis ulang apa pun di lapisan bisnis.
- Sangat mudah bagi kita untuk menukar layer presentasi kita menjadi sesuatu yang lain, dan kemungkinan kita akan melakukannya jika kita menemukan sesuatu yang lebih baik.
- Membiarkan wadah EJB mengatur batas-batas transaksi itu bagus.
- Menggunakan Servlet's + JPA mudah (untuk memulai) dan teknologinya banyak digunakan dan diimplementasikan di banyak server.
- Menggunakan Java EE seharusnya memudahkan kita untuk membuat sistem ketersediaan tinggi dengan penyeimbangan beban dan kegagalan . Keduanya kami rasa harus kami miliki.
Cons
- Menggunakan JPA, Anda dapat menyimpan kueri yang sering digunakan sebagai kueri bernama dengan menggunakan
@NamedQuery
anotasi pada kelas entitas JPA. Jika Anda memiliki sebanyak mungkin terkait dengan kegigihan di kelas kegigihan, seperti dalam arsitektur kami, ini akan menyebar lokasi di mana Anda mungkin menemukan pertanyaan untuk menyertakan entitas JPA juga. Akan lebih sulit untuk meninjau operasi kegigihan dan karenanya lebih sulit untuk mempertahankannya. - Kami memiliki entitas JPA sebagai bagian dari lapisan ketekunan kami. Tapi
Account
danShoppingCart
, bukankah itu benar-benar objek bisnis? Hal ini dilakukan dengan cara ini karena Anda harus menyentuh kelas-kelas ini dan mengubahnya menjadi entitas yang JPA tahu cara menanganinya. - Entitas JPA, yang juga merupakan objek bisnis kami, dibuat seperti Data Transfer Objects ( DTO 's), juga dikenal sebagai Value Objects (VO's). Ini menghasilkan model domain anemia karena objek bisnis tidak memiliki logika sendiri kecuali metode accessor. Semua logika dilakukan oleh manajer kami di lapisan bisnis, yang menghasilkan gaya pemrograman yang lebih prosedural. Ini bukan desain berorientasi objek yang bagus, tapi mungkin itu bukan masalah? (Bagaimanapun orientasi objek bukan satu-satunya paradigma pemrograman yang telah memberikan hasil.)
- Menggunakan EJB dan Java EE memperkenalkan sedikit kompleksitas. Dan kita tidak bisa menggunakan Tomcat murni (menambahkan wadah mikro EJB tidak sepenuhnya Tomcat).
- Ada banyak masalah dengan menggunakan Servlet's + JPA. Gunakan Google untuk informasi lebih lanjut tentang masalah ini.
- Karena transaksi ditutup ketika keluar dari lapisan bisnis, kami tidak dapat memuat informasi apa pun dari entitas JPA yang dikonfigurasi untuk dimuat dari basis data ketika diperlukan (menggunakan
fetch=FetchType.LAZY
) dari dalam lapisan presentasi. Ini akan memicu pengecualian. Sebelum mengembalikan entitas yang berisi bidang-bidang semacam ini, kami harus memastikan untuk memanggil pengambil yang relevan. Pilihan lain adalah menggunakan Java Persistence Query Language ( JPQL ) dan melakukan aFETCH JOIN
. Namun kedua opsi ini sedikit rumit.