Monkey Patching dalam Bahasa Pemrograman Dinamis: Contoh JavaScript

Javascript
Pemrograman Dinamis
Monkey Patching dalam Bahasa Pemrograman Dinamis cover image

Perkenalan

Artikel ini akan mengeksplorasi konsep bahasa pemrograman Dinamis dan Statis, perbedaan utama antara keduanya, dan kelebihan dan kekurangan masing-masing paradigma. Eksplorasi ini akan lebih fokus pada bahasa pemrograman dinamis, khususnya salah satu pola penting yang dimungkinkannya: Monkey Patch, pola ini akan ditampilkan dengan bantuan contoh di JavaScript.

Bahasa Pemrograman Dinamis vs Statis

Terminologi

Untuk memahami apa yang dimaksud dengan bahasa dinamis atau bahasa statis, kita perlu memahami beberapa istilah utama yang umum digunakan dalam konteks ini: Waktu kompilasi, Waktu proses, dan *Pemeriksaan jenis *.

Kompilasi dan Waktu Proses adalah dua istilah yang sesuai dengan tahapan berbeda dalam siklus hidup program komputer, dimulai dengan waktu Kompilasi.

Waktu Kompilasi

Waktu kompilasi adalah langkah pertama dalam siklus hidup suatu program. Seorang pengembang menulis kode dalam bahasa pemrograman tertentu. Seringkali, mesin tidak dapat memahami kode yang ditulis dalam bahasa tingkat tinggi sehingga kompiler khusus digunakan untuk menerjemahkannya ke format perantara tingkat rendah yang siap untuk dieksekusi.

Waktu proses

Runtime biasanya merangkum dua langkah: memuat program ke dalam memori dengan mengalokasikan sumber daya yang diperlukan untuk pelaksanaannya beserta instruksinya, dan kemudian mengeksekusi program mengikuti urutan instruksi tersebut.

Diagram berikut menggambarkan proses ini:

Pengecekan Tipe

Pemeriksaan tipe adalah fitur bawaan di hampir semua bahasa pemrograman. Ini adalah kemampuan untuk memeriksa apakah nilai yang diberikan pada variabel tertentu sesuai dengan jenis variabel yang benar. Setiap bahasa pemrograman memiliki cara berbeda untuk merepresentasikan nilai tipe tertentu dalam memori. Representasi yang berbeda ini memungkinkan untuk memeriksa korespondensi antara tipe nilai dan tipe variabel yang Anda coba berikan nilai tersebut.

Sekarang kita memiliki pemahaman tingkat tinggi tentang siklus hidup program dan pengecekan tipe, kita dapat melanjutkan untuk mengeksplorasi bahasa pemrograman statis.

Bahasa Pemrograman Statis

Bahasa Pemrograman Statis, juga disebut sebagai bahasa yang diketik secara statis adalah bahasa yang menerapkan pemeriksaan tipe yang kami sebutkan pada tahap kompilasi. Ini secara efektif berarti bahwa suatu variabel mempertahankan tipenya dari deklarasi dan tidak ada nilai yang dapat diberikan padanya selain nilai dari tipe deklarasinya. Bahasa pemrograman statis menawarkan keamanan ekstra ketika berhadapan dengan tipe tetapi dapat memperlambat proses pengembangan dalam kasus penggunaan tertentu ketika hal ini menjadi batasan yang ketat.

Bahasa Pemrograman Dinamis

Sebaliknya, bahasa pemrograman dinamis menerapkan pemeriksaan tipe saat runtime. Ini berarti variabel apa pun dapat menyimpan nilai apa pun di titik mana pun dalam program. Hal ini dapat bermanfaat karena menawarkan tingkat fleksibilitas kepada pengembang yang tidak terdapat dalam bahasa statis. Bahasa dinamis cenderung lebih lambat dalam eksekusi dibandingkan bahasa statis karena melibatkan langkah tambahan untuk secara dinamis mencari tahu pengetikan setiap variabel.

Tambalan Monyet

