Versi PDF alamat unduhan PPT: http://www.slideshare.net/jibyjohnc/jqquerysummit-largescale-javascript-application-architecture
Catatan: Selama proses kolasi, saya menemukan bahwa pikiran penulis diulangi, jadi dia menghapus beberapa dari mereka. Jika bahasa Inggris Anda bagus, silakan baca PPT bahasa Inggris secara langsung.
Berikut ini adalah bab utama dari artikel ini:
1. Apa itu "Program JavaScript Besar"?
2. Pertimbangkan arsitektur program saat ini
3. Pertimbangan jangka panjang
4. Brainstorm
5. Arsitektur yang disarankan
5.1 Pola Desain
5.1.1 Teori Modul
5.1.1.1 Ikhtisar
5.1.1.2 Mode Modul
5.1.1.3 Ukuran wajah diri objek
5.1.1.4 Modul CommonJS
5.1.2 Mode fasad
5.1.3 Mode Mediator
5.2 berlaku untuk arsitektur Anda
5.2.1 Fasad - Abstraksi Inti
5.2.2 Mediator - Inti Program
5.2.3 Bekerja erat
6. Publikasikan Pub/Sub Ekstensi: Acara Pendaftaran Otomatis
7. T&J
8. Ucapan Terima Kasih
Apa itu "program JavaScript besar"?
Sebelum kita mulai, mari kita tentukan apa itu situs JavaScript besar. Banyak ahli pengembangan JS yang berpengalaman juga telah ditantang. Beberapa orang mengatakan bahwa lebih dari 100.000 baris kode JavaScript dianggap besar, dan beberapa orang mengatakan bahwa kode JavaScript harus berukuran lebih dari 1MB. Faktanya, tak satu pun dari mereka yang benar, karena jumlah kode tidak dapat diukur sebagai jumlah kode yang diinstal. Banyak kode JS sepele dapat dengan mudah melebihi 100.000 baris.
Definisi saya tentang "besar" adalah sebagai berikut. Meskipun mungkin tidak benar, itu harus relatif dekat:
Saya pribadi berpikir bahwa program JavaScript besar harus sangat penting dan menggabungkan banyak upaya pengembang yang luar biasa untuk memproses data kelas berat dan menampilkannya ke browser.
Tinjau arsitektur program saat ini
Saya tidak bisa menekankan betapa pentingnya masalah ini. Banyak pengembang yang berpengalaman sering mengatakan, "Pola kreatif dan desain yang ada berjalan sangat baik pada proyek menengah saya sebelumnya, jadi harus baik-baik saja untuk menggunakannya lagi dalam program yang sedikit lebih besar, kan?", Itu benar pada program tertentu, tetapi jangan lupa bahwa karena ini adalah program besar, biasanya ada kekhawatiran besar yang perlu dirinci dan memperhatikan. Saya menjelaskan secara singkat bagaimana waktu yang dibutuhkan waktu untuk meninjau arsitektur program yang telah berjalan sejak lama. Dalam kebanyakan kasus, arsitektur program JavaScript saat ini seharusnya terlihat seperti ini (perhatikan bahwa ini adalah arsitektur JS, bukan yang setiap orang sering sebut sebagai ASP.NET MVC):
widget khusus
model
tampilan
Pengontrol
template
Perpustakaan/Toolkit
inti aplikasi.
Anda juga dapat merangkum program menjadi beberapa modul saja, atau menggunakan pola desain lainnya, yang sangat bagus, tetapi jika struktur ini sepenuhnya mewakili arsitektur Anda, mungkin ada beberapa masalah potensial. Mari kita lihat beberapa poin penting:
1. Berapa banyak hal dalam arsitektur Anda yang dapat dikeluarkan dan segera digunakan kembali?
Apakah ada beberapa modul terpisah yang tidak bergantung pada kode lain? Apakah mandiri? Jika saya pergi ke basis kode yang Anda gunakan dan kemudian pilih beberapa kode modul modul dan taruh di halaman baru, dapatkah itu segera digunakan? Anda mungkin mengatakan bahwa prinsipnya baik -baik saja. Saya sarankan Anda berencana untuk waktu yang lama. Jika perusahaan Anda telah mengembangkan banyak program penting sebelumnya, tiba -tiba suatu hari seseorang mengatakan bahwa modul obrolan dalam proyek ini bagus, mari kita keluarkan dan masukkan ke dalam proyek lain. Bisakah Anda menggunakannya tanpa memodifikasi kode?
2. Berapa banyak modul yang perlu diandalkan sistem pada modul lain?
Apakah semua modul dari sistem digabungkan secara ketat? Sebelum saya mengambil pertanyaan ini sebagai perhatian, saya akan menjelaskan terlebih dahulu. Bukannya semua modul tidak boleh memiliki dependensi. Misalnya, fungsi berbutir halus dapat diperpanjang dari fungsi dasar. Masalah saya berbeda dari situasi ini. Saya berbicara tentang ketergantungan sebelum modul fungsional yang berbeda. Secara teori, semua modul fungsional yang berbeda seharusnya tidak memiliki terlalu banyak ketergantungan.
3. Jika ada yang salah dengan satu bagian dari program Anda, apakah bagian lain akan masih berfungsi?
Jika Anda membangun program yang mirip dengan Gmail, Anda dapat menemukan bahwa banyak modul di Gmail dimuat secara dinamis, seperti modul obrolan obrolan, yang tidak dimuat saat menginisialisasi halaman, dan bahkan jika kesalahan terjadi setelah memuat, bagian lain dari halaman dapat digunakan secara normal.
4. Bisakah Anda menguji modul Anda dengan cara yang sangat sederhana?
Setiap modul Anda dapat digunakan di situs besar dengan jutaan pengguna, atau bahkan beberapa situs menggunakannya, sehingga modul Anda perlu bertahan dalam tes, yaitu, baik di dalam atau di luar arsitektur, mereka harus dapat diuji dengan sangat sederhana, termasuk sebagian besar pernyataan yang dapat disahkan di lingkungan yang berbeda.
Pertimbangan jangka panjang
Saat menyusun program besar, yang paling penting adalah tampilan ke depan. Anda tidak hanya dapat mempertimbangkan situasi satu bulan atau satu tahun kemudian. Anda harus mempertimbangkan kemungkinan perubahan dalam jangka waktu yang lebih lama? Pengembang sering mengikat kode dan program operasi DOM terlalu ketat, meskipun kadang -kadang mereka telah merangkum logika terpisah ke dalam modul yang berbeda. Pikirkan mengapa itu tidak terlalu bagus dalam jangka panjang.
Seorang kolega saya pernah mengatakan bahwa arsitektur yang akurat mungkin tidak cocok untuk skenario mendatang, dan kadang -kadang itu benar, tetapi ketika Anda perlu melakukannya, Anda akan membayar banyak uang. Misalnya, Anda mungkin perlu memilih untuk mengganti dojo, jQuery, zepto, dan yui untuk kinerja, keamanan, dan alasan desain tertentu. Saat ini, ada masalah. Sebagian besar modul memiliki ketergantungan, yang membutuhkan uang, waktu, dan orang, bukan?
Tidak apa -apa untuk beberapa situs kecil, tetapi situs besar memang perlu memberikan mekanisme yang lebih fleksibel tanpa khawatir tentang berbagai masalah antara berbagai modul. Ini menghemat uang dan waktu.
Singkatnya, dapatkah Anda sekarang yakin bahwa Anda dapat mengganti beberapa perpustakaan kelas tanpa menulis ulang seluruh program? Jika tidak, maka apa yang akan kita bicarakan di bawah ini lebih cocok untuk Anda.
Banyak pengembang JavaScript yang berpengalaman telah memberikan beberapa catatan kunci:
Justin Meyer, penulis JavaScriptMVC, mengatakan:
Rahasia terbesar untuk membangun program besar adalah bahwa Anda tidak pernah membangun program besar, tetapi memecah program menjadi modul kecil untuk membuat setiap modul kecil dapat diuji, cukup besar, dan kemudian mengintegrasikannya ke dalam program.
Penulis situs web JavaScript berkinerja tinggi Nicholas, Zakas:
"Kuncinya adalah mengakui sejak awal bahwa Anda tidak tahu bagaimana ini akan tumbuh. Ketika Anda menerima bahwa Anda tidak tahu segalanya, Anda mulai merancang sistem secara defensif. Anda mengidentifikasi bidang -bidang utama yang dapat berubah, yang seringkali sangat mudah ketika Anda memasukkan sedikit waktu ke dalamnya. Misalnya, Anda harus mengharapkan bagian mana pun dari aplikasi yang berkomunikasi dengan sistem lain kemungkinan akan berubah, sehingga Anda perlu abstrak." -
Banyak masalah teks terlalu merepotkan. Singkatnya, semuanya bisa diubah, jadi harus abstrak.
Penulis Fundamental JQuery Rebecca Murphey:
Semakin dekat hubungan antara setiap modul, semakin sedikit dapat digunakan kembali, dan semakin besar kesulitan mengubahnya.
Pandangan penting di atas adalah elemen inti dari membangun arsitektur dan kita perlu mengingatnya sepanjang waktu.
Brainstorm
Ayo bertukar pikiran. Kami membutuhkan arsitektur yang digabungkan secara longgar, tanpa ketergantungan antara modul, masing -masing modul dan program berkomunikasi, dan kemudian lapisan perantara mengambil alih dan memproses pesan yang sesuai.
Misalnya, jika kami memiliki JavaScript membangun program toko roti online, modul mengirimkan pesan yang mungkin "ada 42 putaran yang perlu dikirimkan". Kami menggunakan lapisan lapisan yang berbeda untuk memproses pesan yang dikirim oleh modul, dan melakukan hal berikut:
Modul tidak secara langsung mengakses inti program
Modul tidak menelepon secara langsung atau mempengaruhi modul lain
Ini akan mencegah kita melakukan kesalahan di semua modul karena kesalahan dalam modul tertentu.
Masalah lain adalah keamanan. Situasi sebenarnya adalah bahwa kebanyakan orang tidak berpikir keamanan internal adalah masalah. Kami mengatakan dalam hati kami bahwa program -program tersebut dibangun sendiri. Saya tahu mana yang umum dan pribadi. Tidak ada masalah dengan keamanan, tetapi apakah Anda memiliki cara untuk menentukan modul mana yang akan mengakses inti program? Misalnya, ada modul obrolan obrolan yang tidak ingin saya sebut modul admin, atau saya tidak ingin itu memanggil modul dengan izin tulis DB, karena ada kerapuhan di antara mereka dan mudah untuk menyebabkan serangan XSS. Setiap modul seharusnya tidak dapat melakukan segalanya, tetapi kode JavaScript di sebagian besar arsitektur saat ini memiliki masalah ini. Berikan lapisan perantara untuk mengontrol modul mana yang dapat mengakses bagian yang diotorisasi, yaitu modul hanya dapat mencapai sebagian besar bagian yang kami wewenang.
Arsitektur yang disarankan
Fokus artikel kami adalah bahwa kali ini arsitektur yang kami usulkan menggunakan pola desain yang kami semua terkenal: modul, fasad, dan mediator.
Tidak seperti model tradisional, untuk memisahkan setiap modul, kami hanya membiarkan modul menerbitkan beberapa acara acara. Mode mediator dapat bertanggung jawab untuk berlangganan pesan pesan dari modul -modul ini, dan kemudian mengendalikan respons pemberitahuan. Pengguna mode fasad membatasi izin setiap modul.
Berikut ini adalah bagian yang perlu kita perhatikan:
1 pola desain
1.1 Teori Modul
1.1.1 Ikhtisar
1.1.2 Mode Modul
1.1.3 Ukuran wajah diri objek
1.1.4 Modul CommonJS
1.2 Mode Fasad
1.3 Mode Mediator
2 berlaku untuk arsitektur Anda
2.1 Fasad - Abstraksi Inti
2.2 Mediator - Inti Program
2.3 bekerja sama
Teori modal
Setiap orang mungkin menggunakan kode modular kurang lebih. Modul ini adalah bagian dari arsitektur program yang lengkap dan kuat. Setiap modul dibuat untuk tujuan terpisah. Kembali ke Gmail, mari kita ambil contoh. Modul obrolan obrolan tampaknya menjadi bagian yang terpisah, tetapi sebenarnya memiliki banyak submodul terpisah. Misalnya, modul ekspresi di dalam sebenarnya adalah submodule terpisah, yang juga digunakan di jendela untuk mengirim email.
Lain adalah bahwa modul dapat dimuat, dihapus dan diganti secara dinamis.
Dalam JavaScript, kami memiliki beberapa cara untuk mengimplementasikan modul. Setiap orang akrab dengan pola modul dan literal objek. Jika Anda sudah terbiasa dengan ini, abaikan bagian ini dan lompat langsung ke bagian CommonJS.
Mode modul
Pola modul adalah pola desain yang relatif populer. Ini dapat merangkum variabel pribadi, metode, dan negara bagian melalui kawat gigi. Dengan membungkus konten ini, umumnya objek global tidak dapat diakses secara langsung. Dalam pola desain ini, hanya satu API yang dikembalikan, dan semua konten lainnya dienkapsulasi sebagai pribadi.
Selain itu, pola ini mirip dengan ekspresi fungsi yang dieksekusi sendiri. Satu-satunya perbedaan adalah bahwa modul mengembalikan suatu objek, sementara ekspresi fungsi yang dieksekusi sendiri mengembalikan fungsi.
Seperti yang kita semua tahu, JavaScript tidak ingin bahasa lain memiliki pengubah akses, dan tidak dapat menyatakan pengubah pribadi dan publik untuk setiap bidang atau metode. Jadi bagaimana kita menerapkan pola ini? Yaitu mengembalikan objek, termasuk beberapa metode publik, yang memiliki kemampuan untuk memanggil objek internal.
Lihatlah kode di bawah ini. Kode ini adalah kode yang dieksekusi sendiri. Deklarasi mencakup adonmodule objek global. Array keranjang adalah pribadi, jadi seluruh program Anda tidak dapat mengakses array pribadi ini. Pada saat yang sama, kami mengembalikan objek, yang berisi 3 metode (seperti additem, getItemCount, gettotal). 3 metode ini dapat mengakses array keranjang pribadi.
var keranjangmodule = (function () {var keranjang = []; // privatereturn {// terpapar ke additem publik: function (nilai) {keranjang.push (nilai);}, getItemCount: function () {return keranjang;}, getTotal: function () {var q = this.getemcount. } return p;}}} ());Perhatikan juga bahwa objek yang kami kembalikan ditugaskan langsung ke keranjang, sehingga kami dapat menggunakannya seperti berikut:
// BasketModule adalah objek dengan properti yang juga bisa berupa MethodBasketModule.additem ({item: 'Bread', Harga: 0.5}); BasketModule.additem ({item: 'Butter', Harga: 0.3}); Console.log (Bas SumberModule.GetItemCount ()); Console.log (Bas SumberModule.getTotal ()); // Namun, berikut ini tidak akan berfungsi: console.log (keranjangmodule.basket); // (tidak terdefinisi karena tidak di dalam objek yang dikembalikan) konsol.log (keranjang); // (hanya ada dalam lingkup penutupan)Jadi bagaimana melakukannya di berbagai perpustakaan kelas populer (seperti dojo, jQuery)?
Dojo
Dojo mencoba menggunakan dojo.declare untuk memberikan metode deklarasi gaya kelas. Kami dapat menggunakannya untuk mengimplementasikan pola modul. Misalnya, jika Anda ingin mendeklarasikan objek keranjang di bawah namespace toko, Anda dapat melakukan ini:
// toko wayvar tradisional = window.store || {}; store.basket = store.basket || {}; // Menggunakan dojo.setObjectdo.setObject ("store.basket.object", (function () {var keranjang = []; function privateMethod () {console.log (keranjang);} return {publicmethod: function () {privateMethod ();}};} ());Ini sangat kuat ketika dikombinasikan dengan dojo.provide.
Yui
Kode berikut adalah implementasi asli YUI:
Yahoo.store.basket = function () {// "private" variabel: var myprivatevar = "Saya hanya dapat diakses di dalam Yahoo.store.basket."; // metode "pribadi": var myprivatemethod = function () {yahoo.log ("Saya hanya dapat diakses dari dalam yahoo.store.basket"); } return {myPublicProperty: "Saya properti publik.", MyPublicMethod: function () {yahoo.log ("Saya metode publik."); // dalam keranjang, saya dapat mengakses "pribadi" VAR dan metode: Yahoo.log (myprivateVar); Yahoo.log (myprivatemethod ()); // Ruang lingkup asli MyPublicMethod adalah toko sehingga kami dapat // mengakses anggota publik menggunakan "this": yahoo.log (this.mypublicproperty); }};} ();jQuery
Ada banyak implementasi pola modul di jQuery. Mari kita lihat contoh yang berbeda. Fungsi perpustakaan mendeklarasikan perpustakaan baru. Kemudian saat membuat pustaka, metode init secara otomatis dieksekusi di Document.eady.
function library (module) {$ (function () {if (module.init) {module.init ();}}); return module;} var mylibrary = library (function () {return {init: function () { /*implementasi* /}};} ());Ukuran wajah diri objek
Pengukuran wajah-wajah objek dinyatakan dalam kawat gigi, dan kata kunci baru tidak diperlukan saat menggunakannya. Jika Anda tidak terlalu peduli dengan publik/pribadi bidang atribut dalam modul, Anda dapat menggunakan metode ini, tetapi harap dicatat bahwa metode ini berbeda dari JSON. Object Self-Face Ukuran: var item = {name: "tom", value: 123} json: var item = {"name": "tom", "value": 123}.
var mymodule = {myproperty: 'somevalue', // objek literal dapat berisi properti dan metode. // Di sini, objek lain didefinisikan untuk konfigurasi // tujuan: myconfig: {usecaching: true, bahasa: 'en'}, // metode yang sangat mendasar mymethod: function () {console.log ('i can haz functionality?'); }, // output nilai berdasarkan konfigurasi saat ini mymethod2: function () {console.log ('caching adalah:' + (this.myconfig.usecaching)? 'Diaktifkan': 'dinonaktifkan'); }, // angkanya konfigurasi mymethod3: function saat ini (newonfig) {if (typeof newonfig == 'objek') {this.myconfig = newonfig; console.log (this.myconfig.ibuage); }}}; mymodule.mymethod (); // I Can Haz FunctionalityMyModule.mymethod2 (); // output enabledmymodule.mymethod3 ({bahasa: 'fr', usecaching: false}); // frCommonjs
Saya tidak akan berbicara tentang pengenalan CommonJs di sini. Banyak artikel telah memperkenalkannya sebelumnya. Yang ingin kami sebutkan di sini adalah bahwa ada dua ekspor parameter penting dan dibutuhkan dalam standar CommonJS. Ekspor mewakili modul yang akan dimuat, dan membutuhkan berarti bahwa modul yang dimuat ini perlu mengandalkan modul lain dan juga perlu dimuat.
/*Contoh pencapaian kompatibilitas dengan AMD dan standar umum dengan menempatkan boilerplate di sekitar format modul CommonJS standar:*/(function (define) {define (function (wajib, ekspor) {// modul konten var dep1 = membutuhkan ("dep1"); ekspor. define == "function"? Define: function (factory) {factory (membutuhkan, ekspor)});Ada banyak implementasi pemuatan modul standar CommonJS. Yang saya sukai adalah persyaratan. Bisakah memuat modul dan modul ketergantungan terkait dengan sangat baik? Mari kita ambil contoh sederhana. Misalnya, jika Anda perlu mengonversi gambar menjadi kode ASCII, pertama -tama kami memuat modul encoder, dan kemudian mendapatkan metode encodetoascii. Secara teoritis, kode harus sebagai berikut:
var encodetoascii = membutuhkan ("encoder"). Encodetoascii; exports.encodesomesource = function () {// Setelah operasi lain, lalu hubungi encodeToASCII}Namun, kode di atas tidak berfungsi, karena fungsi encodeToASCII tidak digunakan untuk melekat pada objek jendela, sehingga tidak dapat digunakan. Inilah yang perlu dilakukan oleh peningkatan kode:
Define (function (membutuhkan, ekspor, modul) {var encodetoascii = membutuhkan ("encoder"). encodetoascii; exports.encodesomesource = function () {// proses kemudian hubungi encodetoascii}});CommonJS memiliki potensi besar, tetapi karena pamannya tidak terlalu terbiasa dengan itu, saya tidak akan memperkenalkannya.
Mode fasad
Model fasad menempati peran penting dalam arsitektur model ini. Banyak perpustakaan atau kerangka kerja kelas JavaScript tercermin dalam model ini. Fungsi terbesar adalah memasukkan API tingkat tinggi untuk menyembunyikan implementasi tertentu. Ini berarti bahwa kami hanya mengekspos antarmuka, dan kami dapat membuat keputusan implementasi internal sendiri, yang juga berarti bahwa kode implementasi internal dapat dengan mudah dimodifikasi dan diperbarui. Misalnya, hari ini Anda menggunakan jQuery untuk mengimplementasikannya, dan besok Anda ingin mengubah Yui, yang sangat nyaman.
Dalam contoh berikut, kita dapat melihat bahwa kita menyediakan banyak metode pribadi, dan kemudian mengekspos API sederhana untuk memungkinkan dunia luar untuk mengeksekusi dan memanggil metode internal:
var module = (function () { var _private = { i: 5, get: function () { console.log('current value:' + this.i); }, set: function (val) { this.i = val; }, run: function () { console.log('running'); }, jump: function () { console.log('jumping'); } }; return { facade: function (args) {_private.set (args.val);Perbedaan antara fasad dan apa yang kita bicarakan di bawah ini adalah bahwa fasad hanya menyediakan fungsi yang ada, sementara mediator dapat menambahkan fungsi baru.
Mode mediator
Sebelum berbicara tentang Modiator, mari kita beri contoh. Sistem kontrol penerbangan bandara, yang merupakan menara legendaris, memiliki kekuatan mutlak. Ini dapat mengendalikan lepas landas dan waktu pendaratan dan tempat pesawat apa pun. Pesawat dan pesawat tidak diperbolehkan berkomunikasi sebelumnya, yang berarti menara adalah inti dari bandara, dan mediator setara dengan menara ini.
Mediator digunakan untuk memiliki beberapa modul dalam suatu program dan Anda tidak ingin setiap modul memiliki dependensi, maka mode mediator dapat mencapai tujuan kontrol terpusat. Dalam skenario yang sebenarnya, mediator merangkum banyak modul yang tidak ingin mereka lakukan, memungkinkan mereka untuk dihubungkan melalui mediator, dan juga secara longgar menggabungkannya, sehingga mereka harus berkomunikasi melalui mediator.
Jadi apa keuntungan dari mode mediator? Itu adalah decoupling. Jika Anda memiliki pemahaman yang baik tentang pola pengamat sebelumnya, akan relatif mudah untuk memahami diagram mediator di bawah ini. Gambar berikut adalah diagram pola mediator tingkat tinggi:
Pikirkan tentang hal ini, setiap modul adalah penerbit, dan mediator adalah penerbit dan pelanggan.
Modul 1 menyiarkan hal yang sebenarnya untuk mediator, mengatakan sesuatu perlu dilakukan
Setelah mediator menangkap pesan, segera mulai modul 2 yang perlu digunakan untuk memproses pesan. Setelah pemrosesan Modul 2 selesai, kembalikan informasi ke mediator.
Pada saat yang sama, mediator juga memulai Modul 3, dan secara otomatis masuk ke Modul 3 saat menerima pesan pengembalian modul 2.
Dapat dilihat bahwa tidak ada komunikasi antara modul. Selain itu, mediator juga dapat menerapkan fungsi pemantauan status setiap modul. Misalnya, jika ada kesalahan dalam Modul 3, mediator untuk sementara hanya menginginkan modul lain, maka restart Modul 3, lalu terus jalankan.
Melihat ke belakang, kita dapat melihat bahwa keuntungan mediator adalah bahwa modul yang digabungkan secara longgar dikendalikan oleh mediator yang sama. Modul hanya perlu menyiarkan dan mendengarkan acara, dan tidak perlu untuk koneksi langsung antar modul. Selain itu, beberapa modul dapat digunakan untuk memproses informasi pada satu waktu, yang juga memfasilitasi kita untuk menambahkan modul baru ke logika kontrol yang ada di masa depan.
Sudah pasti bahwa karena semua modul tidak dapat berkomunikasi secara langsung, mungkin ada sedikit penurunan kinerja di semua yang relatif, tetapi saya pikir itu sepadan.
Mari kita gunakan demo sederhana berdasarkan penjelasan di atas:
var mediator = (function () {var Subscribe = function (channel, fn) {if (! mediator.channels [channel]) mediator.channels [channel] = []; mediator.channels [channel] .push ({context: callback: fn}); return this;}, publish = function ({context = callback: fn}); return this;}, publish = function (channel) {ifs = moadiator. Array.prototype.slice.call (argumen, 1); Berlangganan: Berlangganan, Installto: Function (OBJ) {OBJ.Subscribe = Berlangganan;Lalu ada 2 modul yang disebut:
// pub/sub pada mediator mediator terpusat.name = "tim"; mediator.subscribe ('namechange', function (arg) {console.log (this.name); this.name = arg; console.log (this.name);}); mediator.publish ('namechange', 'david'); // Tim, David // pub/sub via mediator pihak ketiga var obj = {name: 'sam'}; mediator.installto (obj); obj.subscribe ('namechange', function (arg) {console.log (this.name); this.name = arg; console.log (this.name); obj.publish ('namechange', 'John'); // Sam, JohnFasad Aplikasi: Abstraksi Inti Aplikasi
Fasad berfungsi sebagai abstrak dari inti aplikasi, dan bertanggung jawab untuk komunikasi antara mediator dan modul. Setiap modul hanya dapat berkomunikasi dengan inti program melalui fasad ini. Tanggung jawab sebagai abstrak adalah untuk memastikan bahwa modul -modul ini dapat disediakan dengan antarmuka yang konsisten kapan saja, yang mirip dengan peran pengontrol SendBox. Semua komponen modul berkomunikasi dengan mediator melalui itu, jadi fasad harus dapat diandalkan dan dapat dipercaya. Pada saat yang sama, sebagai fungsi untuk menyediakan antarmuka ke modul, fasad perlu memainkan peran lain, yaitu, kontrol keamanan, yaitu untuk menentukan bagian mana dari program yang dapat diakses oleh modul. Komponen modul hanya dapat memanggil metode mereka sendiri dan tidak dapat mengakses konten yang tidak sah. Misalnya, modul dapat menyiarkan dataValidationCompletedWriteToDB, di mana pemeriksaan keamanan perlu memastikan bahwa modul memiliki izin menulis ke database.
Singkatnya, mediator hanya dapat melakukan pemrosesan informasi setelah deteksi otorisasi fasad.
Mediator Aplikasi: Inti dari Aplikasi
Mediator berfungsi sebagai peran inti untuk aplikasi ini, mari kita bicarakan secara singkat tentang tanggung jawabnya. Pekerjaan paling inti adalah mengelola siklus hidup modul. Ketika inti ini menangkap informasi apa pun, ia perlu menilai bagaimana program menanganinya - yaitu, untuk memutuskan modul mana yang akan dimulai atau berhenti. Ketika suatu modul dimulai, ia harus dapat dieksekusi secara otomatis, tanpa inti aplikasi untuk memutuskan apakah harus dieksekusi (misalnya, apakah harus dieksekusi ketika DOM siap), sehingga modul itu sendiri perlu menentukan.
Anda mungkin memiliki pertanyaan, dalam keadaan apa modul akan berhenti? Ketika program mendeteksi bahwa suatu modul gagal atau membuat kesalahan, program perlu membuat keputusan untuk mencegah metode dalam modul dari terus mengeksekusi sehingga komponen dapat dimulai kembali, dengan tujuan utama meningkatkan pengalaman pengguna.
Selain itu, inti harus dapat secara dinamis menambahkan atau menghapus modul tanpa mempengaruhi fungsi lain. Contoh umum adalah bahwa modul tidak tersedia pada awal pemuatan halaman, tetapi setelah pengguna beroperasi, ia perlu memuat modul secara dinamis dan kemudian menjalankannya. Sama seperti fungsi obrolan di Gmail, harus mudah dimengerti dari tujuan optimasi kinerja.
Penanganan kesalahan pengecualian juga ditangani oleh inti aplikasi. Selain itu, ketika setiap modul menyiarkan informasi, ia juga menyiarkan kesalahan apa pun ke inti sehingga inti program dapat menghentikan/memulai kembali modul -modul ini sesuai dengan situasinya. Ini juga merupakan bagian yang sangat penting dari arsitektur yang digabungkan secara longgar. Kami tidak perlu mengubah modul apa pun secara manual. Kami dapat melakukan ini dengan menggunakan publikasi/berlangganan melalui mediator.
Berkumpul
Setiap modul berisi berbagai fungsi dalam program. Ketika mereka memiliki informasi yang akan diproses, mereka mengeluarkan informasi yang memberi tahu program (ini adalah tanggung jawab utama mereka). Bagian QA berikut menyebutkan bahwa modul dapat mengandalkan beberapa metode operasi alat DOM, tetapi mereka tidak boleh bergantung pada modul lain dari sistem. Modul tidak boleh memperhatikan konten berikut:
1. Objek atau modul mana yang berlangganan informasi yang diterbitkan oleh modul ini
2. Apakah objek ini klien atau objek sisi server
3. Berapa banyak objek yang berlangganan informasi Anda
Inti dari aplikasi abstraksi fasad menghindari komunikasi langsung antar modul. Ini berlangganan informasi dari setiap modul dan juga bertanggung jawab untuk deteksi otorisasi, memastikan bahwa setiap modul memiliki otorisasi terpisah sendiri.
Mediator (Application Core) menggunakan mode mediator untuk memainkan peran sebagai manajer penerbitan/berlangganan, bertanggung jawab untuk manajemen modul dan eksekusi modul start/stop, dan dapat secara dinamis memuat dan memulai kembali modul dengan kesalahan.
Hasil dari arsitektur ini adalah bahwa tidak ada ketergantungan antar modul, karena aplikasi yang digabungkan secara longgar, mereka dapat dengan mudah diuji dan dipelihara, setiap modul dapat dengan mudah digunakan kembali dalam proyek lain, atau dapat ditambahkan dan dihapus secara dinamis tanpa mempengaruhi program.
Publikasikan Pub/Sub Ekstensi: Pendaftaran Acara Otomatis
Mengenai pendaftaran acara secara otomatis, spesifikasi penamaan tertentu perlu diikuti. Misalnya, jika sebuah modul menerbitkan acara bernama MessageUpdate, maka semua modul dengan metode MessageUpdate akan dieksekusi secara otomatis. Ada manfaat dan kelebihan dan kerugian. Untuk metode implementasi tertentu, Anda dapat melihat posting lain dari saya: versi ajaib yang ditingkatkan dari jQuery Custom Binding.
Qa
1. Apakah mungkin untuk tidak menggunakan fasad atau mode kotak pasir serupa?
Meskipun garis besar arsitektur mengusulkan bahwa fasad dapat menerapkan fungsi pemeriksaan otorisasi, sebenarnya sangat mungkin bahwa mediator dapat melakukannya. Apa yang perlu dilakukan arsitektur cahaya hampir sama, yaitu, memisahkan dan memastikan bahwa setiap modul secara langsung berkomunikasi dengan inti dari aplikasi ini baik -baik saja.
2. Anda telah meningkatkan bahwa modul tidak dapat secara langsung bergantung. Apakah itu berarti bahwa itu tidak dapat bergantung pada perpustakaan pihak ketiga mana pun (seperti jQuery).
Ini sebenarnya masalah dua sisi. Seperti yang kami sebutkan di atas, modul mungkin memiliki beberapa submodul, atau modul dasar, seperti kelas alat operasi DOM dasar, dll. Pada level ini, kami dapat menggunakan perpustakaan pihak ketiga, tetapi pastikan bahwa kami dapat dengan mudah menggantinya.
3. Saya suka arsitektur ini dan ingin mulai menggunakan arsitektur ini. Apakah ada sampel kode yang dapat digunakan untuk merujuk?
Saya berencana untuk membuat sampel kode untuk referensi Anda, tetapi sebelum itu, Anda dapat merujuk ke javaScript Modular Penulisan Andrew Burgees.
4. Apakah layak jika modul perlu berkomunikasi secara langsung dengan inti aplikasi?
Secara teknis, tidak ada alasan mengapa modul tidak dapat berkomunikasi secara langsung dengan inti aplikasi sekarang, tetapi untuk sebagian besar pengalaman aplikasi, itu masih belum diizinkan. Karena Anda telah memilih arsitektur ini, Anda harus mematuhi aturan yang ditentukan oleh arsitektur.
Ucapan Terima Kasih
Terima kasih kepada Nicholas Zakas untuk posting aslinya, untuk merangkum ide -ide bersama, kepada Andree Hansson untuk tinjauan teknis, kepada Rebecca Murphey, Justin Meyer, John Hann, Peter Michaux, Paul Irish dan Alex Sexton, semuanya memberikan banyak informasi yang berkaitan dengan sesi ini.