Singleton adalah salah satu dari klasifikasi Creational Design Pattern. Pattern ini memastikan bahwa kamu hanya perlu satu instance , sambil menyediakan akses secara global ke instance.

Hal ini berguna ketika kamu perlu sebuah objek yang dapat mengkoordinasikan tindakan diseluruh sistem. Istilah ini berasal dari konsep matematika bernama <strong>Singleton</strong>.

Dalam pemrograman, sebuah objek bisa dikatakan Singleton, apabila hanya memiliki sebuah instance yang digunakan diseluruh kode logikamu.


Apa Itu Instansi (Instance)


Instansi (Instance) adalah sebuah variabel objek dari class, atau bisa dibilang pembentukan dari class menjadi sebuah objek.

Ragam Design Pattern Singleton
Photo by Amy Humphries on Unsplash

Untuk lebih sederhananya coba lihat kode dibawah ini :

class Hewan:
    def lari(self):
        pass

kucing = Hewan()

Maksud dari kode diatas adalah kita membuat sebuah instance dari class yaitu Hewan() dan menyimpannya ke dalam variabel kucing.

Sehingga dapat dijelaskan bahwa variabel kucing adalah instance dari class Hewan.

Oke, kalian sekarang sudah tahu apa itu Instance, sekarang kita lanjutkan pembahasan kita tentang Singleton.


Kenapa Singleton?


Dalam kenyataannya Singleton Pattern dapat menyelesaikan dua masalah sekaligus :

Ragam Design Pattern Singleton
Photo by Emily Morter on Unsplash

1. Untuk Memastikan Bahwa Sebuah Class Hanya Memiliki Satu Instance

Untuk apa orang ingin mengatur banyak instance dalam class yang ia buat? Alasan paling umum untuk ini adalah ia ingin mengendalikan akses sebuah shared resource, contohnya sebuah Database atau File.

Contoh Kesalahan: Bayangkan kamu membuat sebuah objek, tapi beberapa saat kemudian kamu memutuskan untuk membuat yang baru. Bukannya menerima objek baru, malah menerima objek yang telah kamu buat.

Catatan : Perilaku ini tidak mungkin diterapkan dengan constructor biasa, dikarenakan constructor harus selalu mengembalikan nilai (return) sebuah objek baru sesuai desainnya.

2. Untuk Menyediakan Sebuah Akses Global Ke Instance Tersebut

Ingat apa itu Global Variabel yang digunakan untuk menyimpan dan mengakses sebuah objek dimanapun itu? Meskipun ini sangat praktis, hal ini juga sangat beresiko. Karena variabel ini sangat rentan di overwrite oleh kode lainnya dan membuat app crash.

Sama seperti variabel global, Singleton Pattern memungkinkan kamu mengakses beberapa objek dari manapun di dalam program. Namun, Singleton melindungi instance agar tidak di overwrite oleh kode lain.

Perbedaan antara Singleton Pattern dan Global Variabel yaitu Singleton hanya dibuat saat dibutuhkan, sedangkan Global Variabel dibuat saat awal program dijalankan.

Masalah Dari Sisi Yang Lain :

Kamu tidak ingin kode yang memecahkan masalah A tersebar di seluruh program yang kamu buat. Sehingga dapat menimbulkan adanya kode yang duplikat yang dapat menyebabkan redudansi dan bad pattern.

Jauh lebih baik kode ini dibuat didalam suatu class, dan class itu dapat digunakan untuk berbagai kebutuhanmu. Terutama jika kode yang lain sudah bergantung pada kode tersebut.

. . .

Saat ini , Singleton Pattern telah menjadi sangat populer sehingga orang dapat mengenali bagaimana cara memecahkan masalah dengan Singleton.


Contoh Penggunaan


Contoh implementasi konsep Singleton cukup banyak. Kali ini saya hanya menampilkan yang sering digunakan saja:

  1. Database Connection
    Dalam kebanyakan program yang memiliki koneksi database, mereka hanya membuat satu buah objek yang digunakan untuk berhubungan dari program ke database.

  2. Application Settings
    Ketika kita membuat sebuah pengaturan untuk sistem kita maka hanya satu objek yang dibuat, dan ketika pengaturan di apply maka seluruh sistem akan terpengaruh.

  3. Search Dialog
    Kita punya banyak content didalam program kita, lalu dibuatlah fitur Search Dialog. Ketika kita memanggil fitur ini, tidak mungkin membuat objek Search Dialog secara terus menerus. Hanya satu objek Search Dialog untuk seluruh program.


Analogi Singleton


Dalam dunia nyata, Pemerintah adalah contoh analogi yang tepat untuk Singleton. Satu negara hanya memiliki satu pemerintahan yang resmi.

