Pemrograman

Cara Implementasi Singleton Design Pattern Golang

Pengertian Dasar

Singleton is a software design standard. This standard guarantees the existence of only one instance of a class, while maintaining a global point of access to its object.

Sesuai dengan quote yang diatas bahwa Singleton adalah desain standar perangkat lunak yang memberikan jaminan keberadaan hanya satu instance kelas, sambil mempertahankan titik akses global ke objeknya. Singleton adalah pola desain yang membatasi instantiation ke suatu objek, kita harus memastikan bahwa ini hanya terjadi sekali. Nah kamu sudah mulai kebayang kah?

Biasanya implementasi yang sering kita gunakan dalam software adalah saat kita menginisialisasi koneksi ke database. Agar ketika kita melakukan query tidak menginisialisasikan koneksi lagi maka kita perlu menggunakan Singleton (satu connection) saja agar lebih memanfaatkan resource koneksi ke database. Implementasi lain untuk singleton diantaranya:

  • Instance DB: kita hanya ingin membuat satu instance dari object DB dan satu itu bisa digunakan di seluruh program.
  • Instance Log: sama halnya dengan instance DB log juga hanya kita inisialisasi satu kali dan nanti bisa digunakan di seluruh program.
  • Instance External Call: misalkan kita inisalisasi connection HTTP untuk koneksi ke API ekternal, gRPC dan lainnya.
  • Instance Connect Cache: membuat satu instance cache agar tidak perlu dilakukan inisialisasi cache lagi di seluruh program.

Tidak seperti variabel global, Singleton menjamin bahwa hanya ada satu instance kelas. Tidak ada, kecuali untuk kelas Singleton itu sendiri, yang dapat menggantikan contoh yang di-cache. Perhatikan bahwa Kamu selalu dapat menyesuaikan batasan ini dan mengizinkan pembuatan sejumlah instance Singleton.

Pada dasarnya Singleton adalah cara untuk menggunakan variabel global. Kita tahu betapa berbahayanya penggunaan variabel global, kode Kita rentan terhadap akses variabel global atau di bagian mana pun dari sistem kita dapat mengubah nilainya. Jadi ketika kita mencoba untuk men-debug program, itu tidak akan menjadi tugas yang mudah untuk mengetahui jalur kode mana yang mengarah ke keadaan saat ini, itulah sebabnya tidak menganggap Singleton sebagai Anti Pattern, tetapi cara untuk melindungi variabel global.

Namun, masalah dengan Singleton terjadi jika dalam lingkungan multi-threaded, inisialisasi harus dilindungi untuk menghindari reboot, secara atomic. Singleton adalah fitur yang diturunkan dari paradigma berorientasi objek, jadi bagaimana kita mengimplementasikan Golang jika tidak memiliki dukungan OO? Untuk menjawab pertanyaan ini kita harus memahami bahwa Pemrograman Berorientasi Objek adalah sebuah konsep dan dapat diimplementasikan dalam bahasa pemrograman apa pun meskipun berparadigma lain. Jelas bahwa tingkat abstraksi dan kesulitan menjadi tugas yang sulit sangat meningkatkan tingkat kompleksitas kode tergantung pada bahasa.

Kelebihan dan Kekurangan Singleton

KelebihanKekurangan
Hanya memiliki satu instance.Perlu perlakuan khusu jika dikondisi multithread
Membuat Akses fungsi globalKesulitan ketika kita membuat unit test ketika instance private
Objek inisialisasi untuk pertama kali saja

Dasar Singleton Golang

Solusi yang disajikan di bawah ini akan ideal jika aplikasi kita sinkron, dan masalah akan diselesaikan dengan kode di bawah ini, tetapi karena tujuan kita adalah menerapkan menggunakan kompetisi, solusi di bawah ini jauh dari ideal. Mari kita periksa kode di bawah ini dan mulai kemungkinan penerapannya:

Dibawah ini contoh implementasi dasar idealnya suatu program yang synhronous menggunakan pattern Singleton. Mari kita lihat kode dibawah ini cara penerapannya:

