Mari kita hadapi itu. Pola Singleton adalah topik yang sangat kontroversial dengan pemrogram gerombolan di kedua sisi pagar. Ada orang yang merasa bahwa Singleton tidak lebih dari variabel global yang dimuliakan, dan ada pula yang bersumpah demi pola dan menggunakannya tanpa henti. Saya tidak ingin Kontroversi Singleton berada di inti pertanyaan saya. Setiap orang dapat melakukan tarik tambang dan bertempur habis-habisan dan melihat siapa yang menang untuk semua yang saya pedulikan . Yang ingin saya katakan adalah, saya tidak percaya ada satu jawaban yang benar dan saya tidak sengaja mencoba mengobarkan pertengkaran partisan. Saya hanya tertarik pada alternatif tunggal ketika saya mengajukan pertanyaan:
Apakah ada alternatif khusus mereka untuk GOF Singleton Pattern?
Misalnya, berkali-kali ketika saya telah menggunakan pola tunggal di masa lalu, saya hanya tertarik untuk mempertahankan status / nilai dari satu atau beberapa variabel. Status / nilai variabel, bagaimanapun, dapat dipertahankan antara setiap instansiasi kelas menggunakan variabel statis daripada menggunakan pola tunggal.
Ide lain apa yang Anda miliki?
EDIT: Saya tidak ingin ini menjadi posting lain tentang "cara menggunakan singleton dengan benar." Sekali lagi, saya mencari cara untuk menghindarinya. Untuk bersenang-senang, oke? Saya kira saya mengajukan pertanyaan akademis murni dengan suara trailer film terbaik Anda, "Di alam semesta paralel di mana tidak ada singleton, apa yang bisa kita lakukan?"
sumber
Jawaban:
Alex Miller dalam " Patterns I Hate " mengutip yang berikut:
"Ketika seorang lajang sepertinya jawabannya, saya merasa lebih bijaksana untuk:
sumber
Untuk memahami cara yang tepat untuk mengatasi Singletons, Anda perlu memahami apa yang salah dengan Singletons (dan status global secara umum):
Lajang menyembunyikan dependensi.
Mengapa itu penting?
Karena Jika Anda menyembunyikan dependensi, Anda cenderung kehilangan jejak jumlah kopling.
Anda mungkin membantahnya
lebih sederhana dari
tapi setidaknya API kedua memperjelas apa sebenarnya kolaborator metode tersebut.
Jadi cara untuk mengatasi Singletons bukanlah dengan menggunakan variabel statis atau pelacak layanan, tetapi untuk mengubah kelas Singleton menjadi instance, yang dibuat dalam lingkup di mana mereka masuk akal dan dimasukkan ke dalam komponen dan metode yang membutuhkannya. Anda mungkin menggunakan kerangka kerja IoC untuk menangani ini, atau Anda mungkin melakukannya secara manual, tetapi yang penting adalah menyingkirkan status global Anda dan membuat dependensi dan kolaborasi menjadi eksplisit.
sumber
Solusi terbaik yang saya temukan adalah menggunakan pola pabrik untuk membuat instance kelas Anda. Dengan menggunakan pola tersebut, Anda dapat memastikan bahwa hanya ada satu instance kelas yang dibagikan di antara objek yang menggunakannya.
Saya pikir ini akan rumit untuk mengelolanya, tetapi setelah membaca posting blog ini "Kemana Semua Jomblo Pergi?" , sepertinya sangat alami. Dan sebagai tambahan, ini sangat membantu dengan mengisolasi pengujian unit Anda.
Singkatnya, apa yang perlu Anda lakukan? Setiap kali sebuah objek bergantung pada yang lain, itu akan menerima turunannya hanya melalui konstruktornya (tidak ada kata kunci baru di kelas Anda).
Dan kemudian, pabrik.
Karena Anda hanya akan membuat instance pabrik satu kali, akan ada satu instance exSingleton. Setiap kali Anda memanggil buildNeedy, instance baru NeedyClass akan dibundel dengan exSingleton.
Saya harap ini membantu. Tolong tunjukkan jika ada kesalahan.
sumber
Spring atau IoC-Container lainnya melakukan pekerjaan yang cukup baik dalam hal itu. Karena kelas dibuat dan dikelola di luar aplikasi itu sendiri, penampung dapat membuat kelas sederhana menjadi tunggal dan memasukkannya jika diperlukan.
sumber
Anda tidak harus keluar dari cara Anda untuk menghindari pola apa pun. Penggunaan pola adalah keputusan desain atau kesesuaian alami (hal itu terjadi begitu saja). Saat Anda mendesain sistem, Anda memiliki pilihan untuk menggunakan pola atau tidak menggunakan pola. Namun, Anda tidak boleh berusaha keras untuk menghindari apa pun yang pada akhirnya menjadi pilihan desain.
Saya tidak menghindari Pola Singleton. Entah itu sesuai dan saya menggunakannya atau tidak sesuai dan saya tidak menggunakannya. Saya yakin sesederhana itu.
Kesesuaian (atau ketiadaan) Singleton bergantung pada situasinya. Ini adalah keputusan desain yang harus dibuat dan konsekuensi dari keputusan itu harus dipahami (dan didokumentasikan).
sumber
Monostate (dijelaskan dalam Pengembangan Perangkat Lunak Agile Robert C. Martin) adalah alternatif untuk tunggal. Dalam pola ini, data kelas semuanya statis tetapi getter / setter tidak statis.
Sebagai contoh:
Monostate memiliki perilaku yang mirip dengan singleton tetapi melakukannya dengan cara di mana programmer tidak selalu menyadari fakta bahwa singleton sedang digunakan.
sumber
The tunggal Pola ada karena ada situasi ketika sebuah objek tunggal diperlukan untuk memberikan satu set layanan .
Bahkan jika ini kasusnya, saya masih mempertimbangkan pendekatan membuat lajang dengan menggunakan bidang / properti statis global yang mewakili instance, tidak sesuai. Itu tidak pantas karena itu membuat ketergantungan dalam kode antara bidang statis dan objek bukan, layanan yang disediakan objek.
Jadi, alih-alih pola klasik tunggal, saya sarankan untuk menggunakan pola layanan 'suka' dengan wadah yang dilayani , di mana alih-alih menggunakan tunggal Anda melalui bidang statis, Anda mendapatkan referensi ke sana melalui metode yang meminta jenis layanan yang diperlukan.
bukannya global tunggal
Dengan cara ini ketika Anda ingin mengubah jenis objek dari tunggal ke yang lain, Anda akan memiliki waktu dan waktu yang mudah untuk melakukannya. Juga sebagai manfaat tambahan Anda tidak perlu membagikan semua instance objek ke setiap metode.
Juga lihat Pembalikan Kontrol , idenya adalah dengan mengekspos lajang secara langsung ke konsumen, Anda membuat ketergantungan antara konsumen dan contoh objek, bukan layanan objek yang disediakan oleh objek.
Pendapat saya adalah menyembunyikan penggunaan pola tunggal bila memungkinkan, karena tidak selalu mungkin untuk menghindarinya, atau diinginkan.
sumber
Jika Anda menggunakan Singleton untuk mewakili satu objek data, sebagai gantinya Anda bisa meneruskan objek data sebagai parameter metode.
(meskipun, saya berpendapat ini adalah cara yang salah untuk menggunakan Singleton sejak awal)
sumber
Jika masalah Anda adalah ingin mempertahankan status, Anda menginginkan kelas MumbleManager. Sebelum Anda mulai bekerja dengan sistem, klien Anda membuat MumbleManager, di mana Mumble adalah nama sistemnya. Negara dipertahankan melalui itu. Kemungkinan MumbleManager Anda akan berisi tas properti yang menahan status Anda.
Jenis gaya ini terasa sangat mirip C dan bukan seperti objek - Anda akan menemukan bahwa objek yang menentukan sistem Anda semuanya akan memiliki referensi ke MumbleManager yang sama.
sumber
Gunakan benda biasa dan benda pabrik. Pabrik bertanggung jawab untuk mengawasi instance dan detail objek biasa hanya dengan informasi konfigurasi (misalnya di dalamnya) dan perilaku.
sumber
Sebenarnya jika Anda mendesain langsung dari awal untuk menghindari Singeltons, Anda mungkin tidak perlu bekerja keras untuk tidak menggunakan Singletons dengan menggunakan variabel statis. Saat menggunakan variabel statis, Anda juga membuat Singleton lebih atau kurang, satu-satunya perbedaan adalah Anda membuat contoh objek yang berbeda, namun secara internal mereka semua berperilaku seolah-olah mereka menggunakan Singleton.
Dapatkah Anda memberikan contoh detail di mana Anda menggunakan Singleton atau di mana Singleton saat ini digunakan dan Anda mencoba untuk menghindari penggunaannya? Ini dapat membantu orang untuk menemukan solusi yang lebih mewah bagaimana situasi dapat ditangani tanpa Singleton sama sekali.
BTW, saya pribadi tidak punya masalah dengan Singletons dan saya tidak bisa memahami masalah orang lain tentang Singletons. Saya tidak melihat hal buruk tentang mereka. Artinya, jika Anda tidak menyalahgunakannya. Setiap teknik yang berguna dapat disalahgunakan dan jika disalahgunakan, itu akan menyebabkan hasil yang negatif. Teknik lain yang sering disalahgunakan adalah warisan. Tetap saja tidak ada yang akan mengatakan warisan adalah sesuatu yang buruk hanya karena beberapa orang menyalahgunakannya dengan kejam.
sumber
Secara pribadi bagi saya cara yang jauh lebih masuk akal untuk mengimplementasikan sesuatu yang berperilaku seperti tunggal adalah dengan menggunakan kelas yang sepenuhnya statis (anggota statis, metode statis, properti statis). Sebagian besar waktu saya menerapkannya dengan cara ini (saya tidak dapat memikirkan perbedaan perilaku apa pun dari sudut pandang pengguna)
sumber
Saya pikir tempat terbaik untuk mengawasi singleton adalah di tingkat desain kelas. Pada tahap ini, Anda harus dapat memetakan interaksi antar kelas dan melihat apakah sesuatu benar-benar memerlukan bahwa hanya 1 instance dari kelas ini yang pernah ada setiap saat dalam masa pakai aplikasi.
Jika itu masalahnya, maka Anda memiliki singleton. Jika Anda memasukkan lajang sebagai kenyamanan selama pengkodean maka Anda harus benar-benar meninjau kembali desain Anda dan juga menghentikan pengkodean kata lajang :)
Dan ya, 'polisi' adalah kata yang saya maksud di sini daripada 'menghindari'. Singleton bukanlah sesuatu yang harus dihindari (dengan cara yang sama bahwa variabel goto dan global bukanlah sesuatu yang harus dihindari). Sebaliknya, Anda harus memantau penggunaannya dan memastikan bahwa itu adalah metode terbaik untuk menyelesaikan apa yang Anda inginkan secara efektif.
sumber
Saya menggunakan singleton kebanyakan sebagai "wadah metode", tanpa status sama sekali. Jika saya perlu berbagi metode ini dengan banyak kelas dan ingin menghindari beban instantiasi dan inisialisasi, saya membuat konteks / sesi dan menginisialisasi semua kelas di sana; segala sesuatu yang mengacu pada sesi juga memiliki akses ke "singleton" yang terkandung.
sumber
Karena tidak diprogram dalam lingkungan yang sangat berorientasi objek (misalnya Java), saya tidak sepenuhnya memahami seluk-beluk diskusi. Tetapi saya telah mengimplementasikan singleton di PHP 4. Saya melakukannya sebagai cara untuk membuat handler database 'kotak hitam' yang secara otomatis diinisialisasi dan tidak harus dilewatkan ke atas dan ke bawah pemanggilan fungsi dalam kerangka yang tidak lengkap dan agak rusak.
Setelah membaca beberapa tautan pola tunggal, saya tidak sepenuhnya yakin saya akan menerapkannya dengan cara yang sama lagi. Apa yang benar-benar dibutuhkan adalah beberapa objek dengan penyimpanan bersama (misalnya pegangan database yang sebenarnya) dan inilah yang menjadi panggilan saya.
Seperti kebanyakan pola dan algoritme, menggunakan singleton 'hanya karena keren' adalah The Wrong Thing To Do. Saya benar-benar membutuhkan panggilan 'kotak hitam' yang kebetulan terlihat sangat lajang. Dan IMO itulah cara untuk menjawab pertanyaan: perhatikan polanya, tetapi juga lihat cakupannya yang lebih luas dan pada tingkat apa instansinya perlu unik.
sumber
Apa maksud Anda, apa teknik saya untuk menghindarinya?
Untuk "menghindarinya", itu menyiratkan bahwa ada banyak situasi yang saya temui di mana pola tunggal secara alami cocok, dan karena itu saya harus mengambil beberapa langkah untuk meredakan situasi ini.
Tapi tidak ada. Saya tidak harus menghindari pola tunggal. Itu sama sekali tidak muncul.
sumber