Ragam Design Pattern Singleton
Photo by Marco Oriolesi on Unsplash

Kita ambil contoh yaitu Indonesia, Negara Indonesia memiliki Presiden dan sebuah pemerintahan resmi dengan nama “Pemerintah Indonesia”. Seluruh kebijakan dan kepentingan yang dilontarkan berasal dari pemerintah atas persetujuan presiden dan warga Indonesia menyampaikan aspirasinya kepada presiden lewat pemerintah.

Dalam analogi tersebut, Rakyat dianggap sebagai Modul , Presiden sebagai Resource dan Pemerintah sebagai Singleton.


Bagaimana Cara Mengaplikasikan Singleton?


Secara abstrak , kamu hanya perlu dua langkah sederhana untuk membuat sebuah Singleton objek.

  1. Buat default constructor secara private. Hal ini untuk mencegah objek lain membuat class Singleton baru. Kenapa? karena kita perlu memastikan bahwa objek ini hanya memiliki satu instance saja.

  2. Buat method statis yang bertindak sebagai constructor. Methode ini akan memanggil private constructor untuk membuat sebuah objek dan menyimpannya kedalam field statis.

Kalian masih bingung? Baik, Saya akan menjelaskan menggunakan kode nanti.


Struktur Singleton


Ragam Design Pattern Singleton
Photo by Tim Foster on Unsplash

Inti dari struktur tersebut adalah Client hanya dapat mengambil Instance dari Singleton yang kamu buat dengan memanggil getInstance().

Pada fungsi tersebut ia akan memeriksa Instance yang saat ini ada. Jika ia null, maka ia akan membuat instance baru dan return, dan jika ia tidak null maka return instance yang ada.


Waktunya Koding


Coba kita buat implementasi Singleton dengan bahasa pemrograman Python.

Kita buat studi kasus. Seperti analogi yang kita bahas sebelumnya, yaitu Negara Indonesia dengan Pemerintah Resminya. Sekarang kita konversi ke kode.


# save as : pemerintah.py

class Pemerintah():
    # Informasi
    kebijakan = None
    pajak = 0

    # Instance
    __instance = None

    # Private Constructor
    def __init__(self):
        if Pemerintah.__instance != None:
            raise Exception("Pemerintah sudah terbentuk!")
        else:
            Pemerintah.__instance = self

    # Static Access Method
    @staticmethod
    def getInstance():
        if Pemerintah.__instance == None:
            Pemerintah()
        return Pemerintah.__instance

Baik, saya akan menjelaskan maksud dari kode diatas.

Kita buat class Pemerintah() dengan private constructor dan juga method statis getInstance().

Saya membuat sebuah private variabel yaitu __instance dan beberapa informasi sebagai global variabel seperti kebijakan dan pajak.

Berikut penjelasan __(double underscore) pada Variabel di Python.

Pada fungsi getInstance() terdapat kondisi, jika __instance berisi None maka ia akan memanggil private constructor.

Lalu didalam private constructor terdapat juga kondisi yang menyatakan jika __instance sudah dibuat maka raise Exception() atau keluar ERROR. Ini diperlukan supaya tidak ada duplikasi instance class.

Sedangkan pada blok kode else, variabel __instance didefinisikan sebagai self atau bisa dibilang membuat instance dari class Pemerintah().


Sekarang kita coba implementasikan class Pemerintah().

from pemerintah import Pemerintah

pemindo = pemerintah.getInstance()

pemindo.kebijakan = "Kebebasan Berpendapat"
pemindo.pajak = 1000

print(pemindo.kebijakan) # Output : 'Kebebasan Berpendapat'
print(pemindo.pajak) # Output : 1000

Oke, kode diatas untuk memastikan bahwa tidak ada error dalam inisiasi ataupun alur kode.

Lalu kita coba, bagaimanakah implementasi dari sebuah Singleton.

from pemerintah import Pemerintah

# buat 2 objek instance
pemindo = pemerintah.getInstance()
pemkot = pemerintah.getInstance()

pemindo.kebijakan = "Indonesia Sebagai Negara Agraris"
pemindo.pajak = 1000

pemkot.kebijakan = "Didalam Kota Dilarang Pacaran"
pemkot.pajak = 9999

print(pemindo.kebijakan) # Output : 'Didalam Kota Dilarang Pacaran'
print(pemindo.pajak) # Output : 9999

“Kenapa valuenya sama? Padahal ia adalah objek yang berbeda?"

Siapa bilang mereka adalah objek yang berbeda. Kita coba lagi.

from pemerintah import Pemerintah

# buat 2 objek instance
pemindo = pemerintah.getInstance()
pemkot = pemerintah.getInstance()

if (pemindo == pemkot) :
    print("Mereka Objek yang sama")
else:
    print("Mereka Objek yang berbeda")

