Bab 06: Contoh Aplikasi
Coding Deklaratif
Kita akan mengubah pola pikir kita.
Mulai sekarang, kita akan berhenti memberi tahu komputer bagaimana melakukan tugasnya dan sebagai gantinya menulis spesifikasi apa yang kita inginkan sebagai hasilnya.
Saya yakin Anda akan merasa jauh lebih sedikit stres daripada mencoba mengatur semuanya secara mikro setiap saat.
Deklaratif, sebagai lawan dari imperatif, berarti kita akan menulis ekspresi, sebagai lawan dari instruksi langkah demi langkah.
Pikirkan SQL. Tidak ada istilah "pertama lakukan ini, lalu lakukan itu".
Ada satu ekspresi yang menentukan apa yang kita inginkan dari database. Kami tidak memutuskan bagaimana melakukan pekerjaan, itu yang terjadi.
Ketika database ditingkatkan dan mesin SQL dioptimalkan, kita tidak perlu mengubah kueri kita. Ini karena ada banyak cara untuk menginterpretasikan spesifikasi kami dan mencapai hasil yang sama.
Untuk beberapa orang, termasuk saya sendiri, sulit untuk memahami konsep pengkodean deklaratif pada awalnya, jadi mari tunjukkan beberapa contoh untuk merasakannya.
Loop imperatif pertama-tama harus membuat instance array. Interpreter harus mengevaluasi statement ini sebelum melanjutkan.
Kemudian secara langsung beralih melalui daftar mobil, secara manual meningkatkan penghitung dan menunjukkan potongan-potongannya kepada kami dalam tampilan vulgar dari iterasi eksplisit.
Versi map
adalah salah satu ekspresi. Itu tidak memerlukan urutan evaluasi.
Ada banyak kebebasan di sini untuk bagaimana fungsi map
berulang dan bagaimana array yang dikembalikan dapat dirakit.
Ini menentukan "apa", bukan "bagaimana". Dengan demikian, ia memakai selempang deklaratif yang mengkilap.
Selain lebih jelas dan ringkas, fungsi map
dapat dioptimalkan sesuka hati dan kode aplikasi kita yang berharga tidak perlu diubah.
Bagi Anda yang berpikir "Ya, tetapi jauh lebih cepat untuk melakukan loop imperatif", saya sarankan Anda mendidik diri sendiri tentang bagaimana JIT mengoptimalkan kode Anda. Inilah video hebat yang mungkin bisa memberi pencerahan
Berikut adalah contoh lain.
Meskipun tidak ada yang salah dengan versi imperatif, masih ada evaluasi langkah demi langkah yang dikodekan.
Ekspresi compose
hanya menyatakan fakta: Otentikasi adalah komposisi toUser
dan logIn
.
Sekali lagi, ini meninggalkan ruang gerak untuk perubahan kode dukungan dan menghasilkan kode aplikasi kita menjadi spesifikasi tingkat tinggi.
Dalam contoh di atas, urutan evaluasi ditentukan (toUser
harus dipanggil sebelum logIn
).
Tetapi ada banyak skenario di mana urutannya tidak penting, dan ini mudah ditentukan dengan pengkodean deklaratif (lebih lanjut tentang ini nanti).
Karena kita tidak harus mengkodekan urutan evaluasi, pengkodean deklaratif cocok untuk komputasi paralel.
Ini ditambah dengan fungsi murni adalah mengapa FP (Functional Programming) adalah pilihan yang baik untuk masa depan paralel - kami tidak benar-benar perlu melakukan sesuatu yang istimewa untuk mencapai sistem paralel/bersamaan.
Flickr dari Pemrograman Fungsional
Sekarang kita akan membangun sebuah contoh aplikasi Flickr dengan cara yang deklaratif dan dapat dikomposisi.
Kami masih akan menipu dan menggunakan efek samping untuk saat ini, tetapi kami akan membuatnya minimal dan terpisah dari basis kode murni kami.
Kita akan membuat widget browser yang menyedot gambar flickr dan menampilkannya. Mari kita mulai dengan membuat perancah aplikasi.
Berikut html-nya:
Dan inilah kerangka main.js:
Kami menggunakan rambda alih-alih lodash atau perpustakaan utilitas lainnya.
Ini memiliki compose
, curry
, dan banyak lagi.
Saya telah menggunakan requirejs, yang mungkin tampak berlebihan, tetapi kami akan menggunakannya di seluruh buku dan konsistensi adalah kuncinya.
Sekarang itu keluar dari jalan, ke spesifikasi. Aplikasi kami akan melakukan 4 hal.
Buat url untuk istilah pencarian khusus kami.
Lakukan panggilan API Flickr.
Ubah json yang dihasilkan menjadi gambar html.
Tempatkan di layar.
Ada 2 perbuatan impure (tidak murni) yang disebutkan di atas. Apakah kamu melihat mereka? Sedikit tentang mendapatkan data dari api flickr dan menempatkannya di layar.
Mari kita definisikan terlebih dahulu sehingga kita dapat mengkarantina mereka. Juga, saya akan menambahkan fungsi trace
untuk memudahkan debugging.
Di sini kami hanya membungkus method jQuery untuk menjadi kari dan kami telah menukar argumen ke posisi yang lebih menguntungkan.
Saya telah memberi mereka namespace Impure
sehingga kami tahu ini adalah fungsi yang berbahaya. Dalam contoh yang akan datang, kita akan membuat kedua fungsi ini murni.
Selanjutnya kita harus membuat url untuk diteruskan ke fungsi Impure.getJSON
.
Ada cara yang bagus dan terlalu rumit untuk menulis url
pointfree menggunakan monoid (kita akan mempelajarinya nanti) atau kombinator.
Kami telah memilih untuk tetap menggunakan versi yang dapat dibaca dan merakit string ini dengan cara yang normal.
Mari kita tulis fungsi aplikasi yang membuat panggilan dan menempatkan konten di layar.
Ini memanggil fungsi url
kita, lalu meneruskan string ke fungsi getJSON
, yang sebagian telah diterapkan dengan trace
. Memuat aplikasi akan menampilkan respons dari panggilan api di konsol.
Kami ingin membuat gambar dari json ini. Sepertinya mediaUrls
tertimbun di items
termasuk properti masing media
, m
.
Bagaimanapun, untuk mendapatkan properti bersarang ini kita dapat menggunakan fungsi pengambil universal yang bagus dari ramda yang disebut prop.
Ini adalah versi buatan sendiri agar Anda dapat melihat apa yang terjadi:
Sebenarnya ini cukup membosankan. Kami hanya menggunakan sintaks []
untuk mengakses properti pada objek apa pun.
Mari kita gunakan ini untuk mendapatkan mediaUrls
.
Setelah kami mengumpulkan items
, kami harus map
untuk mengekstrak setiap url media. Ini menghasilkan array yang bagus dari mediaUrls
.
Mari kita kaitkan ini ke aplikasi kita dan mencetaknya di layar.
Yang telah kita lakukan adalah membuat komposisi baru yang akan memanggil mediaUrls
dan mengatur <main>
html dengan mereka.
Kami telah mengganti panggilan trace
dengan render
sekarang karena kami memiliki sesuatu yang perlu dirender selain JSON mentah. Ini secara kasar akan menampilkan mediaUrls
di dalam body.
Langkah terakhir kami adalah mengubahnya mediaUrls
menjadi bonafid images.
Dalam aplikasi yang lebih besar, kami akan menggunakan perpustakaan template/dom seperti Handlebars atau React. Untuk aplikasi ini, kita hanya membutuhkan tag img jadi mari kita tetap menggunakan jQuery.
Method html
jQuery akan menerima tag array. Kita hanya perlu mengubah mediaUrls
kita menjadi gambar dan mengirimkannya ke setHtml
.
Dan kita sudah selesai!
Ini skrip yang sudah jadi: exercises/ch06/main.js
Sekarang lihat itu. Spesifikasi deklaratif yang indah tentang apa adanya, bukan bagaimana hal itu terjadi.
Kami sekarang melihat setiap baris sebagai persamaan dengan sifat-sifat yang berlaku. Kita dapat menggunakan properti ini untuk alasan tentang aplikasi dan refactor kita.
Refactor Berprinsip
Ada pengoptimalan yang tersedia - kami memetakan setiap item untuk mengubahnya menjadi url media, lalu kami memetakan lagi di atas mediaUrls tersebut untuk mengubahnya menjadi tag img.
Ada hukum tentang map dan komposisi:
Kita dapat menggunakan properti ini untuk mengoptimalkan kode kita. Mari kita gunakan refactor berprinsip.
Mari kita sebariskan peta kita. Kita bisa sebariskan panggilan untuk mediaUrls
di images
berkat penalaran equational dan kemurnian.
Sekarang kita telah menyusun map
kita, kita dapat menerapkan hukum komposisi.
Sekarang bugger hanya akan mengulang sekali sambil mengubah setiap item menjadi img. Mari kita membuatnya sedikit lebih mudah dibaca dengan mengekstrak fungsinya.
In Summary
Kami telah melihat bagaimana menggunakan keterampilan baru kami dengan aplikasi kecil tapi nyata.
Kami telah menggunakan kerangka matematika kami untuk alasan dan refactor kode kami.
Tapi bagaimana dengan error handling dan percabangan? Bagaimana kita bisa membuat seluruh aplikasi murni alih-alih hanya memberi nama pada fungsi destruktif?
Bagaimana kita bisa membuat aplikasi kita lebih aman dan lebih ekspresif?
Ini adalah pertanyaan yang akan kita tangani di bab 2.
Last updated