Pengetikan Statis vs Dinamis adalah ciri mendasar dalam bahasa pemrograman, menggunakan satu paradigma di atas paradigma lainnya dapat memungkinkan sejumlah pola dan praktik berbeda yang secara signifikan dapat meningkatkan kualitas dan kecepatan pengembangan. Hal ini juga dapat membuka pintu bagi banyak keterbatasan dan anti-pola jika tidak ada pertimbangan yang cermat saat membuat keputusan desain.

Khususnya, bahasa pemrograman yang diketik secara dinamis diketahui menawarkan tingkat fleksibilitas yang lebih tinggi karena tidak membatasi variabel pada satu jenis saja. Fleksibilitas ini disertai dengan tanggung jawab tambahan kepada pengembang saat mengimplementasikan dan melakukan debug program untuk memastikan tidak ada perilaku tak terduga yang terjadi. Pola patch monyet berasal dari filosofi ini.

Monkey Patch mengacu pada proses memperluas/mengubah cara kerja suatu komponen pada saat runtime. Komponen yang dimaksud bisa berupa perpustakaan, kelas, metode, atau bahkan modul. Idenya sama: sepotong kode dibuat untuk menyelesaikan tugas tertentu, dan tujuan dari monkey patching adalah untuk mengubah atau memperluas perilaku potongan kode tersebut sehingga menyelesaikan tugas baru, semuanya tanpa mengubah kode itu sendiri. .

Hal ini dimungkinkan dalam bahasa pemrograman dinamis karena apa pun jenis komponen yang kita hadapi, ia masih memiliki struktur objek yang sama dengan atribut yang berbeda, atribut tersebut dapat menampung metode yang dapat ditugaskan kembali untuk mencapai perilaku baru pada objek tersebut. tanpa membahas internal dan detail implementasinya. Hal ini menjadi sangat berguna dalam hal perpustakaan dan modul pihak ketiga karena cenderung lebih sulit untuk diubah.

Contoh berikut akan menampilkan kasus penggunaan umum yang dapat memperoleh manfaat dari penggunaan teknik patch monyet. Javascript digunakan demi implementasi di sini tetapi ini masih berlaku secara luas untuk bahasa pemrograman dinamis lainnya.

Contoh

Menerapkan Kerangka Pengujian Minimal dengan Modul HTTP Asli Node

Pengujian unit dan integrasi dapat termasuk dalam kasus penggunaan patching Monkey. Mereka biasanya melibatkan kasus pengujian yang mencakup lebih dari satu layanan untuk pengujian integrasi, atau ketergantungan API dan/atau database untuk pengujian unit. Dalam dua skenario ini, dan untuk mencapai tujuan pengujian, kami ingin pengujian kami tidak bergantung pada sumber daya eksternal ini. Cara untuk mencapai hal ini adalah dengan mengejek. Mocking adalah simulasi perilaku layanan eksternal sehingga pengujian dapat fokus pada logika kode sebenarnya. Monkey patching dapat membantu di sini karena dapat memodifikasi metode layanan eksternal dengan menggantinya dengan metode placeholder yang kita sebut “stub”. Metode ini mengembalikan hasil yang diharapkan dalam kasus pengujian sehingga kita dapat menghindari memulai permintaan ke layanan produksi hanya untuk kepentingan pengujian.

Contoh berikut adalah implementasi sederhana dari patching Monkey pada modul http asli NodeJs. Modul http adalah antarmuka yang mengimplementasikan metode protokol http untuk NodeJs. Hal ini terutama digunakan untuk membuat server http barebone dan berkomunikasi dengan layanan eksternal menggunakan protokol http.

Pada contoh di bawah ini kita memiliki kasus pengujian sederhana di mana kita memanggil layanan eksternal untuk mengambil daftar id pengguna. Daripada memanggil layanan sebenarnya, kami menambal metode http get sehingga hanya mengembalikan hasil yang diharapkan yaitu serangkaian id pengguna acak. Hal ini mungkin tidak terlalu penting karena kita hanya mengambil data, tetapi jika kita menerapkan kasus pengujian lain yang melibatkan perubahan data, kita mungkin secara tidak sengaja mengubah data produksi saat menjalankan pengujian.

