Saya ingin bertanya - Saya perlahan belajar jQuery.
Apa yang saya lihat adalah contoh tepat dari anti-pola Objek Allah . Pada dasarnya, semuanya berjalan ke $
fungsi, apa pun itu.
Apakah saya benar dan apakah jQuery benar-benar contoh dari pola-anti ini?
jquery
anti-patterns
Karel Bílek
sumber
sumber
$
fungsi ataujQuery
objek.Jawaban:
Untuk menjawab pertanyaan itu, saya akan mengajukan pertanyaan retoris tentang struktur lain yang memiliki properti serupa dengan elemen DOM yang dimanipulasi jQuery, yaitu iterator tua yang baik. Pertanyaannya adalah:
Berapa banyak operasi yang Anda butuhkan pada iterator sederhana?
Pertanyaannya dapat dijawab dengan mudah dengan melihat API Iterator dalam bahasa tertentu. Anda memerlukan 3 metode:
Itu yang kamu butuhkan. Jika Anda dapat melakukan 3 operasi tersebut, Anda dapat melewati urutan elemen apa pun.
Tapi bukan hanya itu yang biasanya ingin Anda lakukan dengan urutan elemen, bukan? Anda biasanya memiliki tujuan tingkat yang jauh lebih tinggi untuk dicapai. Anda mungkin ingin melakukan sesuatu dengan setiap elemen, Anda mungkin ingin memfilternya berdasarkan kondisi tertentu, atau salah satu dari beberapa metode lain. Lihat antarmuka IEnumerable di pustaka LINQ di .NET untuk contoh lebih lanjut.
Apakah Anda melihat ada berapa? Dan itu hanya sebagian dari semua metode yang dapat mereka gunakan pada antarmuka IEnumerable, karena Anda biasanya menggabungkannya untuk mencapai tujuan yang lebih tinggi.
Tapi di sini ada twist. Metode-metode itu tidak ada pada antarmuka IEnumerable. Mereka adalah metode utilitas sederhana yang benar-benar mengambil IEnumerable sebagai input dan melakukan sesuatu dengannya. Jadi sementara dalam bahasa C # rasanya seperti ada metode bajillion pada antarmuka IEnumerable, IEnumerable bukan objek dewa.
Sekarang kembali ke jQuery. Mari kita ajukan pertanyaan itu lagi, kali ini dengan elemen DOM.
Berapa banyak operasi yang Anda butuhkan pada elemen DOM?
Sekali lagi jawabannya cukup mudah. Semua metode yang Anda butuhkan adalah metode untuk membaca / memodifikasi atribut dan elemen turunan. Itu saja. Yang lainnya hanyalah kombinasi dari operasi dasar itu.
Tetapi seberapa banyak hal tingkat yang lebih tinggi yang ingin Anda lakukan dengan elemen DOM? Yah, sama seperti Iterator: satu bajillion hal yang berbeda. Dan di situlah jQuery masuk. JQuery, pada dasarnya menyediakan dua hal:
Jika Anda mengeluarkan formulir bergula, Anda menyadari bahwa jQuery dapat dengan mudah ditulis sebagai sekelompok fungsi yang memilih / memodifikasi elemen DOM. Sebagai contoh:
... bisa ditulis sebagai:
Semantik itu hal yang persis sama. Namun bentuk pertama memiliki keuntungan besar bahwa urutan kiri-ke-kanan dari pernyataan mengikuti urutan operasi akan dieksekusi. Mulai kedua di tengah, yang membuat kode sangat sulit dibaca jika Anda menggabungkan banyak operasi bersama.
Jadi, apa artinya semua itu? JQuery itu (seperti LINQ) bukan anti-pola objek Allah. Ini bukan kasus pola yang sangat dihormati yang disebut Dekorator .
Tetapi sekali lagi, bagaimana dengan menimpa
$
untuk melakukan semua hal yang berbeda itu? Ya, itu benar-benar gula sintaksis. Semua panggilan$
dan turunannya suka$.getJson()
adalah hal-hal yang benar-benar berbeda yang kebetulan berbagi nama yang sama sehingga Anda dapat segera merasa bahwa mereka milik jQuery.$
melakukan satu dan hanya satu tugas: biarkan Anda memiliki titik awal yang mudah dikenali untuk menggunakan jQuery. Dan semua metode yang dapat Anda panggil pada objek jQuery bukan merupakan gejala objek dewa. Mereka hanya fungsi utilitas yang berbeda yang masing-masing melakukan satu-satunya hal pada elemen DOM yang dilewatkan sebagai argumen. Notasi .dot hanya ada di sini karena membuat penulisan kode lebih mudah.sumber
Tidak -
$
fungsi ini sebenarnya hanya kelebihan beban untuk tiga tugas . Yang lainnya adalah fungsi anak yang hanya menggunakannya sebagai namespace .sumber
Math
. Karena tidak ada built-in namespace di JS, mereka hanya menggunakan objek untuk itu. Meskipun saya tidak yakin apa alternatifnya? Taruh semua fungsi dan properti di namespace global?Fungsi jQuery utama (misalnya
$("div a")
) pada dasarnya adalah metode pabrik yang mengembalikan instance dari tipe jQuery yang mewakili kumpulan elemen DOM.Ini contoh dari jenis jQuery memiliki sejumlah besar metode manipulasi DOM tersedia yang beroperasi pada elemen DOM diwakili oleh instance. Meskipun ini bisa dianggap sebagai kelas yang tumbuh terlalu besar, itu tidak benar-benar cocok dengan pola Obyek Dewa.
Akhirnya, seperti yang disebutkan Michael Borgwardt, ada juga sejumlah besar fungsi utilitas yang menggunakan $ sebagai namespace dan hanya secara tangensial terkait dengan objek koleksi jOM DOM.
sumber
$
bukan objek, ini namespace.Apakah Anda memanggil java.lang objek dewa karena banyak kelas yang dikandungnya? Ini sintaks yang benar-benar valid untuk dipanggil
java.lang.String.format(...)
, sangat mirip dalam bentuk memanggil apa pun di jQuery.Suatu objek, untuk menjadi objek dewa, harus menjadi objek yang tepat di tempat pertama - berisi data dan kecerdasan untuk bertindak berdasarkan data. jQuery hanya berisi metode.
Cara lain untuk melihatnya: ukuran yang baik untuk berapa banyak objek dewa objek adalah kohesi - kohesi yang lebih rendah berarti lebih banyak objek dewa. Kohesi mengatakan karena banyak data yang digunakan oleh berapa banyak metode. Karena tidak ada data di jQuery, Anda melakukan matematika - semua metode menggunakan semua data, jadi jQuery sangat kohesif, sehingga tidak menjadi objek dewa.
sumber
Benjamin meminta saya untuk mengklarifikasi posisi saya, jadi saya mengedit posting saya sebelumnya dan menambahkan pemikiran lebih lanjut.
Bob Martin adalah penulis buku hebat berjudul Clean Code. Dalam buku itu ada bab (Bab 6.) yang disebut Objects and struktur Data, yang ia membahas perbedaan paling penting antara objek dan struktur data dan klaim bahwa kita harus memilih di antara mereka, karena mencampurkannya adalah ide yang sangat buruk.
Saya pikir DOM adalah contoh dari hibrida objek dan struktur data ini. Sebagai contoh oleh DOM kami menulis kode seperti ini:
DOM harus jelas merupakan struktur data, bukan hibrid.
Kerangka kerja jQuery adalah sekelompok prosedur, yang dapat memilih dan memodifikasi kumpulan node DOM dan melakukan banyak hal lainnya. Seperti yang ditunjukkan Laurent dalam posnya, jQuery adalah sesuatu seperti ini di bawah tenda:
Pengembang jQuery menggabungkan semua prosedur ini ke dalam satu kelas, yang bertanggung jawab untuk semua fitur yang tercantum di atas. Jadi jelas melanggar Prinsip Tanggung Jawab Tunggal dan jadi itu adalah objek dewa. Satu-satunya hal karena tidak merusak apa pun, karena itu adalah kelas mandiri tunggal yang bekerja pada struktur data tunggal (kumpulan node DOM). Jika kita akan menambahkan subclass jQuery atau struktur data lain proyek akan runtuh sangat cepat. Jadi saya tidak berpikir kita bisa berbicara tentang oo dengan jQuery itu lebih prosedural daripada oo meskipun fakta bahwa mendefinisikan kelas.
Apa yang diklaim Laurent adalah omong kosong:
Pola Dekorator adalah tentang menambahkan fungsionalitas baru dengan menjaga antarmuka dan tidak mengubah kelas yang ada. Sebagai contoh:
Anda dapat mendefinisikan 2 kelas yang mengimplementasikan antarmuka yang sama, tetapi dengan implementasi yang sama sekali berbeda:
Jika Anda memiliki metode yang hanya menggunakan antarmuka umum, maka Anda dapat menentukan satu atau lebih Dekorator alih-alih menyalin kode yang sama antara A dan B. Anda dapat menggunakan dekorator ini bahkan dalam struktur bersarang.
Jadi Anda dapat mengganti instance asli dengan instance dekorator dalam kode level abstraksi yang lebih tinggi.
Kesimpulannya bahwa jQuery bukan Dekorator apa pun, karena ia tidak mengimplementasikan antarmuka yang sama dengan Array, NodeList atau objek DOM lainnya. Ini mengimplementasikan antarmuka itu sendiri. Modul tidak digunakan sebagai Dekorator juga, mereka hanya menimpa prototipe asli. Jadi pola dekorator tidak digunakan di seluruh jQuery lib. Kelas jQuery hanyalah sebuah adaptor besar yang memungkinkan kami menggunakan API yang sama oleh banyak browser yang berbeda. Dari perspektif oo memang berantakan, tetapi itu tidak terlalu penting, ia bekerja dengan baik, dan kami menggunakannya.
sumber