Gambar 1. Pengenalan modular programming.
Modular programming adalah pendekatan dalam pemrograman di mana kode dipisah menjadi modul-modul yang terpisah dan independen. Setiap modul memiliki tugas spesifik dan dapat berinteraksi dengan modul lain melalui antarmuka yang ditentukan. Pendekatan ini membantu dalam memecah kode menjadi bagian-bagian yang lebih kecil dan terorganisir, sehingga memudahkan pengembangan, pemeliharaan, dan peningkatan skala proyek.
Di Node.js, konsep modular programming memiliki fitur yang sangat berguna. Dalam penggunaan modul pada Node.js, Kalian dapat mengimpor fungsi, kelas, object, file eksternal, modul inti Node.js, dan modul NPM. Dalam Node.js, Kalian dapat menggunakan modul untuk membuat kode Kalian lebih terstruktur dan terorganisir. Modul memungkinkan Kalian untuk membagi kode ke dalam bagian-bagian yang terpisah, sehingga lebih mudah untuk mengelola dan mempertahankan aplikasi Kalian.
Ada dua jenis pola modular yang umum digunakan dalam Node.js, yaitu:
Pola stateless digunakan untuk mengelola entitas yang tidak menyimpan status atau informasi yang berkelanjutan. Misalnya, Kalian dapat menggunakan pola stateless untuk mengelola kelas, object, dan metode yang tidak bergantung pada status sebelumnya.
Pola stateful digunakan untuk mengelola object yang memiliki status atau informasi yang berkelanjutan. Misalnya, Kalian dapat menggunakan pola stateful untuk mengelola instance object seperti koneksi database atau layanan API pihak ketiga.
Berikut adalah langkah-langkah umum untuk menerapkan modul-modul pada Node.js:
Gambar 2. Membuat file.
Pisahkan kode kalian ke dalam file-file modul yang berisi fungsionalitas tertentu. Biasanya, setiap modul akan memiliki satu fungsi utama atau object yang didefinisikan di dalamnya.
Gambar 3. Membuat program untuk mengimport modul.
Di dalam file JavaScript lain, gunakan pernyataan require untuk mengimpor modul yang dibutuhkan. Misalnya, var mathUtils = require(' ./mathUtils '); akan mengimpor modul yang disebut "mathUtils.js" yang berada di direktori yang sama seperti pada gambar 3.
Gambar 4. Membuat program untuk mengekspor modul.
Di dalam file modul, gunakan pernyataan module.exports atau exports untuk mengekspor function, object, atau variabel yang ingin digunakan di luar modul tersebut seperti pada gambar 4.
Gambar 5. Contoh penggunaan modul.
Setelah mengimpor modul, Anda dapat menggunakan function, object, atau variabel yang diekspor oleh modul tersebut seperti pada gambar 5.
Gambar 6. Pengenalan design patterns.
Design patterns adalah solusi yang telah teruji dan terbukti efektif dalam memecahkan masalah yang umum ditemui dalam pengembangan perangkat lunak. Dengan menggunakan design patterns, kalian dapat meningkatkan struktur, kebersihan, dan skalabilitas aplikasi Node.js. Design patterns membantu kalian mengorganisasi kode dengan cara yang sistematis, sehingga lebih mudah dipahami, diubah, dan diperluas di masa depan.
Ada banyak design patterns yang dapat diterapkan dalam pengembangan aplikasi Node.js, yaitu:
Singleton Pattern adalah salah satu design pattern yang digunakan untuk memastikan bahwa hanya ada satu instance dari suatu kelas yang dapat dibuat. Dalam kata lain, Singleton Pattern memastikan bahwa hanya ada satu object yang dapat diakses dan digunakan di seluruh aplikasi.
Contoh sederhana untuk memahami Singleton Pattern adalah sebuah logger (pencatat) dalam sebuah aplikasi. Kita ingin memastikan bahwa hanya ada satu object logger yang digunakan di semua bagian aplikasi untuk mencatat pesan-pesan. Dengan menggunakan Singleton Pattern, kita memastikan bahwa seluruh bagian aplikasi menggunakan object logger yang sama, sehingga pesan-pesan log dapat dicatat dengan konsisten dan tidak ada duplikasi object logger yang tidak perlu.
Gambar 7. Membuat program membuat log.
Gambar 8. Contoh penggunaan singleton pattern.
Pada program di gambar 8, ketika object logger pertama kali dibuat dengan new Logger, instance Singleton akan disimpan dalam variabel instance atau bisa lihat gambar 7. Ketika kita membuat object logger kedua kalinya, variabel instance sudah berisi instance yang telah dibuat sebelumnya, sehingga object logger yang kedua akan merujuk pada object logger yang pertama.
Factory Pattern adalah sebuah design pattern yang digunakan untuk membuat object-object berdasarkan suatu tipe atau kategori tertentu, tanpa harus secara langsung mengungkapkan kelas spesifik yang akan dibuat. Dengan menggunakan Factory Pattern, kita dapat membuat sebuah pabrik (factory) yang bertanggung jawab untuk membuat object bentuk berdasarkan input yang diberikan.
Contoh sederhana untuk memahami Factory Pattern adalah pembuatan object Shape (bentuk). Kita memiliki beberapa jenis bentuk seperti lingkaran, persegi, dan segitiga.
Gambar 9. Membuat program shape factory.
Pada program di gambar 9, kita memiliki class Shape sebagai kelas abstrak yang memiliki metode draw. Kemudian, kita memiliki kelas-kelas turunan seperti Circle, Square, dan Triangle yang mengimplementasikan metode draw sesuai dengan jenis bentuknya.
Selanjutnya, kita memiliki class ShapeFactory yang bertanggung jawab untuk menciptakan object Shape berdasarkan tipe yang diberikan. Dengan menggunakan metode createShape, kita dapat membuat object Shape tanpa perlu mengetahui secara langsung kelas spesifik yang dibuat.
Gambar 10. Contoh penggunaan factory pattern.
Dengan Factory Pattern, kita dapat dengan mudah menambahkan jenis bentuk baru ke dalam aplikasi hanya dengan menambahkan implementasi kelas turunan dan memperbarui metode createShape di dalam ShapeFactory seperti pada gambar 10. Hal ini memisahkan proses pembuatan object dari penggunaan object, sehingga aplikasi menjadi lebih fleksibel dan dapat dengan mudah diubah tanpa mengganggu kode yang sudah ada.
Observer Pattern adalah sebuah design pattern yang digunakan untuk mengatur komunikasi antar object yang tergantung pada suatu subject. Dalam Observer Pattern, subject akan memiliki daftar observer (pengamat) yang akan dipanggil secara otomatis ketika terjadi perubahan pada subjek tersebut. Ini memungkinkan object-object pengamat untuk memperoleh pembaruan (update) secara real-time dari subject tanpa harus saling bergantung.
Contoh sederhana untuk memahami Observer Pattern adalah sistem pemberitahuan (notification system). Bayangkan kalian memiliki aplikasi chat dimana pengguna dapat berlangganan (subscribe) ke berbagai ruang obrolan. Setiap kali ada pesan baru dalam ruang obrolan yang mereka ikuti, pengguna akan menerima pemberitahuan tentang pesan tersebut.
Gambar 11. Membuat program sistem notifikasi.
Pada program di gambar 11, terdapat dua kelas utama yang mewakili subject (ruang obrolan) dan observer (pengguna). Subject bertanggung jawab untuk mengelola daftar observer yang terdaftar dan memberitahu mereka tentang perubahan yang terjadi. Observer adalah objek yang menerima pemberitahuan dari subjek dan melakukan tindakan tertentu ketika menerima pemberitahuan.
Class ChatRoom merupakan subject yang memiliki metode subscribe untuk menambahkan observer baru ke dalam daftar, unsubscribe untuk menghapus observer dari daftar, dan notify untuk memberi tahu semua observer tentang pesan baru. Pada metode notify, subject akan melakukan iterasi melalui daftar observer dan memanggil metode update pada setiap observer.
Class User merupakan observer yang memiliki metode update yang dipanggil ketika menerima pemberitahuan dari subject. Pada program di atas, metode update hanya mencetak pesan baru ke konsol.
Gambar 12. Contoh penggunaan observer pattern.
Pada program di gambar 12,, beberapa pengguna (observer) berlangganan ke ruang obrolan (subject). Ketika subject mengirimkan pemberitahuan, setiap pengguna yang berlangganan akan menerima pemberitahuan tersebut dan melakukan tindakan sesuai dengan implementasi dalam metode update.
Pada program di atas menunjukkan penggunaan observer pattern di mana ketiga pengguna (user1, user2, dan user3) berlangganan ke ruang obrolan (chatRoom). Ketika subject mengirimkan pemberitahuan dengan pesan tertentu, setiap pengguna yang berlangganan akan menerima pesan tersebut dan mencetaknya ke konsol. Ketika pengguna kedua (user2) berhenti berlangganan, dia tidak akan menerima pemberitahuan berikutnya.
MVC Pattern adalah sebuah design pattern yang digunakan untuk memisahkan logika aplikasi ke dalam tiga komponen utama: Model, View, dan Controller. Setiap komponen memiliki tanggung jawab yang berbeda, sehingga memungkinkan pengembangan aplikasi yang terstruktur, modular, dan mudah dipelihara. Apa saja kegunaan dari setiap komponen utama? Mari kita bahas!
a. Model
Komponen model berfungsi untuk mengelola data dan bisnis logic aplikasi. Model merepresentasikan struktur data yang digunakan dalam aplikasi, serta menyediakan metode untuk mengakses, memodifikasi, dan memanipulasi data tersebut. Model tidak bergantung pada tampilan (view) atau interaksi pengguna (controller).
Gambar 13. Membuat program model.
b. View
Komponen view menampilkan informasi kepada pengguna. Tampilan adalah bagian visual dari aplikasi yang digunakan untuk berinteraksi dengan pengguna. Contoh tampilan bisa berupa halaman web, antarmuka pengguna grafis (GUI), atau tampilan lainnya yang mempresentasikan data kepada pengguna.
Gambar 14. Membuat program view.
c. Controller
Komponen controller berperan sebagai penghubung antara Model dan View. Controller menerima input dari pengguna melalui tindakan (action) yang dilakukan di View, kemudian mengolah input tersebut dan memperbarui Model jika diperlukan. Controller juga bertanggung jawab untuk mengupdate tampilan (View) berdasarkan perubahan pada Model.
Gambar 15. Membuat program controller.
Gambar 16. Contoh penggunaan MVC pattern.
Pada program di gambar 16, kita memiliki Model class User yang mewakili data pengguna, View class UserView yang bertanggung jawab untuk menampilkan informasi pengguna ke konsol, dan Controller class UserController yang menghubungkan antara Model dan View.
Ketika metode updateUserInfo dipanggil pada Controller, data pengguna dalam Model diperbarui, dan kemudian informasi pengguna baru ditampilkan melalui View. Dengan menggunakan pola MVC, kita dapat memisahkan tugas-tugas yang berbeda dalam aplikasi, sehingga membuatnya lebih terorganisir dan mudah diubah jika diperlukan.
Dependency Injection (DI) Pattern adalah sebuah design pattern yang digunakan untuk mengurangi ketergantungan antar komponen dalam sebuah sistem. Dalam DI, ketergantungan diatur dari luar object, yang berarti bahwa object tidak bertanggung jawab untuk membuat atau memperoleh object dependennya sendiri. Sebaliknya, object tersebut menerima dependensi yang diperlukan dari sumber eksternal.
Secara sederhana, DI berarti sebuah object tidak bertanggung jawab untuk membuat atau mengetahui detail implementasi dari object lain yang dibutuhkannya, tetapi hanya menerima object tersebut dari luar.
Gambar 17. Membuat program yang membutuhkan dependensi.
Gambar 18. Membuat program yang menyediakan dependensi.
Gambar 19. Contoh penggunaan dependency injection.
Pada program di gambar 19, kita memiliki class ProductService yang membutuhkan akses ke database untuk mengambil produk berdasarkan id. Namun, ProductService tidak bertanggung jawab untuk membuat instance object Database, melainkan menerimanya sebagai parameter konstruktor.
Kemudian, kita membuat instance object Database terlebih dahulu, dan kemudian menginjectnya ke dalam ProductService saat membuat instance object ProductService. Dengan demikian, ProductService tidak perlu mengetahui detail implementasi dari Database, dan ketergantungan antara kedua kelas tersebut dikendalikan dari luar.
Dengan menggunakan Dependency Injection, kita dapat dengan mudah mengganti implementasi dari dependensi (misalnya, mengganti database dengan implementasi yang berbeda) tanpa mengubah kode dalam ProductService. Hal ini membuat sistem lebih fleksibel, terisolasi, dan memudahkan pengujian (testing) karena kita dapat mengganti dependensi dengan object palsu (mock) selama pengujian.
Middleware Pattern adalah sebuah design pattern yang sering digunakan dalam pengembangan aplikasi web. Pattern ini memungkinkan pemisahan fungsionalitas aplikasi menjadi beberapa lapisan yang berbeda dan dapat memodifikasi atau menambahkan perilaku di tengah proses penanganan permintaan (request) dan pembaruan tanggapan (response) dalam aplikasi.
Secara sederhana, middleware dapat dianggap sebagai fungsi-fungsi perantara yang ditempatkan di antara permintaan dan tanggapan dalam suatu aliran (flow) pengolahan aplikasi. Setiap fungsi middleware menerima objek permintaan (request), objek tanggapan (response), dan fungsi berikutnya dalam aliran. Fungsi tersebut dapat memodifikasi objek permintaan dan tanggapan, menjalankan logika tambahan, atau menghentikan aliran dan mengembalikan tanggapan.
Gambar 20. Contoh penggunaan middleware pattern.
Pada program di gambar 20, middleware logger digunakan untuk mencatat log setiap permintaan yang masuk ke server. Kemudian middleware authentication Digunakan untuk melakukan otorisasi terhadap permintaan dengan memeriksa apakah pengguna terotentikasi atau memiliki token yang valid. Middleware response Digunakan untuk mengirimkan tanggapan "Hello, World!" saat permintaan diakses.
Ketiga middleware tersebut ditambahkan ke dalam aliran penanganan permintaan dengan menggunakan metode app.use dan app.get. Middleware akan dieksekusi secara berurutan saat permintaan diterima oleh server.
Dengan menggunakan Middleware Pattern, kita dapat memisahkan fungsionalitas yang berbeda dalam aplikasi web ke dalam lapisan yang terpisah dan menerapkan logika tambahan atau validasi pada setiap permintaan sebelum mencapai tanggapan. Hal ini memungkinkan modularitas, fleksibilitas, dan penggunaan kembali kode yang lebih baik dalam pengembangan aplikasi web.
Referensi