Saya merancang aplikasi berbasis web yang sederhana. Saya baru mengenal domain berbasis web ini. Saya membutuhkan saran Anda mengenai pola desain seperti bagaimana tanggung jawab harus didistribusikan di antara Servlet, kriteria untuk membuat Servlet baru, dll.
Sebenarnya, saya memiliki beberapa entitas di halaman rumah saya dan sesuai dengan masing-masing entitas, kami memiliki beberapa opsi seperti menambah, mengedit, dan menghapus. Sebelumnya saya menggunakan satu Servlet per opsi seperti Servlet1 untuk add entity1, Servlet2 untuk mengedit entitas1 dan seterusnya dan dengan cara ini kami akhirnya memiliki sejumlah besar servlet.
Sekarang kami mengubah desain kami. Pertanyaan saya adalah bagaimana Anda secara tepat memilih bagaimana Anda memilih tanggung jawab servlet. Haruskah kita memiliki satu Servlet per entitas yang akan memproses semua opsi itu dan meneruskan permintaan ke lapisan layanan. Atau haruskah kita memiliki satu servlet untuk seluruh halaman yang akan memproses permintaan seluruh halaman dan kemudian meneruskannya ke lapisan layanan yang sesuai? Juga, haruskah objek permintaan diteruskan ke lapisan layanan atau tidak.
sumber
Jawaban:
Aplikasi web yang sedikit baik terdiri dari campuran pola desain. Saya hanya akan menyebutkan yang paling penting.
Pola Pengendali Tampilan Model
Pola desain inti (arsitektur) yang ingin Anda gunakan adalah pola Model-View-Controller . The Pengendali harus diwakili oleh Servlet yang (di) langsung menciptakan / menggunakan spesifik Model dan View berdasarkan permintaan. The Model yang akan diwakili oleh kelas JavaBean. Ini sering dibagi lagi dalam Model Bisnis yang berisi tindakan (perilaku) dan Model Data yang berisi data (informasi). The View adalah untuk diwakili oleh file JSP yang memiliki akses langsung ke ( data ) Model oleh EL (Expression Language).
Lalu, ada variasi berdasarkan bagaimana tindakan dan peristiwa ditangani. Yang populer adalah:
Permintaan (tindakan) berdasarkan MVC : ini adalah yang paling sederhana untuk diterapkan. The ( Bisnis ) Model bekerja secara langsung dengan
HttpServletRequest
danHttpServletResponse
benda-benda. Anda harus mengumpulkan, mengonversi, dan memvalidasi parameter permintaan (kebanyakan) sendiri. The View dapat diwakili oleh plain vanilla HTML / CSS / JS dan tidak mempertahankan negara di seluruh permintaan. Beginilah cara kerja Spring MVC , Struts and Stripes .MVC berbasis komponen : ini lebih sulit untuk diterapkan. Tetapi Anda berakhir dengan model yang lebih sederhana dan melihat di mana semua API Servlet "mentah" diabstraksi sepenuhnya. Anda seharusnya tidak perlu mengumpulkan, mengonversi, dan memvalidasi sendiri parameter permintaan. The Pengendali melakukan tugas ini dan set berkumpul, parameter permintaan dikonversi dan divalidasi dalam Model . Yang perlu Anda lakukan adalah mendefinisikan metode tindakan yang bekerja langsung dengan properti model. The View diwakili oleh "komponen" di rasa taglibs JSP atau elemen XML yang pada gilirannya menghasilkan HTML / CSS / JS. Keadaan Tampilanuntuk permintaan selanjutnya dipertahankan dalam sesi. Ini sangat membantu untuk konversi sisi server, validasi, dan perubahan nilai. Ini adalah bagaimana antara lain JSF , Wicket and Play! bekerja.
Sebagai catatan tambahan, bermain-main dengan kerangka kerja MVC buatan sendiri adalah latihan pembelajaran yang sangat menyenangkan, dan saya merekomendasikannya selama Anda menyimpannya untuk keperluan pribadi / pribadi. Tetapi begitu Anda menjadi profesional, maka sangat disarankan untuk memilih kerangka kerja yang ada daripada menciptakan kembali kerangka kerja Anda sendiri. Mempelajari kerangka kerja yang sudah ada dan dikembangkan dengan baik membutuhkan waktu lebih lama daripada mengembangkan dan mempertahankan kerangka kerja yang kokoh.
Dalam penjelasan rinci di bawah ini saya akan membatasi diri untuk meminta MVC berbasis karena itu lebih mudah untuk diterapkan.
Pola Pengontrol Depan ( pola Mediator )
Pertama, bagian Pengendali harus menerapkan pola Pengontrol Depan (yang merupakan jenis khusus dari pola Mediator ). Ini harus terdiri dari hanya satu servlet yang menyediakan titik masuk terpusat dari semua permintaan. Ini harus membuat Model berdasarkan informasi yang tersedia oleh permintaan, seperti pathinfo atau servletpath, metode dan / atau parameter tertentu. The Model Bisnis disebut
Action
di bawah iniHttpServlet
contoh.Menjalankan tindakan harus mengembalikan beberapa pengidentifikasi untuk menemukan tampilan. Paling sederhana adalah menggunakannya sebagai nama file dari JSP. Peta servlet ini pada spesifik
url-pattern
diweb.xml
, misalnya/pages/*
,*.do
atau bahkan hanya*.html
.Dalam kasus pola awalan seperti misalnya
/pages/*
Anda kemudian dapat memanggil URL seperti http://example.com/pages/register , http://example.com/pages/login , dll dan berikan/WEB-INF/register.jsp
,/WEB-INF/login.jsp
dengan tindakan GET dan POST yang sesuai . Bagian-bagianregister
,,login
dll kemudian tersediarequest.getPathInfo()
seperti pada contoh di atas.Saat Anda menggunakan pola sufiks seperti
*.do
,,*.html
dll, maka Anda dapat memunculkan URL seperti http://example.com/register.do , http://example.com/login.do , dll dan Anda harus mengubah contoh kode dalam jawaban ini (juga theActionFactory
) untuk mengekstrak bagianregister
-login
bagian danrequest.getServletPath()
sebagai gantinya.Pola strategi
The
Action
harus mengikuti pola Strategi . Itu perlu didefinisikan sebagai tipe abstrak / antarmuka yang harus melakukan pekerjaan berdasarkan argumen yang dilewatkan dari metode abstrak (ini adalah perbedaan dengan pola Command , di mana jenis abstrak / antarmuka harus melakukan pekerjaan berdasarkan pada argumen yang telah diteruskan selama penciptaan implementasi).Anda mungkin ingin membuat yang
Exception
lebih spesifik dengan pengecualian khusus sepertiActionException
. Ini hanya contoh awal kickoff, sisanya terserah Anda.Berikut adalah contoh dari
LoginAction
yang (seperti namanya) mencatat pengguna. ItuUser
sendiri pada gilirannya Model Data . The View menyadari kehadiranUser
.Pola metode pabrik
The
ActionFactory
harus mengikuti pola metode Factory . Pada dasarnya, ini harus menyediakan metode kreatif yang mengembalikan implementasi konkret dari tipe abstrak / antarmuka. Dalam hal ini, harus mengembalikan implementasiAction
antarmuka berdasarkan informasi yang disediakan oleh permintaan. Misalnya, metode dan pathinfo (pathinfo adalah bagian setelah konteks dan jalur servlet di URL permintaan, tidak termasuk string kueri).Pada
actions
gilirannya harus berupa static / applicationwideMap<String, Action>
yang menampung semua tindakan yang diketahui. Terserah Anda bagaimana mengisi peta ini. Hardcoding:Atau dapat dikonfigurasi berdasarkan file konfigurasi properti / XML di classpath: (pseudo)
Atau secara dinamis didasarkan pada pemindaian di classpath untuk kelas yang mengimplementasikan antarmuka dan / atau anotasi tertentu: (pseudo)
Perlu diingat untuk membuat "tidak melakukan apa-apa"
Action
untuk kasus ini tidak ada pemetaan. Biarkan misalnya mengembalikan langsungrequest.getPathInfo().substring(1)
itu.Pola lainnya
Itu adalah pola penting sejauh ini.
Untuk melangkah lebih jauh, Anda bisa menggunakan pola Facade untuk membuat
Context
kelas yang pada gilirannya membungkus objek permintaan dan respons dan menawarkan beberapa metode kenyamanan mendelegasikan ke objek permintaan dan respons dan meneruskannya sebagai argumen ke dalamAction#execute()
metode sebagai gantinya. Ini menambahkan lapisan abstrak ekstra untuk menyembunyikan API Servlet mentah. Anda pada dasarnya harus berakhir dengan nolimport javax.servlet.*
deklarasi dalam setiapAction
implementasi. Dalam istilah JSF, inilah yang dilakukan olehFacesContext
danExternalContext
kelas. Anda dapat menemukan contoh nyata dalam jawaban ini .Lalu ada pola Status untuk kasus yang ingin Anda tambahkan lapisan abstraksi ekstra untuk membagi tugas mengumpulkan parameter permintaan, mengonversinya, memvalidasinya, memperbarui nilai-nilai model dan menjalankan tindakan. Dalam istilah JSF, inilah yang
LifeCycle
dilakukannya.Lalu ada pola Komposit untuk kasus yang ingin Anda buat tampilan berbasis komponen yang dapat dilampirkan dengan model dan yang perilakunya tergantung pada keadaan siklus hidup berdasarkan permintaan. Dalam istilah JSF, inilah yang
UIComponent
diwakilinya.Dengan cara ini Anda dapat berevolusi sedikit demi sedikit menuju kerangka kerja berbasis komponen.
Lihat juga:
sumber
web.xml
, maka Anda bisa menggunakanServletContextListener
ini. Mintalah pabrik mengimplementasikannya (dan daftar seperti<listener>
diweb.xml
) dan melakukan pekerjaan pengisian selamacontextInitialized()
metode.Action
implementasi dengan cara yang sama seperti pada servlets normal (lihat juga servlets wiki untuk contoh dasar, yang Anda bebas untuk refactor lebih jauh ke beberapaValidator
antarmuka). Tapi Anda juga bisa melakukannya sebelum menjalankan tindakan, tetapi ini lebih kompleks karena memerlukan aturan validasi yang diketahui berdasarkan per-view. JSF telah menutupi ini dengan korbanrequired="true"
,validator="customValidatorName"
, dll di markup XHTML.Dalam pola MVC yang terpukul, Servlet adalah "C" - controller.
Tugas utamanya adalah melakukan evaluasi permintaan awal dan kemudian mengirimkan pemrosesan berdasarkan evaluasi awal kepada pekerja tertentu. Salah satu tanggung jawab pekerja mungkin adalah menyiapkan beberapa lapisan kacang presentasi dan meneruskan permintaan ke halaman JSP untuk membuat HTML. Jadi, untuk alasan ini saja, Anda perlu meneruskan objek permintaan ke lapisan layanan.
Saya tidak akan mulai menulis
Servlet
kelas mentah . Pekerjaan yang mereka lakukan sangat mudah diprediksi dan dipanaskan, sesuatu yang kerangka kerjanya sangat baik. Untungnya, ada banyak kandidat yang telah teruji oleh waktu (sesuai urutan abjad): Apache Wicket , Java Server Faces , Spring untuk beberapa nama.sumber
IMHO, tidak ada banyak perbedaan dalam hal aplikasi web jika Anda melihatnya dari sudut penugasan tanggung jawab. Namun, pertahankan kejelasan di layer. Simpan segala sesuatu murni untuk tujuan presentasi di lapisan presentasi, seperti kontrol dan kode khusus untuk kontrol web. Simpan saja entitas Anda di lapisan bisnis dan semua fitur (seperti menambah, mengedit, menghapus) dll di lapisan bisnis. Namun merendernya ke browser untuk ditangani di lapisan presentasi. Untuk .Net, pola ASP.NET MVC sangat baik dalam hal menjaga lapisan dipisahkan. Lihatlah pola MVC.
sumber
Saya telah menggunakan kerangka kerja struts dan merasa cukup mudah dipelajari. Saat menggunakan struts framework, setiap halaman situs Anda akan memiliki item berikut.
1) Suatu tindakan yang digunakan dipanggil setiap kali halaman HTML di-refresh. Tindakan harus mengisi data dalam bentuk ketika halaman pertama kali dimuat dan menangani interaksi antara UI web dan lapisan bisnis. Jika Anda menggunakan halaman jsp untuk memodifikasi objek java yang bisa diubah, salinan dari objek java harus disimpan dalam bentuk daripada yang asli sehingga data asli tidak bisa dimodifikasi kecuali pengguna menyimpan halaman.
2) Formulir yang digunakan untuk mentransfer data antara tindakan dan halaman jsp. Objek ini harus terdiri dari satu set pengambil dan setter untuk atribut yang harus dapat diakses ke file jsp. Formulir ini juga memiliki metode untuk memvalidasi data sebelum tetap ada.
3) Halaman jsp yang digunakan untuk membuat HTML akhir halaman. Halaman jsp adalah gabungan dari tag HTML dan struts khusus yang digunakan untuk mengakses dan memanipulasi data dalam formulir. Meskipun struts memungkinkan pengguna untuk memasukkan kode Java ke file jsp, Anda harus sangat berhati-hati melakukan hal itu karena membuat kode Anda lebih sulit dibaca. Kode Java di dalam file jsp sulit untuk di-debug dan tidak dapat diuji unit. Jika Anda menemukan diri Anda menulis lebih dari 4-5 baris kode java di dalam file jsp, kode tersebut mungkin harus dipindahkan ke tindakan.
sumber
BalusC jawaban yang sangat baik mencakup sebagian besar pola untuk aplikasi web.
Beberapa aplikasi mungkin memerlukan Chain-of-responsibility_pattern
Gunakan case untuk menggunakan pola ini:
Ketika pawang memproses permintaan (perintah) tidak diketahui dan permintaan ini dapat dikirim ke beberapa objek. Umumnya Anda menetapkan penerus ke objek. Jika objek saat ini tidak dapat menangani permintaan atau memproses permintaan secara parsial dan meneruskan permintaan yang sama ke objek penerus .
Pertanyaan / artikel SE yang bermanfaat:
Mengapa saya akan menggunakan Rantai Tanggung Jawab atas Dekorator?
Penggunaan umum untuk rantai tanggung jawab?
rantai-of-tanggung jawab-pola dari oodesign
chain_of_responsibility dari pembuatan sumber
sumber