Dengan cara ini kami dapat mengimplementasikan fungsionalitas kami, dan menulis pengujian untuk setiap fungsi sambil memastikan keamanan layanan produksi kami.

// import the http module
let http = require("http");

// patch the get method of the http module
http.get = async function(url) {
  return {
    data: ["1234", "1235", "1236", "1236"]
  };
}

// example test suite, call new patched get method for testing
test('get array of user ids from users api', async () => {
  const res = await http.get("https://users.api.com/ids");
  const userIds = res.data;
  expect(userIds).toBeDefined();
  expect(userIds.length).toBe(4);
  expect(userIds[0]).toBe("1234");
});

Kode di atas sangat mudah, kita mengimpor modul http, menugaskan kembali metode http.get dengan metode baru yang hanya mengembalikan array id. Sekarang kita memanggil metode patch baru di dalam test case dan kita mendapatkan hasil baru yang diharapkan.

~/SphericalTartWorker$ npm test

> nodejs@1.0.0 test
> jest

PASS  ./index.test.js
  ✓ get array of user ids from users api (25 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.977 s, estimated 2 s
Ran all test suites.

Kesalahan Umum dan Keterbatasan

Tidak mengherankan jika menambal monyet memiliki kekurangan dan keterbatasannya sendiri. Dalam konteks modul dalam sistem modul simpul, menambal modul global seperti http dianggap sebagai operasi dengan efek samping, hal ini karena http dapat diakses dari titik mana pun di dalam basis kode dan entitas lain mungkin memiliki ketergantungan padanya. Entitas ini mengharapkan modul http beroperasi seperti biasa, dengan mengubah salah satu metode http kita secara efektif memutus semua dependensi http lainnya di dalam basis kode.

Karena kami beroperasi dalam bahasa yang diketik secara dinamis, segala sesuatunya mungkin tidak langsung gagal dan lebih memilih perilaku default yang tidak dapat diprediksi yang membuat proses debug menjadi tugas yang sangat kompleks. Dalam kasus penggunaan lainnya, mungkin terdapat dua patch berbeda dari komponen yang sama pada atribut yang sama, sehingga kami tidak dapat memprediksi patch mana yang akan didahulukan dibandingkan patch lainnya sehingga menghasilkan kode yang lebih tidak dapat diprediksi.

Penting juga untuk disebutkan bahwa patching monyet mungkin memiliki sedikit variasi dalam perilaku antara bahasa pemrograman yang berbeda. Itu semua tergantung pada desain bahasa dan pilihan implementasi. Misalnya, dalam python, tidak semua instance yang menggunakan metode patch akan terpengaruh oleh patch tersebut. Jika sebuah instance secara eksplisit memanggil metode yang ditambal maka ia akan mendapatkan versi terbaru yang baru, sebaliknya, instance lain yang mungkin hanya memiliki atribut yang menunjuk ke metode yang ditambal dan tidak memanggilnya secara eksplisit akan mendapatkan versi asli, hal ini disebabkan oleh cara python pengikatan di kelas beroperasi.

Kesimpulan

Dalam artikel ini kami mengeksplorasi perbedaan tingkat tinggi antara bahasa pemrograman statis dan dinamis, kami melihat bagaimana bahasa pemrograman dinamis dapat memperoleh manfaat dari paradigma dan pola baru yang memanfaatkan fleksibilitas bawaan yang ditawarkan bahasa-bahasa ini. Contoh yang kami tunjukkan terkait dengan Monkey patching, sebuah teknik yang digunakan untuk memperluas perilaku kode tanpa mengubahnya dari sumbernya. Kami melihat kasus di mana penggunaan teknik ini akan bermanfaat dan juga potensi kelemahannya. Pengembangan perangkat lunak adalah tentang pengorbanan, dan menggunakan solusi yang tepat untuk masalah tersebut memerlukan pertimbangan yang rumit dari pengembang dan pemahaman yang baik tentang prinsip dan fundamental arsitektur.


Career Services background pattern

Layanan Karir

Contact Section background image

Mari tetap berhubungan

Code Labs Academy © 2024 Semua hak dilindungi undang-undang.