Implementasi diatas merupakan simplenya penerapan Singleton di Golang dan kita jalankan dengan goroutine secara bersamaan. Masalah akan terlihat ketika gorouting melakukan pemeriksaan pertama dan semua akan membuat inisialisasi instance dan akan menggantikan satu sama lain sehingga tidak ada jaminan kalau instance ini dikembalikan sesuai dengan ekspektasi kita. Sayang sekali pendekatan ini, sangatlah memiliki kesalahan yang bisa terus terjadi dan ada kemungkinan besar value akan berbeda-beda. Ini merupakan hal yang tidak baik ketika kita akan melakukan debugging dan akan menjadi sangat sulit untuk mendeteksi bug, karena saat debug tidak ada yang salah karena runtime break. Penerapan ini kurang baik karena potensi Not Thread Safe.

Singleton menggunakan Locks with Mutex

Kode dibawah ini penerapan Singleton sebenarnya masih buruk untuk mencoba memecahkan masalah Thread Safe. Kode dibawah ini bisa memecahkan masalah tersebut tetapi masih bisa ter

Dalam kode di bawah ini adalah solusi yang buruk untuk mencoba memecahkan masalah “Thread Safe”. Sebenarnya, ini memecahkan masalah “Thread Safe”, tetapi menciptakan potensi masalah serius lainnya. Ini memperkenalkan penahanan dalam goroutine yang menjalankan pemblokiran agresif seluruh fungsi, mari kita periksa kode di bawah ini:jadi potensi masalah lainnya. Berikut ini kode untuk approach agar tidak terjadi masalah Thread Safe.

Masalah “Thread Safe” telah teratasi dengan implementasi di atas menggunakan sync.Mutex dimana Lockdown terjadi sebelum membuat instance Singleton. Masalah besar dengan pendekatan ini adalah pemblokiran yang berlebihan bahkan jika tidak diperlukan untuk melakukannya jika instance telah dibuat dan seharusnya mengembalikan instance tunggal. Jika program kita ditulis untuk menjadi sangat konkuren, ini bisa menghasilkan kemacetan, karena hanya satu rutinitas goroutine yang bisa mendapatkan instance tunggal dalam satu waktu, menjadikannya solusi ini sangat lambat. Mari kita periksa solusi lain, karena ini bukan pendekatan terbaik kami di atas.

Singleton menggunakan Check-Lock-Check

Salah satu cara untuk meningkatkan dan memastikan penguncian minimum dan tetap aman untuk goroutine adalah dengan menggunakan pola yang disebut Check-Lock-Check saat memperoleh kunci. Tetapi kamu harus menggunakan Mutex dengan atomic sehingga tidak “the tread safe”. Cek kode di bawah ini:

Singleton menggunakan sync.Once

Kami memiliki tipe Once pada library sync, mengingat bahwa library dalam Golang ini sangat berguna dan harus kita gunakan sebaik mungkin, Objek sync.Once akan melakukan inisialisasi tepat sekali dan tidak lebih, itu adalah penerapan paling baik dan powerful.

Dengan pendekatan ini, kode kita selain menjadi lebih bersih jauh lebih baik, fungsi sync.Once menjamin keunikan instance, sekarang dapat memiliki 100 goroutine atau lebih sesuai dengan kebutuhannya, menempatkan mereka dalam persaingan bukan kami akan melakukannya memiliki masalah Thread Safe atau pemeriksaan agresif. Cara sederhana dan aman untuk menulis kode Golang untuk mengimplementasikan Singleton Pattern.

Kesimpulan

Idealnya tidak diragukan lagi adalah penggunaan sync setelah itu menjamin initialisasi unik, tunggal dan juga Thread Safe yang menjamin bahwa “Kondisi Balapan” tidak terjadi, Ini memungkinkan fungsi untuk dijalankan hanya setelah Golang mengotomatiskan semua. Golang benar-benar menjadi lebih powerful dalam pendekatan ini, membuatnya mudah untuk diterapkan dan dipahami. Ketika kita berbicara tentang persaingan, seluruh cara berpikir kita dan solusi pengkodean menggunakan Golang berubah secara drastis. Ada beberapa skenario yang kami perlukan untuk menerapkan standar dan praktik dalam proyek kami untuk memanfaatkan sepenuhnya kekuatan yang ditawarkan Golang.

Semoga dengan artikel ini bisa membantu mengklarifikasi beberapa keraguan tentang penggunaan Singleton Pattern, menggunakan variabel global, goroutines, sync.Once, Init, Mutex, dan beberapa poin teknis penting lainnya yang tercakup dalam artikel ini.

Referensi

comments powered by Disqus