Katakanlah setiap kali saya melakukan operasi CRUD atau memodifikasi hubungan dengan cara tertentu saya juga ingin melakukan sesuatu yang lain. Misalnya, setiap kali seseorang menerbitkan posting saya juga ingin menyimpan sesuatu ke meja untuk analitik. Mungkin bukan contoh terbaik tetapi secara umum ada banyak fungsi "dikelompokkan" ini.
Biasanya saya melihat tipe logika ini dimasukkan ke dalam controller. Itu semua bagus dan keren sampai Anda ingin mereproduksi fungsi ini di banyak tempat. Ketika Anda mulai masuk ke sebagian, membuat API dan menghasilkan konten dummy itu menjadi masalah dengan menjaga hal-hal KERING.
Cara yang saya lihat untuk mengelola ini adalah peristiwa, repositori, perpustakaan, dan menambah model. Inilah pemahaman saya masing-masing:
Layanan: Di sinilah kebanyakan orang mungkin akan meletakkan kode ini. Masalah utama saya dengan layanan adalah bahwa kadang-kadang sulit untuk menemukan fungsionalitas spesifik di dalamnya dan saya merasa mereka dilupakan ketika orang-orang fokus menggunakan Eloquent. Bagaimana saya tahu saya perlu memanggil metode publishPost()
di perpustakaan ketika saya bisa melakukannya $post->is_published = 1
?
Satu-satunya syarat saya melihat ini berfungsi dengan baik adalah jika Anda HANYA menggunakan layanan (dan idealnya membuat Eloquent tidak dapat diakses entah bagaimana dari pengontrol secara bersamaan).
Pada akhirnya sepertinya ini hanya akan membuat banyak file tambahan yang tidak perlu jika permintaan Anda umumnya mengikuti struktur model Anda.
Repositori: Dari apa yang saya pahami ini pada dasarnya seperti layanan tetapi ada antarmuka sehingga Anda dapat beralih di antara ORM, yang tidak saya butuhkan.
Kejadian: Saya melihat ini sebagai sistem yang paling elegan karena Anda tahu acara model Anda akan selalu dipanggil dengan metode Eloquent, sehingga Anda dapat menulis pengendali seperti yang biasa Anda lakukan. Saya bisa melihat ini semakin berantakan dan jika ada yang punya contoh proyek besar menggunakan acara untuk kopling kritis saya ingin melihatnya.
Model: Secara tradisional saya memiliki kelas yang melakukan CRUD dan juga menangani coupling kritis. Ini sebenarnya membuat segalanya mudah karena Anda tahu semua fungsi di sekitar CRUD + apa pun yang harus dilakukan dengan itu ada di sana.
Sederhana, tetapi dalam arsitektur MVC ini biasanya tidak seperti yang saya lihat selesai. Dalam arti tertentu saya lebih suka ini daripada layanan karena sedikit lebih mudah ditemukan, dan ada sedikit file untuk melacak. Itu bisa agak berantakan meskipun. Saya ingin mendengar kejatuhan metode ini dan mengapa kebanyakan orang tampaknya tidak melakukannya.
Apa kelebihan / kekurangan masing-masing metode? Apakah saya melewatkan sesuatu?
sumber
Jawaban:
Saya pikir semua pola / arsitektur yang Anda sajikan sangat berguna selama Anda mengikuti prinsip-prinsip SOLID .
Untuk tempat menambahkan logika, saya pikir penting untuk merujuk pada Prinsip Tanggung Jawab Tunggal . Juga, jawaban saya menganggap Anda sedang mengerjakan proyek menengah / besar. Jika ini adalah proyek throw-something-on-a-page , lupakan jawaban ini dan tambahkan semuanya ke pengontrol atau model.
Jawaban singkatnya adalah: Di mana masuk akal bagi Anda (dengan layanan) .
Jawaban panjangnya:
Controllers : Apa tanggung jawab Controllers? Tentu, Anda dapat menempatkan semua logika Anda di controller, tetapi apakah itu tanggung jawab controller? Saya kira tidak.
Bagi saya, controller harus menerima permintaan dan mengembalikan data dan ini bukan tempat untuk meletakkan validasi, memanggil metode db, dll.
Model : Apakah ini tempat yang baik untuk menambahkan logika seperti mengirim email selamat datang ketika pengguna mendaftar atau memperbarui penghitungan suara suatu posting? Bagaimana jika Anda perlu mengirim email yang sama dari tempat lain dalam kode Anda? Apakah Anda membuat metode statis? Bagaimana jika email itu membutuhkan informasi dari model lain?
Saya pikir model harus mewakili suatu entitas. Dengan LARAVEL, saya hanya menggunakan kelas model untuk menambahkan hal-hal seperti
fillable
,guarded
,table
dan hubungan (ini karena saya menggunakan Pola Repository, jika model ini juga akan memilikisave
,update
,find
metode, dll).Repositori (Pola Repositori) : Pada awalnya saya sangat bingung dengan ini. Dan, seperti Anda, saya pikir "baiklah, saya menggunakan MySQL dan hanya itu."
Namun, saya telah menyeimbangkan pro dan kontra menggunakan Pola Repositori dan sekarang saya menggunakannya. Saya pikir sekarang , pada saat ini, saya hanya perlu menggunakan MySQL. Tetapi, jika tiga tahun dari sekarang saya perlu mengubah ke sesuatu seperti MongoDB sebagian besar pekerjaan dilakukan. Semua dengan mengorbankan satu antarmuka tambahan dan a
$app->bind(«interface», «repository»)
.Acara ( Pola Pengamat ): Acara berguna untuk hal-hal yang dapat dilemparkan ke kelas mana saja kapan saja. Pikirkan, misalnya, mengirim pemberitahuan ke pengguna. Ketika Anda membutuhkan, Anda memecat acara untuk mengirim pemberitahuan di kelas aplikasi Anda. Kemudian, Anda dapat memiliki kelas seperti
UserNotificationEvents
itu yang menangani semua acara yang dipecat untuk pemberitahuan pengguna.Layanan : Sampai sekarang, Anda memiliki pilihan untuk menambahkan logika ke pengontrol atau model. Bagi saya, masuk akal untuk menambahkan logika di dalam Layanan . Mari kita hadapi itu, Layanan adalah nama mewah untuk kelas. Dan Anda dapat memiliki kelas sebanyak yang masuk akal untuk Anda dalam aplikasi Anda.
Ambil contoh ini: Beberapa waktu yang lalu, saya mengembangkan sesuatu seperti Formulir Google. Saya mulai dengan
CustomFormService
dan berakhir denganCustomFormService
,CustomFormRender
,CustomFieldService
,CustomFieldRender
,CustomAnswerService
danCustomAnswerRender
. Mengapa? Karena itu masuk akal bagi saya. Jika Anda bekerja dengan tim, Anda harus menempatkan logika Anda di tempat yang masuk akal bagi tim.Keuntungan menggunakan Layanan vs Pengontrol / Model adalah bahwa Anda tidak dibatasi oleh Pengontrol tunggal atau Model tunggal. Anda dapat membuat sebanyak mungkin layanan sesuai kebutuhan berdasarkan desain dan kebutuhan aplikasi Anda. Tambahkan juga keuntungan memanggil Layanan dalam kelas apa pun dari aplikasi Anda.
Ini berlangsung lama, tetapi saya ingin menunjukkan kepada Anda bagaimana saya menyusun aplikasi saya:
Saya menggunakan setiap folder untuk fungsi tertentu. Misalnya
Validators
direktori berisiBaseValidator
kelas yang bertanggung jawab untuk memproses validasi, berdasarkan pada$rules
dan$messages
validator tertentu (biasanya satu untuk setiap model). Saya dapat dengan mudah memasukkan kode ini ke dalam Layanan, tetapi masuk akal bagi saya untuk memiliki folder khusus untuk ini bahkan jika hanya digunakan dalam layanan (untuk saat ini).Saya sarankan Anda untuk membaca artikel berikut, karena mereka mungkin menjelaskan hal-hal yang sedikit lebih baik kepada Anda:
Breaking the Mold oleh Dayle Rees (penulis CodeBright): Di sinilah saya menggabungkan semuanya, meskipun saya mengubah beberapa hal agar sesuai dengan kebutuhan saya.
Memisahkan kode Anda di Laravel menggunakan Repositori dan Layanan oleh Chris Goosey: Posting ini menjelaskan dengan baik apa itu Layanan dan Pola Repositori dan bagaimana mereka cocok bersama.
Laracasts juga memiliki Repositori yang Disederhanakan dan Tanggung Jawab Tunggal yang merupakan sumber daya yang bagus dengan contoh-contoh praktis (walaupun Anda harus membayar).
sumber
Saya ingin mengirim jawaban untuk pertanyaan saya sendiri. Saya bisa membicarakan hal ini selama berhari-hari, tetapi saya akan mencoba untuk memposting ini dengan cepat untuk memastikan saya bangun.
Saya akhirnya menggunakan struktur yang ada yang disediakan Laravel, artinya saya menyimpan file saya terutama sebagai Model, View, dan Controller. Saya juga memiliki folder Perpustakaan untuk komponen yang dapat digunakan kembali yang sebenarnya bukan model.
SAYA TIDAK MENGAMBIL MODEL SAYA DALAM LAYANAN / PERPUSTAKAAN . Semua alasan yang diberikan tidak 100% meyakinkan saya tentang manfaat menggunakan layanan. Walaupun saya mungkin salah, sejauh yang saya bisa lihat mereka hanya menghasilkan banyak file kosong yang hampir saya butuhkan untuk membuat dan beralih antara ketika bekerja dengan model dan juga benar-benar mengurangi manfaat menggunakan fasih (terutama ketika datang ke model RETRIEVING , misalnya, menggunakan pagination, cakupan, dll).
Saya menempatkan logika bisnis DI MODEL dan akses fasih langsung dari pengendali saya. Saya menggunakan sejumlah pendekatan untuk memastikan bahwa logika bisnis tidak dilewati:
Mengatasi masalah orang dengan menggunakan model:
Catatan tambahan: Saya merasa seperti membungkus model Anda dalam layanan seperti memiliki pisau tentara swiss, dengan banyak alat, dan membangun pisau lain di sekitarnya yang pada dasarnya melakukan hal yang sama? Ya, kadang-kadang Anda mungkin ingin melepas pisau atau memastikan dua bilah digunakan bersama-sama ... tetapi biasanya ada cara lain untuk melakukannya ...
KAPAN MENGGUNAKAN LAYANAN : Artikel ini mengartikulasikan dengan sangat baik contoh HEBAT untuk kapan menggunakan layanan ( petunjuk: itu tidak terlalu sering ). Dia mengatakan pada dasarnya ketika objek Anda menggunakan banyak model atau model di bagian aneh siklus hidupnya, itu masuk akal. http://www.justinweiss.com/articles/where-do-you-put-your-code/
sumber
Apa yang saya gunakan untuk membuat logika antara pengontrol dan model adalah membuat lapisan layanan . Pada dasarnya, ini adalah alur saya untuk setiap tindakan dalam aplikasi saya:
Beginilah cara saya melakukannya:
Ini metode pengontrol untuk membuat sesuatu:
Ini adalah kelas layanan yang melakukan logika terkait dengan operasi:
Dan ini adalah model saya:
Untuk informasi lebih lanjut tentang cara ini saya gunakan untuk mengatur kode saya untuk aplikasi Laravel: https://github.com/rmariuzzo/Pitimi
sumber
$congregation->save();
mungkin Anda tidak perlu Repositori. Namun, Anda mungkin melihat kebutuhan akses data Anda meningkat seiring waktu. Anda mungkin mulai memiliki kebutuhan untuk$congregation->destroyByUser()
atau$congregationUsers->findByName($arrayOfSelectedFields);
dan sebagainya. Mengapa tidak membatalkan layanan Anda dari kebutuhan akses data. Biarkan sisa aplikasi Anda bekerja dengan objek / array yang dikembalikan dari repo, dan hanya menangani manipulasi / pemformatan / dll ... Repo Anda akan tumbuh (tetapi membaginya menjadi file yang berbeda, pada akhirnya kompleksitas proyek harus berada di suatu tempat).Menurut pendapat saya, Laravel sudah memiliki banyak pilihan bagi Anda untuk menyimpan logika bisnis Anda.
Jawaban singkat:
Request
untuk memvalidasi input Anda secara otomatis, dan kemudian bertahan data dalam permintaan (buat model). Karena semua input pengguna langsung tersedia dalam permintaan, saya yakin masuk akal untuk melakukan ini di sini.Job
untuk melakukan tugas-tugas yang memerlukan komponen individual, lalu kirimkan saja. kupikirJob
mencakup kelas layanan. Mereka melakukan tugas, seperti logika bisnis.Panjang (er) jawaban:
Gunakan Respositoris Ketika Diperlukan: Repositori pasti akan terlalu banyak digunakan, dan sebagian besar waktu, hanya digunakan sebagai
accessor
model. Saya merasa mereka pasti memiliki beberapa kegunaan, tetapi kecuali Anda sedang mengembangkan aplikasi besar yang membutuhkan sejumlah fleksibilitas bagi Anda untuk dapat membuang laravel sepenuhnya, tinggal jauh dari repositori. Anda akan berterima kasih kepada diri sendiri nanti dan kode Anda akan jauh lebih jelas.Tanyakan pada diri Anda apakah ada kemungkinan Anda akan mengubah kerangka kerja PHP atau ke tipe database yang tidak didukung laravel.
Jika jawaban Anda adalah "Mungkin tidak", maka jangan menerapkan pola repositori.
Selain di atas, jangan menampar pola di atas ORM hebat seperti Eloquent. Anda hanya menambahkan kompleksitas yang tidak diperlukan dan sama sekali tidak menguntungkan Anda.
Manfaatkan Layanan dengan hemat: Kelas layanan bagi saya, hanyalah tempat untuk menyimpan logika bisnis untuk melakukan tugas tertentu dengan dependensi yang diberikan. Laravel memiliki ini di luar kotak, yang disebut 'Pekerjaan', dan mereka memiliki lebih banyak fleksibilitas daripada kelas Layanan kustom.
Saya merasa seperti Laravel memiliki solusi menyeluruh untuk
MVC
masalah logika. Itu hanya masalah atau organisasi.Contoh:
Minta :
Pengendali :
Pada contoh di atas, input permintaan secara otomatis divalidasi, dan yang perlu kita lakukan hanyalah memanggil metode persistence dan mengirimkan Post baru. Saya pikir keterbacaan dan pemeliharaan harus selalu truf pola desain yang kompleks dan tidak dibutuhkan.
Anda kemudian dapat menggunakan metode bertahan yang sama persis untuk memperbarui posting juga, karena kami dapat memeriksa apakah posting sudah ada dan melakukan logika alternatif jika diperlukan.
sumber
ShouldQueue
yang disediakan Laravel. Jika Anda ingin menulis logika Bisnis dalam perintah atau acara, jalankan saja pekerjaan di dalam acara / perintah tersebut. Pekerjaan Laravels sangat fleksibel, tetapi pada akhirnya mereka hanya kelas layanan biasa.