Nah, dari kode diatas dapat disimpulkan mereka adalah objek yang sama. Karena mereka menggunakan instance yang sama.

Lalu, bagaimana jika kita definisikan lagi instance dari class Pemerintah()?

from pemerintah import Pemerintah

pemindo = pemerintah.getInstance()
pemkot = Pemerintah()

Yups, akan terjadi ERROR yaitu Exception("Pemerintah Sudah Terbentuk!"). Seperti konsep yang kita bahas sebelumnya bahwa tidak boleh adanya duplikasi instance class.


Tipe - Tipe Singleton


Sekarang kita bahas 3 tipe dari Singleton.

  1. Early Loading Singleton
    Singleton yang instance-nya dinisialisasi secara langsung selama instance dideklarasi.
    pemindo = Pemerintah()  # Instance Dideklarasikan Langsung

    def getInstance():
        return pemindo
  1. Single-Thread โ€” Lazy Loading Singleton
    Singleton yang instance-nya dinisialisasi hanya saat class Singleton tersebut digunakan untuk pertama kali dan hanya ditujukan untuk Single Thread. Ini adalah Singleton yang kita buat tadi.

  2. Multi-Thread โ€” Lazy Loading Singleton
    Singleton yang instance-nya dinisialisasi hanya saat class Singleton tersebut digunakan untuk pertama kali dan ditujukan untuk multhi-threaded environtment.

Didalam environtment multi-threaded, akan sangat mungkin terjadi ketika dua thread memanggil method getInstance() pada waktu yang sama, dan akan membuat dua instance class Singleton yang tidak diinginkan, dan mungkin membuat program sulit diprediksi.

Untuk membuat thread instance Singleton yang aman, method getInstance() harus di Synchronized agar method akan tereksekusi oleh satu thread pada satu waktu (One-Thread-One-Run).

Kita akan bahas lebih mendalam tentang Multi-Thread pada artikel yang lain.


-> Singleton Tipe Apa Yang Sebaiknya Saya Pakai?

Jawaban atas pertanyaan ini berdasarkan masalah yang kamu hadapi.

Jika kamu hanya butuh Singleton sederhana dan mengesampingkan performa dari program yang kamu buat, gunakan Early Loading Singleton.

Jika kamu peduli tentang performa aplikasimu, tapi hanya menggunakan single threading, gunakan Single Thread - Lazy Loading Singleton. Pastikan kamu memanggil getInstance() didalam single thread, jika tidak Singleton yang kamu buat akan dinisialisasi dua kali dan menghasilkan multi-instance (maka kita tidak bisa menyebutnya sebuah Singleton)

Dan yang terakhir, jika kamu peduli tentang performa aplikasimu dan menggunakan environment multi-thread, gunakan Multi Thread - Lazy Loading Singleton.


Sesi Review


Ragam Design Pattern Singleton
Photo by Isaac Smith on Unsplash

Setelah semua teori dan contoh kode diatas, kita bisa menyimpulkan bahwa mengimplementasikan sebuah Singleton sangatlah mudah, seperti :

  1. Menambahkan private static field didalam class untuk menyimpan instance Singleton.

  2. Mendeklarasikan sebuah method public static creation untuk mendapatkan instance Singleton.

  3. Implementasikan salah satu tipe Singleton “Lazy Initilization” didalam method statis.

  4. Buat private constructor dari class.

  5. Lalu implementasikan ke kode program yang kamu buat.


-> Kapan Kita Menggunakan Singleton?

  • Gunakan Singleton ketika class pada programmu seharusnya memiliki satu instance untuk semua modul. Contoh, seperti shared database atau file.

  • Gunakan Singleton ketika kamu ingin mengontrol atas global variabel pada program yang kamu buat.

-> Kelebihan Singleton

  • Kamu bisa memastikan bahwa hanya ada satu instance yang dibuat.

  • Kamu dapat mengontrol instance yang memiliki akses secara global.

  • Objek Singleton hanya diinisialisasi ketika ia direquest untuk pertama kalinya.

-> Kekurangan Singleton

  • Singleton dapat menutupi desain program yang buruk oleh penciptanya, misalnya, ketika setiap komponen program tahu terlalu banyak informasi tentang satu sama lain.

  • Singleton membutuhkan perlakuan khusus saat berada di environment multi-threaded, agar tidak membuat objek Singleton berkali - kali.

. . .

Artikel ini adalah hasil translasi dari artikel aslinya yang bisa kalian lihat disini. Artikel yang asli ditulis oleh kerabat saya bernama Ezra Lazuardy dengan versi bahasa inggris. Sedangkan saya membuatnya menjadi versi bahasa indonesia dengan perubahan beberapa kalimat agar mudah dipahami.


***stay fool so you have learn***