Saya telah mendengar berkali-kali tentang jebakan para Singleton / global, dan saya mengerti mengapa mereka begitu disukai.
Yang tidak saya mengerti adalah apa alternatif yang elegan dan tidak berantakan itu. Tampaknya alternatif untuk menggunakan Singletons / globals selalu melibatkan melewati objek satu juta level ke bawah melalui objek mesin Anda hingga mencapai objek yang membutuhkannya.
Misalnya, dalam game saya, saya memuat beberapa aset saat game dimulai. Aset ini tidak digunakan sampai nanti ketika pemain menavigasi menu utama dan memasuki permainan. Apakah saya harus meneruskan data ini dari objek Game saya, ke objek ScreenManager saya (terlepas dari kenyataan bahwa hanya satu Layar yang benar-benar peduli tentang data ini), kemudian ke objek Layar yang sesuai, dan di mana pun?
Sepertinya saya memperdagangkan data keadaan global untuk injeksi dependensi yang berantakan, meneruskan data ke objek yang bahkan tidak peduli dengan data kecuali untuk tujuan meneruskannya ke objek anak.
Apakah ini kasus di mana Singleton akan menjadi hal yang baik, atau adakah solusi elegan yang saya lewatkan?
sumber
Jika Anda tidak / tidak dapat memiliki satu bagian kode yang secara ajaib "tahu" tentang beberapa data, maka entah bagaimana itu harus diteruskan. Namun itu tidak berarti harus melalui argumen saja.
Dalam contoh kasus Anda, bisakah Anda tidak memiliki semacam "AssetManager" yang akan memuat dan menyimpan aset, dan kemudian ScreenManager hanya perlu diberikan referensi untuk itu (mungkin saat pembuatan)? Dalam pengertian itu Anda meneruskan referensi ke aset yang dibungkus dalam objek lain, dan Anda bisa memberikannya sekali, pada inisialisasi, daripada meneruskannya ke fungsi daun saat diperlukan.
Sekarang IMHO bahwa AssetManager, menjadi hal yang Anda hanya ingin satu, mungkin juga singleton. Asalkan Anda memahami jebakan, dan kode khusus untuk menghindarinya (anggap bahwa singleton akan diakses secara bersamaan dari beberapa utas dan menusuk diri sendiri dengan garpu setiap kali Anda melakukan sesuatu yang perlu diblokir), lalu benturkan diri.
sumber
Saya pikir Jason D benar - inilah cara saya menanganinya:
Game memiliki instance dari AssetManager, objek dari mana Anda bisa mendapatkan aset apa pun dengan nama.
Dalam permainan:
Di ScreenManager:
Di Layar:
Sekarang semua layar memiliki akses ke semua aset yang mereka butuhkan. Ini tidak lebih rumit atau gila daripada menggunakan global atau Singletons, dan Anda memiliki opsi untuk menjalankan 2 instance Game dalam aplikasi yang sama tanpa bentrokan. Saya pernah harus membuat game yang terdiri dari 8 mini-game, semua berbagi kelas dasar / kerangka kerja yang sama. Saya harus memperbaiki semua global / lajang saya untuk menggunakan gaya passing referensi ini, dan saya tidak pernah melihat ke belakang. Satu-satunya hal yang seharusnya menjadi global adalah hal-hal yang hanya dapat secara fisik ada satu kali, seperti audio, jaringan, i / o dll.
sumber
Anda dapat menggunakan pola Pabrik untuk menggantikan Singleton . Kemudian kelas pabrik memiliki kendali atas berapa banyak instance yang dapat Anda buat, yang nantinya dapat Anda ubah dengan mudah ketika Anda membutuhkan lebih dari satu
AssetManager
. Sebagaimana dinyatakan dalam artikel ini :Kemungkinan lain, yang agak terbatas, adalah membuat kelas statis (yang menurut saya tidak layak untuk AssetManager dan hanya mungkin dalam bahasa yang memiliki kelas statis sama sekali). Tetapi itu hanya akan berhasil jika Anda tidak membutuhkan warisan / polimorfisme. Ini solusi yang sangat tidak fleksibel:
Ini tentang metode statis, tetapi juga bisa diterapkan ke kelas statis.
sumber