Dalam aplikasi web MVC khas (dirancang dengan baik), database tidak mengetahui kode model, kode model tidak mengetahui kode pengontrol, dan kode pengontrol tidak mengetahui kode tampilan. (Saya membayangkan Anda bahkan bisa mulai sejauh hardware, atau mungkin lebih jauh, dan polanya mungkin sama.)
Pergi ke arah lain, Anda bisa pergi hanya satu lapisan ke bawah. Tampilan dapat menyadari controller tetapi bukan modelnya; pengontrol dapat mengetahui model tetapi tidak database; model dapat mengetahui database tetapi tidak OS. (Apa pun yang lebih dalam mungkin tidak relevan.)
Saya secara intuitif dapat memahami mengapa ini adalah ide yang baik tetapi saya tidak dapat mengartikulasikannya. Mengapa gaya layering searah ini merupakan ide yang bagus?
sumber
Jawaban:
Lapisan, modul, memang arsitektur itu sendiri, adalah cara untuk membuat program komputer lebih mudah dipahami oleh manusia . Metode penyelesaian angka yang optimal secara numerik hampir selalu merupakan kekacauan kusut dari kode non-modular, referensi-sendiri atau bahkan modifikasi-sendiri - apakah itu kode assembler yang sangat dioptimalkan dalam sistem tertanam dengan kendala memori yang melumpuhkan atau urutan DNA setelah jutaan tahun. tekanan seleksi. Sistem seperti itu tidak memiliki lapisan, tidak ada arah aliran informasi yang jelas, bahkan tidak ada struktur yang dapat kita lihat sama sekali. Bagi semua orang kecuali penulisnya, mereka tampaknya bekerja dengan sihir murni.
Dalam rekayasa perangkat lunak, kami ingin menghindarinya. Arsitektur yang baik adalah keputusan yang disengaja untuk mengorbankan efisiensi demi membuat sistem dimengerti oleh orang normal. Memahami satu hal pada satu waktu lebih mudah daripada memahami dua hal yang hanya masuk akal ketika digunakan bersama. Itu sebabnya modul dan layer adalah ide yang bagus.
Tapi mau tidak mau modul harus memanggil fungsi satu sama lain, dan layer harus dibuat saling bertumpukan. Jadi dalam praktiknya, selalu diperlukan untuk membangun sistem sehingga beberapa bagian memerlukan bagian lain. Kompromi yang lebih disukai adalah membangunnya sedemikian rupa sehingga satu bagian membutuhkan yang lain, tetapi bagian itu tidak membutuhkan yang pertama kembali. Dan inilah yang sebenarnya diberikan oleh layering searah: mungkin untuk memahami skema basis data tanpa mengetahui aturan bisnis, dan untuk memahami aturan bisnis tanpa mengetahui tentang antarmuka pengguna. Alangkah baiknya memiliki kemandirian di kedua arah - memungkinkan seseorang untuk memprogram UI baru tanpa mengetahui apa - apasama sekali tentang aturan bisnis - tetapi dalam praktiknya ini hampir tidak pernah mungkin. Aturan praktis seperti "Tidak ada ketergantungan siklus" atau "Ketergantungan hanya harus mencapai satu tingkat" cukup menangkap batas praktis yang dapat dicapai dari gagasan mendasar bahwa satu hal pada suatu waktu lebih mudah dipahami daripada dua hal.
sumber
Motivasi mendasar adalah ini: Anda ingin dapat merobek seluruh lapisan dan mengganti yang sama sekali berbeda (ditulis ulang), dan TIDAK ADA YANG HARUS (DAPAT MAMPU) PEMBERITAHUAN PERBEDAAN.
Contoh yang paling jelas adalah merobek lapisan bawah dan mengganti yang lain. Ini adalah apa yang Anda lakukan ketika Anda mengembangkan lapisan atas terhadap simulasi perangkat keras, dan kemudian mengganti perangkat keras yang sebenarnya.
Contoh berikutnya adalah ketika Anda merobek lapisan tengah dan mengganti lapisan tengah yang berbeda. Pertimbangkan aplikasi yang menggunakan protokol yang berjalan di atas RS-232. Suatu hari, Anda harus mengubah pengkodean protokol sepenuhnya, karena "sesuatu yang lain berubah". (Contoh: beralih dari penyandian ASCII langsung ke penyandian Reed-Solomon dari aliran ASCII, karena Anda sedang mengerjakan tautan radio dari pusat kota LA ke Marina Del Rey, dan Anda sekarang bekerja melalui tautan radio dari pusat kota LA ke sebuah probe yang mengorbit Europa) , salah satu bulan Jupiter, dan tautan itu memerlukan koreksi kesalahan ke depan yang lebih baik.)
Satu-satunya cara untuk membuat pekerjaan ini adalah jika setiap lapisan mengekspor antarmuka yang diketahui dan didefinisikan ke lapisan di atas, dan mengharapkan antarmuka yang dikenal dan didefinisikan ke lapisan di bawah ini.
Sekarang, itu bukan kasus yang lapisan bawah tahu TIDAK ADA tentang lapisan atas. Sebaliknya, apa yang diketahui lapisan bawah adalah bahwa lapisan tepat di atasnya akan beroperasi secara tepat sesuai dengan antarmuka yang ditentukan. Ia tidak tahu apa-apa lagi, karena dengan definisi apa pun yang tidak ada di antarmuka yang didefinisikan dapat berubah TANPA PEMBERITAHUAN.
Lapisan RS-232 tidak tahu apakah itu menjalankan ASCII, Reed-Solomon, Unicode (halaman kode Arab, halaman kode Jepang, halaman kode Beta Rigellian), atau apa. Ia hanya tahu bahwa ia mendapatkan urutan byte dan menulis byte tersebut ke port. Minggu depan, dia mungkin mendapatkan urutan byte yang sama sekali berbeda dari sesuatu yang sama sekali berbeda. Dia tidak peduli. Dia hanya memindahkan byte.
Penjelasan pertama (dan terbaik) dari desain berlapis adalah makalah klasik Dijkstra "Structure of the Multiprogramming System" . Diperlukan bacaan dalam bisnis ini.
sumber
Karena level yang lebih tinggi
mungkinakan berubah.Ketika itu terjadi, apakah karena perubahan persyaratan, pengguna baru, teknologi yang berbeda, aplikasi modular (yaitu berlapis secara tidak langsung) harus memerlukan lebih sedikit perawatan dan lebih mudah disesuaikan agar sesuai dengan kebutuhan baru.
sumber
Saya pikir alasan utamanya adalah membuat hal-hal menjadi lebih erat. Semakin ketat kopling, semakin besar kemungkinan mengalami masalah nanti. Lihat artikel ini info lebih lanjut: Kopling
Berikut ini kutipannya:
Dengan itu dikatakan alasan untuk memiliki sistem digabungkan lebih tinggi adalah untuk alasan kinerja. Artikel yang saya sebutkan juga memiliki beberapa informasi tentang ini juga.
sumber
IMO, ini sangat sederhana. Anda tidak dapat menggunakan kembali sesuatu yang terus merujuk konteks yang digunakan.
sumber
Layers seharusnya tidak memiliki dependensi dua arah
Keuntungan dari arsitektur berlapis adalah bahwa lapisan-lapisan tersebut harus dapat digunakan secara independen:
Kondisi ini pada dasarnya simetris . Mereka menjelaskan mengapa umumnya lebih baik hanya memiliki satu arah ketergantungan, tetapi bukan yang mana .
Arah ketergantungan harus mengikuti arahan perintah
Alasan mengapa kami lebih suka struktur ketergantungan top-down adalah karena objek atas membuat dan menggunakan objek bawah . Ketergantungan pada dasarnya adalah hubungan yang berarti "A bergantung pada B jika A tidak dapat bekerja tanpa B". Jadi, jika objek dalam A menggunakan objek dalam B, itulah cara dependensi seharusnya.
Ini agak sewenang-wenang. Dalam pola lain, seperti MVVM, kontrol mudah mengalir dari lapisan bawah. Misalnya, Anda dapat mengatur label yang teksnya terlihat terikat ke variabel dan mengubahnya. Akan tetapi, biasanya lebih baik memiliki dependensi top-down, karena objek-objek utamanya selalu yang berinteraksi dengan pengguna, dan objek-objek itu melakukan sebagian besar pekerjaan.
Sementara dari atas ke bawah kami menggunakan doa metode, dari bawah ke atas (biasanya) kami menggunakan acara. Acara memungkinkan dependensi untuk naik turun bahkan ketika kontrol mengalir sebaliknya. Objek lapisan atas berlangganan acara di lapisan bawah. Lapisan bawah tidak tahu apa-apa tentang lapisan atas, yang bertindak sebagai plug in.
Ada juga cara lain untuk mempertahankan satu arah misalnya:
sumber
Saya ingin menambahkan dua sen ke apa yang sudah dijelaskan oleh Matt Fenwick dan Kilian Foth.
Salah satu prinsip arsitektur perangkat lunak adalah bahwa program yang kompleks harus dibangun dengan menyusun blok yang lebih kecil, mandiri (kotak hitam): ini meminimalkan ketergantungan sehingga mengurangi kompleksitas. Jadi, ketergantungan searah ini adalah ide yang baik karena membuatnya lebih mudah untuk memahami perangkat lunak, dan mengelola kompleksitas adalah salah satu masalah terpenting dalam pengembangan perangkat lunak.
Jadi, dalam arsitektur berlapis, lapisan bawah adalah kotak hitam yang menerapkan lapisan abstraksi di atasnya lapisan atas dibangun. Jika lapisan bawah (katakanlah, lapisan B) dapat melihat detail lapisan atas A, maka B bukan lagi kotak hitam: detail implementasinya tergantung pada beberapa detail penggunanya sendiri, tetapi gagasan kotak hitam adalah bahwa konten (implementasinya) tidak relevan bagi penggunanya!
sumber
Hanya untuk bersenang-senang.
Pikirkan piramida pemandu sorak. Baris bawah mendukung baris di atas mereka.
Jika pemandu sorak pada baris itu melihat ke bawah, mereka stabil dan akan tetap seimbang sehingga orang-orang di atasnya tidak jatuh.
Jika dia melihat ke atas untuk melihat bagaimana semua orang di atasnya melakukan, dia akan kehilangan keseimbangan menyebabkan seluruh tumpukan jatuh.
Tidak terlalu teknis, tapi itu analogi yang saya pikir mungkin bisa membantu.
sumber
Sementara kemudahan memahami dan sampai tingkat tertentu komponen yang dapat diganti tentu saja merupakan alasan yang baik alasan yang sama pentingnya (dan mungkin alasan lapisan pertama kali ditemukan) adalah dari sudut pandang pemeliharaan perangkat lunak. Intinya adalah bahwa ketergantungan menyebabkan potensi untuk merusak sesuatu.
Misalnya, anggap A bergantung pada B. Karena tidak ada yang bergantung pada A, pengembang bebas untuk mengubah A ke isi hati mereka tanpa harus khawatir bahwa mereka dapat merusak apa pun selain A. Namun, jika pengembang ingin mengubah B maka perubahan apa pun di B yang dibuat berpotensi memecahkan A. Ini adalah masalah yang sering terjadi di awal komputer (pikirkan pengembangan terstruktur) di mana pengembang akan memperbaiki bug di satu bagian dari program dan itu akan meningkatkan bug di bagian yang tampaknya sama sekali tidak terkait dengan program di tempat lain. Semua karena ketergantungan.
Untuk melanjutkan dengan contoh, sekarang anggaplah A tergantung pada B DAN B tergantung pada A. IOW, ketergantungan melingkar. Sekarang, kapan saja perubahan dilakukan di mana saja itu berpotensi merusak modul lainnya. Perubahan dalam B masih bisa menembus A, tetapi sekarang perubahan dalam A juga bisa mematahkan B.
Jadi dalam pertanyaan awal Anda, jika Anda berada di tim kecil untuk proyek kecil maka semua ini cukup banyak karena Anda dapat dengan bebas mengubah modul sesuai keinginan Anda. Namun, jika Anda berada pada proyek yang cukup besar, jika semua modul bergantung pada yang lain maka setiap kali diperlukan perubahan itu berpotensi merusak modul lainnya. Pada proyek besar, mengetahui semua dampak mungkin sulit untuk ditentukan sehingga Anda mungkin akan kehilangan beberapa dampak.
Itu menjadi lebih buruk pada proyek besar di mana ada banyak pengembang, (misalnya beberapa yang hanya bekerja lapisan A, beberapa lapisan B dan beberapa lapisan C). Karena setiap perubahan harus ditinjau / didiskusikan dengan anggota di lapisan lain untuk memastikan perubahan Anda tidak rusak atau memaksa ulang apa yang sedang mereka kerjakan. Jika perubahan Anda memaksakan perubahan pada orang lain, maka Anda harus meyakinkan mereka bahwa mereka harus melakukan perubahan, karena mereka tidak ingin mengambil lebih banyak pekerjaan hanya karena Anda memiliki cara baru yang hebat dalam melakukan sesuatu dalam modul Anda. TKI, mimpi buruk birokrasi.
Tetapi jika Anda membatasi dependensi ke A tergantung pada B, B tergantung pada C maka hanya lapisan C orang yang perlu mengoordinasikan perubahan mereka untuk kedua tim. Lapisan B hanya perlu mengoordinasikan perubahan dengan tim Lapisan A dan tim lapisan A bebas untuk melakukan apa pun yang mereka inginkan karena kode mereka tidak memengaruhi lapisan B atau C. Jadi idealnya, Anda akan merancang lapisan Anda sehingga perubahan lapisan C sangat sedikit, lapisan B agak berubah dan lapisan A melakukan sebagian besar perubahan.
sumber
Alasan paling mendasar bahwa lapisan bawah tidak harus sadar akan lapisan yang lebih tinggi adalah bahwa ada lebih banyak jenis lapisan yang lebih tinggi. Sebagai contoh, ada ribuan dan ribuan program berbeda di sistem Linux Anda, tetapi mereka menyebut
malloc
fungsi C library yang sama . Jadi ketergantungannya adalah dari program-program ini ke perpustakaan itu.Perhatikan bahwa "lapisan bawah" sebenarnya adalah lapisan tengah.
Pikirkan aplikasi yang berkomunikasi melalui dunia luar melalui beberapa driver perangkat. Sistem operasi ada di tengah .
Sistem operasi tidak tergantung pada detail dalam aplikasi, atau dalam driver perangkat. Ada banyak jenis driver perangkat dari tipe yang sama dan mereka berbagi kerangka kerja driver perangkat yang sama. Kadang-kadang peretas kernel harus memasukkan beberapa kasus khusus ke dalam kerangka kerja demi perangkat keras atau perangkat tertentu (contoh baru-baru ini saya menemukan: kode khusus PL2303 dalam kerangka usb-serial Linux). Ketika itu terjadi, mereka biasanya memberi komentar tentang berapa banyak yang menyebalkan dan harus dihapus. Meskipun OS memanggil fungsi dalam driver, panggilan melalui kait yang membuat driver terlihat sama, sedangkan ketika driver memanggil OS, mereka sering menggunakan fungsi tertentu secara langsung berdasarkan nama.
Jadi, dalam beberapa hal, sistem operasi benar-benar lapisan yang lebih rendah dari perspektif aplikasi dan dari perspektif aplikasi: semacam hub komunikasi di mana hal-hal terhubung dan data dialihkan untuk menuju jalur yang sesuai. Ini membantu desain hub komunikasi untuk mengekspor layanan fleksibel yang dapat digunakan oleh apa saja, dan tidak memindahkan peretasan khusus perangkat atau aplikasi ke hub.
sumber
Pemisahan masalah dan pendekatan memecah / menaklukkan dapat menjadi penjelasan lain untuk pertanyaan ini. Pemisahan keprihatinan memberikan kemampuan portabilitas dan dalam beberapa arsitektur yang lebih kompleks, memberikan platform skala independen dan keuntungan kinerja.
Dalam konteks ini, jika Anda berpikir tentang archictecture 5-tier (klien, presentasi, bisnis, integrasi, dan tingkat sumber daya) tingkat arsitektur yang lebih rendah seharusnya tidak menyadari logika dan bisnis dari tingkat yang lebih tinggi dan sebaliknya. Maksud saya dengan tingkat yang lebih rendah sebagai tingkat integrasi dan sumber daya. Antarmuka integrasi basis data yang disediakan dalam integrasi dan basis data serta layanan web yang nyata (penyedia data pihak ketiga) milik tier sumber daya. Jadi misalkan Anda akan mengubah database MySQL Anda menjadi dokumen DB NoSQL seperti MangoDB dalam hal skalabilitas atau apa pun.
Dalam pendekatan ini, tingkat bisnis tidak peduli bagaimana tingkat integrasi menyediakan koneksi / transmisi oleh sumber daya. Itu hanya mencari objek akses data yang disediakan oleh tingkat integrasi. Ini dapat diperluas ke lebih banyak skenario tetapi pada dasarnya, pemisahan masalah dapat menjadi alasan nomor satu untuk ini.
sumber
Memperluas jawaban Kilian Foth, arah layering ini sesuai dengan arah di mana manusia mengeksplorasi suatu sistem.
Bayangkan Anda adalah pengembang baru yang ditugasi memperbaiki bug di sistem berlapis.
Bug biasanya ketidakcocokan antara apa yang dibutuhkan pelanggan dan apa yang ia dapatkan. Ketika pelanggan berkomunikasi dengan sistem melalui UI, dan mendapatkan hasil melalui UI (UI secara harfiah berarti 'antarmuka pengguna'), bug dilaporkan dalam hal UI juga. Jadi, sebagai pengembang, Anda tidak punya banyak pilihan selain mulai melihat UI juga, untuk mencari tahu apa yang terjadi.
Itulah mengapa diperlukan koneksi lapisan atas-bawah. Sekarang, mengapa kita tidak memiliki koneksi yang berjalan dua arah?
Nah, Anda punya tiga skenario bagaimana bug itu bisa terjadi.
Itu bisa terjadi dalam kode UI itu sendiri, dan dilokalkan di sana. Ini mudah, Anda hanya perlu menemukan tempat dan memperbaikinya.
Itu bisa terjadi di bagian lain dari sistem sebagai hasil dari panggilan yang dilakukan dari UI. Yang cukup sulit, Anda melacak pohon panggilan, menemukan tempat di mana kesalahan terjadi, dan memperbaikinya.
Dan itu bisa terjadi sebagai akibat dari panggilan KE kode UI Anda. Yang sulit, Anda harus menangkap panggilan, menemukan sumbernya, lalu mencari tahu di mana kesalahan terjadi. Mengingat titik yang Anda mulai terletak jauh di dalam cabang tunggal dari pohon panggilan, DAN Anda harus menemukan pohon panggilan yang benar terlebih dahulu, mungkin ada beberapa panggilan ke dalam kode UI, Anda memiliki debugging yang cocok untuk Anda.
Untuk menghilangkan kasus tersulit sebanyak mungkin, dependensi melingkar sangat tidak disarankan, lapisan terhubung sebagian besar dengan cara top-down. Bahkan ketika koneksi dengan cara lain diperlukan, biasanya terbatas dan didefinisikan dengan jelas. Misalnya, bahkan dengan panggilan balik, yang merupakan semacam koneksi balik, kode yang dipanggil dalam panggilan balik biasanya memberikan panggilan balik ini di tempat pertama, menerapkan semacam "keikutsertaan" untuk koneksi balik, dan membatasi dampaknya pada pemahaman suatu sistem.
Layering adalah alat, dan terutama ditujukan untuk pengembang yang mendukung sistem yang ada. Koneksi antar lapisan juga mencerminkan hal itu.
sumber
Alasan lain yang ingin saya lihat secara eksplisit disebutkan di sini adalah penggunaan kembali kode . Kami telah memiliki contoh media RS232 yang akan diganti, jadi mari selangkah lebih maju ...
Bayangkan Anda sedang mengembangkan driver. Ini pekerjaan Anda dan Anda menulis cukup banyak. Protokol mungkin mulai berulang di beberapa titik, seperti halnya media fisik.
Jadi apa yang akan Anda mulai lakukan - kecuali Anda penggemar melakukan hal yang sama berulang-ulang - adalah menulis lapisan yang dapat digunakan kembali untuk hal-hal ini.
Katakanlah Anda harus menulis 5 driver untuk perangkat Modbus. Salah satunya menggunakan Modbus TCP, dua menggunakan Modbus di RS485 dan sisanya pergi ke RS232. Anda tidak akan mengimplementasikan ulang Modbus 5 kali, karena Anda menulis 5 driver. Anda juga tidak akan mengimplementasikan ulang Modbus 3 kali, karena Anda memiliki 3 lapisan Fisik yang berbeda di bawah Anda.
Apa yang Anda lakukan adalah, Anda menulis Akses Media TCP, Akses Media RS485 dan Kemungkinan Akses Media RS232. Apakah pintar mengetahui bahwa akan ada lapisan modbus di atas, pada titik ini? Mungkin tidak. Driver berikutnya yang akan Anda implementasikan mungkin juga menggunakan Ethernet tetapi gunakan HTTP-REST. Akan memalukan jika Anda harus mengimplementasikan ulang Ethernet Media Access untuk berkomunikasi melalui HTTP.
Satu layer di atas, Anda akan mengimplementasikan Modbus sekali saja. Lapisan Modbus itu sekali lagi, tidak akan tahu driver, yaitu satu lapisan ke atas. Driver ini, tentu saja harus tahu bahwa mereka seharusnya berbicara modbus, dan mereka seharusnya tahu bahwa mereka menggunakan Ethernet. Howevever menerapkan cara saya baru saja menggambarkannya, Anda tidak bisa hanya merobek lapisan dan menggantinya. Anda tentu saja bisa - dan bagi saya itu adalah manfaat terbesar dari semuanya, silakan dan gunakan kembali lapisan Ethernet yang ada untuk sesuatu yang sama sekali tidak terkait dengan proyek yang awalnya menyebabkan penciptaannya.
Ini adalah sesuatu, kita mungkin melihat setiap hari sebagai pengembang dan itu menghemat banyak waktu. Ada banyak Perpustakaan untuk semua jenis protokol dan hal lainnya. Ini ada karena prinsip-prinsip seperti arah ketergantungan mengikuti arah perintah, yang memungkinkan kita untuk membangun lapisan perangkat lunak yang dapat digunakan kembali.
sumber