The pola tunggal adalah anggota disetor dari GOF 's pola buku , tetapi akhir-akhir ini tampaknya agak yatim piatu oleh dunia pengembang. Saya masih menggunakan banyak lajang, terutama untuk kelas pabrik , dan walaupun Anda harus sedikit berhati-hati tentang masalah multithreading (seperti kelas mana pun sebenarnya), saya gagal melihat mengapa mereka begitu mengerikan.
Stack Overflow terutama tampaknya menganggap bahwa semua orang setuju bahwa Singletons jahat. Mengapa?
Harap dukung jawaban Anda dengan " fakta, referensi, atau keahlian khusus "
Jawaban:
Parafrase dari Brian Button:
Mereka umumnya digunakan sebagai contoh global, mengapa begitu buruk? Karena Anda menyembunyikan dependensi aplikasi Anda dalam kode Anda, alih-alih mengekspos mereka melalui antarmuka. Membuat sesuatu yang global untuk menghindari menyebarkannya adalah bau kode .
Mereka melanggar prinsip tanggung jawab tunggal : berdasarkan fakta bahwa mereka mengendalikan penciptaan dan siklus hidup mereka sendiri.
Mereka inheren menyebabkan kode yang akan erat digabungkan . Ini membuat berpura-pura mereka dalam ujian agak sulit dalam banyak kasus.
Mereka membawa keadaan sekitar selama aplikasi seumur hidup. Hit lain untuk pengujian karena Anda bisa berakhir dengan situasi di mana tes harus dipesan yang merupakan tidak besar tidak untuk tes unit. Mengapa? Karena setiap unit tes harus independen dari yang lain.
sumber
Lajang memecahkan satu (dan hanya satu) masalah.
Kontensi Sumber Daya.
Jika Anda memiliki beberapa sumber daya
( 1 ) hanya dapat memiliki satu instance, dan
( 2 ) Anda perlu mengelola satu instance itu,
kamu butuh seorang singleton .
Tidak banyak contoh. File log adalah yang besar. Anda tidak ingin hanya meninggalkan satu file log. Anda ingin menyiram, menyinkronkan dan menutupnya dengan benar. Ini adalah contoh dari satu sumber daya bersama yang harus dikelola.
Jarang sekali Anda membutuhkan singleton. Alasan mereka buruk adalah karena mereka merasa seperti global dan mereka adalah anggota penuh dari buku Pola Desain GoF .
Ketika Anda berpikir Anda membutuhkan global, Anda mungkin membuat kesalahan desain yang mengerikan.
sumber
Beberapa penyandi pengkodean memandangnya hanya sebagai global yang dimuliakan. Dengan cara yang sama bahwa banyak orang membenci pernyataan goto ada orang lain yang membenci gagasan pernah menggunakan global . Saya telah melihat beberapa pengembang berusaha keras untuk menghindari global karena mereka menganggap menggunakannya sebagai pengakuan kegagalan. Aneh tapi Nyata.
Dalam praktiknya pola Singleton hanyalah teknik pemrograman yang merupakan bagian yang berguna dari perangkat konsep Anda. Dari waktu ke waktu Anda mungkin menemukan itu adalah solusi yang ideal dan gunakan itu. Tetapi menggunakannya hanya agar Anda dapat membanggakan tentang menggunakan pola desain sama bodohnya dengan menolak untuk menggunakannya karena itu hanya global .
sumber
Misko Hevery, dari Google, memiliki beberapa artikel menarik tentang topik ini ...
Lajang adalah Pembohong Patologis memiliki contoh pengujian unit yang menggambarkan bagaimana lajang dapat mempersulit untuk mengetahui rantai ketergantungan dan memulai atau menguji suatu aplikasi. Ini adalah contoh pelecehan yang cukup ekstrem, tetapi poin yang ia buat masih valid:
Di mana semua Singletons Gone menyatakan bahwa injeksi ketergantungan telah membuatnya mudah untuk mendapatkan instance untuk konstruktor yang membutuhkannya, yang mengurangi kebutuhan mendasar di balik yang buruk, Singletons global mengutuk dalam artikel pertama.
sumber
Saya pikir kebingungan ini disebabkan oleh fakta bahwa orang tidak tahu aplikasi sebenarnya dari pola Singleton. Saya tidak bisa cukup menekankan hal ini. Singleton bukan pola untuk membungkus global. Pola singleton hanya boleh digunakan untuk menjamin bahwa satu dan hanya satu instance dari kelas yang diberikan ada selama run time.
Orang mengira Singleton jahat karena mereka menggunakannya untuk orang global. Karena kebingungan inilah Singleton dipandang rendah. Tolong, jangan bingung Lajang dan global. Jika digunakan untuk tujuan yang dimaksudkan, Anda akan mendapatkan manfaat ekstrem dari pola Singleton.
sumber
setInstance
metode sebelumnya.) Namun, itu tidak masalah - bahwa Weenie yang "membutuhkan" seorang lajang juga tidak tahu apa-apa tentang enkapsulasi atau apa yang salah dengan enkapsulasi. negara global yang bisa berubah, jadi dia sangat membantu (?) menyediakan setter untuk setiap. tunggal. bidang. (Dan ya, ini terjadi. Banyak . Hampir setiap singleton yang pernah saya lihat di alam liar dapat berubah karena desain, dan seringkali memalukan.)goto
dll. Mereka mungkin bekerja dalam banyak kasus, tetapi terus terang, "bekerja" tidak cukup - jika Anda ingin bertentangan dengan kebijaksanaan konvensional, Anda sebaiknya dapat menunjukkan bagaimana pendekatan Anda adalah lebih baik daripada solusi konvensional. Dan saya belum melihat kasus seperti itu untuk pola Singleton.getInstance
metode yang serupa, dan mencegah keberadaan contoh kedua. Terus terang, pada titik itu, Anda mungkin bahkan tidak memiliki satu contoh.Satu hal yang agak buruk tentang lajang adalah Anda tidak dapat memperluasnya dengan mudah. Anda pada dasarnya harus membangun semacam pola dekorator atau semacamnya jika Anda ingin mengubah perilaku mereka. Juga, jika suatu hari Anda ingin memiliki banyak cara untuk melakukan satu hal itu, itu bisa agak menyakitkan untuk diubah, tergantung pada bagaimana Anda mengeluarkan kode Anda.
Satu hal yang perlu diperhatikan, jika Anda LAKUKAN menggunakan lajang, cobalah untuk mengirimkannya kepada siapa pun yang membutuhkannya daripada meminta mereka mengaksesnya secara langsung ... Jika tidak, jika Anda pernah memilih untuk memiliki banyak cara untuk melakukan hal yang dilakukan oleh lajang, itu akan menjadi agak sulit untuk diubah karena setiap kelas menanamkan ketergantungan jika mengakses langsung tunggal.
Pada dasarnya:
daripada:
Saya percaya pola semacam ini disebut injeksi ketergantungan dan umumnya dianggap sebagai hal yang baik.
Seperti pola apa pun ... Pikirkan dan pertimbangkan apakah penggunaannya dalam situasi yang diberikan tidak sesuai atau tidak ... Aturan dibuat untuk dilanggar biasanya, dan pola tidak boleh diterapkan tanpa tujuan tanpa berpikir.
sumber
getInstance()
, maka (b) tidak lagi benar.getInstance()
, Anda telah secara efektif membuang satu perbedaan yang bermanfaat antara pola Singleton dan referensi biasa. Sejauh menyangkut kode, kelajangan bukan lagi properti. Hanya penelepon yanggetInstance()
pernah perlu tahu atau bahkan peduli berapa banyak contoh ada. Dengan hanya satu penelepon, perlu biaya lebih banyak dalam upaya dan fleksibilitas bagi kelas untuk menegakkan keterikatan secara andal daripada meminta penelepon hanya menyimpan referensi dan menggunakannya kembali.Pola singleton bukanlah masalah tersendiri. Masalahnya adalah bahwa pola tersebut sering digunakan oleh orang-orang yang mengembangkan perangkat lunak dengan alat yang berorientasi objek tanpa memiliki pemahaman yang kuat tentang konsep OO. Ketika lajang diperkenalkan dalam konteks ini mereka cenderung tumbuh menjadi kelas yang tidak terkelola yang berisi metode pembantu untuk setiap penggunaan kecil.
Lajang juga merupakan masalah dari sudut pandang pengujian. Mereka cenderung membuat unit-test yang terisolasi sulit untuk ditulis. Inversion of control (IoC) dan injeksi ketergantungan adalah pola yang dimaksudkan untuk mengatasi masalah ini dengan cara yang berorientasi objek yang cocok untuk pengujian unit.
Dalam lingkungan sampah yang dikumpulkan, lajang dapat dengan cepat menjadi masalah sehubungan dengan manajemen memori.
Ada juga skenario multi-utas di mana lajang dapat menjadi hambatan serta masalah sinkronisasi.
sumber
Singleton diimplementasikan menggunakan metode statis. Metode statis dihindari oleh orang yang melakukan pengujian unit karena mereka tidak dapat diejek atau di-stub. Kebanyakan orang di situs ini adalah pendukung besar pengujian unit. Konvensi yang paling umum diterima untuk menghindarinya adalah menggunakan pola kontrol inversi .
sumber
Singleton
kelas palsu . Namun, itu sangat menyulitkan proses pengujian. Untuk satu, sekarang Anda harus dapat membongkar kelas sesuka hati (bukan benar-benar pilihan dalam kebanyakan bahasa), atau memulai VM baru untuk setiap tes (baca: tes mungkin memakan waktu ribuan kali lebih lama). Namun untuk dua orang, ketergantungan padaSingleton
adalah detail implementasi yang sekarang bocor di seluruh tes Anda.Lajang juga buruk dalam hal pengelompokan . Karena itu, Anda tidak memiliki "persis satu singleton" dalam aplikasi Anda lagi.
Pertimbangkan situasi berikut: Sebagai pengembang, Anda harus membuat aplikasi web yang mengakses database. Untuk memastikan bahwa panggilan database bersamaan tidak saling bertentangan, Anda membuat thread-save
SingletonDao
:Jadi, Anda yakin hanya ada satu singleton dalam aplikasi Anda dan semua basis data melewati satu-satunya ini
SingletonDao
. Lingkungan produksi Anda sekarang terlihat seperti ini:Semuanya baik-baik saja sejauh ini.
Sekarang, pertimbangkan Anda ingin mengatur beberapa contoh aplikasi web Anda dalam sebuah cluster. Sekarang, Anda tiba-tiba memiliki sesuatu seperti ini:
Kedengarannya aneh, tetapi sekarang Anda memiliki banyak lajang dalam aplikasi Anda . Dan memang itulah yang seharusnya tidak dilakukan oleh seorang lajang: Memiliki banyak objek. Ini sangat buruk jika Anda, seperti ditunjukkan dalam contoh ini, ingin melakukan panggilan tersinkronisasi ke database.
Tentu saja ini adalah contoh dari penggunaan singleton yang buruk. Tetapi pesan dari contoh ini adalah: Anda tidak dapat mengandalkan bahwa ada satu contoh singleton dalam aplikasi Anda - terutama ketika menyangkut pengelompokan.
sumber
sumber
Monopoli adalah iblis dan lajang dengan keadaan yang tidak bisa dibaca / bisa berubah adalah masalah 'nyata' ...
Setelah membaca Singletons adalah Pendusta Patologis seperti yang disarankan dalam jawaban jason, saya menemukan berita gembira kecil ini yang memberikan contoh terbaik yang disajikan tentang bagaimana singleton sering disalahgunakan.
Dalam pernyataan terakhir dia merujuk pada konsep blog tentang 'lajang adalah pembohong'.
Bagaimana ini berlaku untuk Monopoli?
Untuk memulai permainan monopoli, pertama:
Sekarang, bagi siapa saja yang belum benar - benar bermain monopoli, standar-standar ini paling ideal. Kekalahan dalam monopoli sulit ditelan karena, monopoli adalah tentang uang, jika Anda kalah, Anda harus dengan susah payah menonton sisa pemain yang menyelesaikan permainan, dan kekalahan biasanya cepat dan menghancurkan. Jadi, aturan biasanya diputar di beberapa titik untuk melayani kepentingan diri sendiri dari beberapa pemain dengan mengorbankan yang lain.
Jadi, Anda bermain monopoli dengan teman-teman Bob, Joe, dan Ed. Anda dengan cepat membangun kerajaan Anda dan mengonsumsi pangsa pasar pada tingkat eksponensial. Lawan Anda melemah dan Anda mulai mencium bau darah (kiasan). Teman Anda, Bob, memasukkan semua uangnya ke dalam kemacetan sebanyak mungkin properti bernilai rendah, tetapi miliknya tidak menerima pengembalian investasi yang tinggi seperti yang ia harapkan. Bob, sebagai pukulan sial, mendarat di Boardwalk Anda dan dikeluarkan dari permainan.
Sekarang permainan beralih dari dadu-bergulir ramah ke bisnis yang serius. Bob telah menjadi contoh kegagalan dan Joe dan Ed tidak ingin berakhir seperti 'pria itu'. Jadi, menjadi pemain terkemuka Anda, tiba-tiba, menjadi musuh. Joe dan Ed mulai mempraktikkan perdagangan di bawah meja, suntikan uang di belakang, pertukaran rumah yang undervalued dan umumnya apa pun untuk melemahkan Anda sebagai pemain sampai salah satu dari mereka naik ke atas.
Kemudian, alih-alih salah satu dari mereka menang, prosesnya dimulai dari awal. Tiba-tiba, seperangkat aturan yang terbatas menjadi target yang bergerak dan permainan berubah menjadi jenis interaksi sosial yang akan menjadi dasar dari setiap acara TV realitas berperingkat tinggi sejak Survivor. Mengapa, karena peraturan berubah dan tidak ada konsensus tentang bagaimana / mengapa / apa yang seharusnya mereka wakili, dan yang lebih penting, tidak ada satu orang pun yang mengambil keputusan. Setiap pemain dalam permainan, pada saat itu, membuat peraturannya sendiri dan kekacauan terjadi sampai dua pemain terlalu lelah untuk mempertahankan permainan dan perlahan-lahan menyerah.
Jadi, jika buku aturan untuk permainan secara akurat mewakili singleton, buku aturan monopoli akan menjadi contoh penyalahgunaan.
Bagaimana ini berlaku untuk pemrograman?
Selain dari semua masalah keamanan dan sinkronisasi utas yang jelas yang hadir dalam lajang yang bisa berubah ... Jika Anda memiliki satu set data, yang dapat dibaca / dimanipulasi oleh berbagai sumber secara bersamaan dan ada selama masa eksekusi aplikasi, mungkin ini saat yang tepat untuk mundur dan bertanya "apakah saya menggunakan tipe data struktur yang tepat di sini".
Secara pribadi, saya telah melihat seorang programmer menyalahgunakan singleton dengan menggunakannya sebagai semacam toko database cross-thread twisted dalam suatu aplikasi. Setelah bekerja pada kode secara langsung, saya dapat membuktikan bahwa itu lambat (karena semua kunci utas diperlukan untuk membuatnya aman) dan mimpi buruk untuk dikerjakan (karena sifat bug sinkronisasi yang tidak dapat diprediksi / berselang), dan hampir tidak mungkin diuji dalam kondisi 'produksi'. Tentu, sebuah sistem bisa dikembangkan menggunakan polling / pensinyalan untuk mengatasi beberapa masalah kinerja tetapi itu tidak akan menyelesaikan masalah dengan pengujian dan, mengapa repot ketika database 'nyata' sudah dapat mencapai fungsi yang sama dalam jauh lebih kuat / Cara terukur.
Singleton hanya merupakan opsi jika Anda membutuhkan apa yang disediakan oleh singleton. Sebuah instance read-only read-only dari objek. Aturan yang sama harus mengalir ke properti / anggota objek juga.
sumber
Singleton.getInstance()
. Bahasa yang mendukung refleksi mungkin dapat mengatasinya dengan mengatur bidang tempat One True Instance disimpan. IMO, bagaimanapun, tes menjadi sedikit kurang dapat dipercaya setelah Anda melakukan monkeying dengan negara pribadi kelas lain.Singleton bukan tentang satu contoh!
Tidak seperti jawaban lain saya tidak ingin berbicara tentang apa yang salah dengan Singletons tetapi untuk menunjukkan kepada Anda betapa kuat dan mengagumkannya mereka jika digunakan dengan benar!
Solusi : Gunakan proses bootstrap berulir tunggal untuk menginisialisasi semua dependensi singleton Anda.
Solusi : Gunakan metode Pola pabrik untuk mengejek
Anda dapat memetakan
MyModel
keTestMyModel
kelas yang mewarisinya, di mana pun saatMyModel
akan disuntikkan Anda akan mendapatkanTestMyModel
instread. - Masalah : Lajang dapat menyebabkan kebocoran memori karena tidak pernah dibuang.Solusi : Baiklah, buang mereka! Menerapkan panggilan balik di aplikasi Anda untuk membuang lajang dengan benar, Anda harus menghapus data apa pun yang terhubung dengannya dan akhirnya: menghapusnya dari Pabrik.
Seperti yang saya nyatakan pada judul singleton bukan tentang satu contoh.
sumber
Settings
objek tunggal yang dapat diakses dari widget apa pun sehingga setiap widget tahu tentang cara memformat angka yang ditampilkan. Jika itu bukan objek yang dapat diakses secara global, saya harus menyuntikkannya dalam konstruktor ke setiap widget di konstruktor dan menyimpan referensi sebagai variabel anggota. Ini adalah pemborosan memori dan waktu yang mengerikan.Jawaban saya tentang bagaimana Singletons buruk selalu, "mereka sulit dilakukan dengan benar". Banyak komponen dasar bahasa adalah singleton (kelas, fungsi, ruang nama dan bahkan operator), seperti komponen dalam aspek lain dari komputasi (localhost, rute default, sistem file virtual, dll.), Dan itu bukan kebetulan. Walaupun mereka menyebabkan masalah dan frustrasi dari waktu ke waktu, mereka juga dapat membuat banyak hal bekerja lebih baik.
Dua gangguan terbesar yang saya lihat adalah: memperlakukannya seperti global & gagal mendefinisikan penutupan Singleton.
Semua orang berbicara tentang Singleton sebagai global, karena pada dasarnya memang demikian. Namun, banyak (sayangnya, tidak semua) dari keburukan di global datang secara intrinsik bukan dari menjadi global, tetapi bagaimana Anda menggunakannya. Hal yang sama berlaku untuk para lajang. Sebenarnya lebih sebagai "contoh tunggal" benar-benar tidak perlu berarti "dapat diakses secara global". Ini lebih merupakan produk sampingan alami, dan mengingat semua hal buruk yang kita tahu berasal darinya, kita tidak boleh terburu-buru mengeksploitasi aksesibilitas global. Setelah programmer melihat Singleton mereka sepertinya selalu mengaksesnya secara langsung melalui metode instance-nya. Sebagai gantinya, Anda harus menavigasi ke sana seperti Anda akan objek lain. Sebagian besar kode bahkan tidak harus sadar bahwa itu berurusan dengan Singleton (longgar, kan?). Jika hanya sedikit kode mengakses objek seperti itu adalah global, banyak kerusakan yang dibatalkan.
Konteks Singleton juga sangat penting. Karakteristik yang menentukan dari Singleton adalah bahwa ada "hanya satu", tetapi kenyataannya adalah "hanya satu" dalam semacam konteks / namespace. Mereka biasanya salah satu dari: satu per utas, proses, alamat IP atau cluster, tetapi juga bisa satu per prosesor, mesin, bahasa namespace / kelas loader / apa pun, subnet, Internet, dll.
Kesalahan lainnya, yang kurang umum, adalah mengabaikan gaya hidup Singleton. Hanya karena hanya ada satu tidak berarti Singleton adalah mahakuasa "selalu ada dan akan selalu ada", juga tidak secara umum diinginkan (objek tanpa awal dan akhir melanggar semua jenis asumsi yang berguna dalam kode, dan harus digunakan hanya dalam situasi yang paling menyedihkan.
Jika Anda menghindari kesalahan-kesalahan itu, Lajang masih bisa menjadi PITA, sedikit itu siap untuk melihat banyak masalah terburuk dikurangi secara signifikan. Bayangkan Java Singleton, yang secara eksplisit didefinisikan sebagai sekali per classloader (yang berarti membutuhkan kebijakan keselamatan ulir), dengan metode penciptaan dan penghancuran yang ditentukan dan siklus hidup yang menentukan kapan dan bagaimana mereka dipanggil, dan yang metode "instance" memiliki paket perlindungan sehingga umumnya diakses melalui objek non-global lainnya. Masih merupakan sumber masalah yang potensial, tetapi tentu saja jauh lebih sedikit masalah.
Sedihnya, alih-alih mengajarkan contoh yang baik tentang bagaimana melakukan lajang. Kami mengajarkan contoh-contoh buruk, membiarkan programmer menggunakan mereka untuk sementara waktu, dan kemudian memberi tahu mereka bahwa mereka adalah pola desain yang buruk.
sumber
Lihat Wikipedia Singleton_pattern
Referensi (hanya referensi yang relevan dari artikel)
sumber
Bukannya lajang itu sendiri buruk tetapi pola desain GoF adalah. Satu-satunya argumen yang benar-benar valid adalah bahwa pola desain GoF tidak cocok untuk pengujian, terutama jika tes dijalankan secara paralel.
Menggunakan instance tunggal dari kelas adalah konstruk yang valid selama Anda menerapkan cara berikut dalam kode:
Pastikan kelas yang akan digunakan sebagai singleton mengimplementasikan antarmuka. Ini memungkinkan stubs atau ejekan untuk diimplementasikan menggunakan antarmuka yang sama
Pastikan Singleton aman dari utas benang. Itu diberikan.
Singleton harus sederhana dan tidak terlalu rumit.
Selama runtime aplikasi Anda, di mana lajang perlu dikirimkan ke objek tertentu, gunakan pabrik kelas yang membangun objek itu dan minta pabrik kelas meneruskan instance singleton ke kelas yang membutuhkannya.
Selama pengujian dan untuk memastikan perilaku deterministik, buat kelas singleton sebagai contoh terpisah sebagai kelas aktual itu sendiri atau sebuah rintisan / mock yang mengimplementasikan perilakunya dan meneruskannya seperti halnya ke kelas yang membutuhkannya. Jangan gunakan faktor kelas yang menciptakan objek yang diuji yang membutuhkan singleton selama pengujian karena akan melewati instance global tunggal dari itu, yang mengalahkan tujuannya.
Kami telah menggunakan Singletons dalam solusi kami dengan banyak keberhasilan yang dapat diuji memastikan perilaku deterministik dalam aliran uji coba paralel.
sumber
Saya ingin membahas 4 poin dalam jawaban yang diterima, semoga seseorang dapat menjelaskan mengapa saya salah.
Mengapa menyembunyikan dependensi dalam kode Anda buruk? Sudah ada puluhan dependensi tersembunyi (panggilan runtime C, panggilan OS API, panggilan fungsi global), dan dependensi singleton mudah ditemukan (cari misalnya ()).
"Membuat sesuatu yang global untuk menghindari menyebarkannya adalah bau kode." Mengapa tidak melewatkan sesuatu untuk menghindari membuatnya menjadi bau kode?
Jika Anda melewatkan objek melalui 10 fungsi dalam tumpukan panggilan hanya untuk menghindari singleton, apakah itu hebat?
Prinsip Tanggung Jawab Tunggal: Saya pikir ini agak kabur dan tergantung pada definisi tanggung jawab Anda. Pertanyaan yang relevan adalah, mengapa menambahkan "tanggung jawab" khusus ini ke masalah kelas?
Mengapa melewatkan objek ke kelas membuatnya lebih erat daripada menggunakan objek itu sebagai singleton dari dalam kelas?
Mengapa itu berubah berapa lama negara berlangsung? Lajang dapat dibuat atau dimusnahkan secara manual, sehingga kontrolnya masih ada, dan Anda dapat membuat masa pakai itu sama dengan masa hidup objek yang bukan tunggal.
Mengenai tes unit:
sumber
Vince Huston memiliki kriteria ini, yang menurut saya masuk akal:
sumber
Lajang buruk dari sudut pandang murni.
Dari sudut pandang praktis, singleton adalah trade-off yang mengembangkan waktu vs kompleksitas .
Jika Anda tahu aplikasi Anda tidak akan banyak berubah, mereka cukup baik untuk digunakan. Hanya tahu bahwa Anda mungkin perlu memperbaiki keadaan jika persyaratan Anda berubah secara tak terduga (yang cukup baik dalam kebanyakan kasus).
Lajang terkadang juga mempersulit pengujian unit .
sumber
Tidak ada yang salah secara inheren dengan polanya, dengan asumsi itu sedang digunakan untuk beberapa aspek dari model Anda yang benar-benar tunggal.
Saya percaya serangan balik itu karena terlalu sering digunakan, yang pada gilirannya, disebabkan oleh fakta bahwa itu adalah pola termudah untuk dipahami dan diterapkan.
sumber
Saya tidak akan mengomentari argumen baik / jahat, tapi saya belum menggunakannya sejak Spring datang. Menggunakan injeksi ketergantungan telah cukup banyak menghilangkan persyaratan saya untuk singleton, servicelocators dan pabrik. Saya menemukan ini lingkungan yang jauh lebih produktif dan bersih, setidaknya untuk jenis pekerjaan yang saya lakukan (aplikasi web berbasis Java).
sumber
Singleton adalah sebuah pola dan dapat digunakan atau disalahgunakan seperti alat lainnya.
Bagian buruk dari singleton umumnya adalah pengguna (atau harus saya katakan penggunaan singleton yang tidak tepat untuk hal-hal yang tidak dirancang untuk dilakukan). Pelaku terbesar menggunakan singleton sebagai variabel global palsu.
sumber
Ketika Anda menulis kode menggunakan lajang, katakanlah, logger atau koneksi database, dan setelah itu Anda menemukan Anda membutuhkan lebih dari satu log atau lebih dari satu database, Anda dalam masalah.
Lajang membuatnya sangat sulit untuk berpindah dari mereka ke benda biasa.
Juga, terlalu mudah untuk menulis singleton yang tidak aman.
Daripada menggunakan lajang, Anda harus melewati semua objek utilitas yang diperlukan dari fungsi ke fungsi. Itu bisa disederhanakan jika Anda membungkus semuanya menjadi objek pembantu, seperti ini:
sumber
Masalah dengan lajang adalah masalah peningkatan cakupan dan karena itu penggandengan . Tidak dapat disangkal bahwa ada beberapa situasi di mana Anda memang membutuhkan akses ke satu contoh, dan itu dapat dilakukan dengan cara lain.
Saya sekarang lebih suka mendesain di sekitar wadah inversi kontrol (IOC) dan memungkinkan masa hidup dikontrol oleh wadah. Ini memberi Anda manfaat dari kelas-kelas yang bergantung pada instance untuk tidak menyadari fakta bahwa ada satu instance. Masa hidup singleton dapat diubah di masa depan. Setelah contoh seperti yang saya temui baru-baru ini adalah penyesuaian yang mudah dari single threaded ke multi-threaded.
FWIW, jika PIA ketika Anda mencoba untuk mengujinya maka itu akan menjadi PIA ketika Anda mencoba untuk debug, memperbaiki bug atau meningkatkannya.
sumber
Artikel terbaru tentang hal ini oleh Chris Reath di Coding Tanpa Komentar .
Catatan: Pengodean Tanpa Komentar tidak lagi valid. Namun, artikel yang ditautkan telah dikloning oleh pengguna lain.
http://geekswithblogs.net/AngelEyes/archive/2013/09/08/singleton-i-love-you-but-youre-bringing-me-down-re-uploaded.aspx
sumber
Lajang TIDAK buruk. Ini hanya buruk ketika Anda membuat sesuatu yang unik secara global yang tidak unik secara global.
Namun, ada "layanan lingkup aplikasi" (pikirkan sistem pesan yang membuat komponen berinteraksi) - PANGGILAN ini untuk singleton, "MessageQueue" - kelas yang memiliki metode "SendMessage (...)".
Anda kemudian dapat melakukan yang berikut dari semua tempat:
MessageQueue.Current.SendMessage (MailArrivedMessage (...)) baru;
Dan, tentu saja, lakukan:
MessageQueue.Current.RegisterReceiver (ini);
di kelas yang mengimplementasikan IMessageReceiver.
sumber
Terlalu banyak orang menaruh benda yang tidak aman dalam pola tunggal. Saya telah melihat contoh-contoh DataContext ( LINQ to SQL ) yang dilakukan dalam pola tunggal, meskipun fakta bahwa DataContext tidak aman dan murni objek unit kerja.
sumber
Ini satu hal lagi tentang lajang yang belum ada yang mengatakan.
Dalam kebanyakan kasus "singletonity" adalah detail implementasi untuk beberapa kelas daripada karakteristik antarmuka-nya. Pembalikan Wadah Kontrol dapat menyembunyikan karakteristik ini dari pengguna kelas; Anda hanya perlu menandai kelas Anda sebagai singleton (dengan
@Singleton
anotasi di Jawa misalnya) dan hanya itu; IoCC akan melakukan sisanya. Anda tidak perlu menyediakan akses global ke instance singleton Anda karena akses sudah dikelola oleh IoCC. Dengan demikian tidak ada yang salah dengan IoC Singletons.GoF Singletons berlawanan dengan IoC Singletons seharusnya mengekspos "singletonity" di antarmuka melalui metode getInstance (), dan agar mereka menderita dari semua yang dikatakan di atas.
sumber
Lajang tidak jahat, jika Anda menggunakannya dengan benar & minimal . Ada banyak pola desain bagus lainnya yang menggantikan kebutuhan singleton di beberapa titik (& juga memberikan hasil terbaik). Tetapi beberapa programmer tidak menyadari pola-pola yang baik & menggunakan singleton untuk semua kasus yang membuat singleton jahat bagi mereka.
sumber
Pertama kelas dan kolaboratornya harus terlebih dahulu melakukan tujuan yang dimaksudkan daripada berfokus pada tanggungan. Manajemen siklus hidup (ketika instance dibuat dan ketika mereka keluar dari ruang lingkup) tidak boleh menjadi bagian dari tanggung jawab kelas. Praktik terbaik yang diterima untuk ini adalah membuat atau mengonfigurasi komponen baru untuk mengelola dependensi menggunakan injeksi dependensi.
Seringkali perangkat lunak menjadi lebih rumit, masuk akal untuk memiliki beberapa instance independen dari kelas Singleton dengan status yang berbeda. Mengkomit kode untuk mengambil singleton salah dalam kasus seperti itu. Menggunakan
Singleton.getInstance()
mungkin ok untuk sistem kecil sederhana tetapi tidak bekerja / skala ketika seseorang mungkin membutuhkan contoh berbeda dari kelas yang sama.Tidak ada kelas yang harus dianggap sebagai singleton melainkan yang seharusnya merupakan aplikasi penggunaannya atau bagaimana itu digunakan untuk mengkonfigurasi tanggungan. Untuk yang cepat dan buruk ini tidak masalah - hanya luke hard coding mengatakan path file tidak masalah tetapi untuk aplikasi yang lebih besar ketergantungan seperti itu harus diperhitungkan dan dikelola dengan cara yang lebih tepat menggunakan DI.
Masalah yang disebabkan oleh singleton dalam pengujian adalah gejala dari kasus / lingkungan penggunaan tunggal berkode keras. Test suite dan banyak tes adalah masing-masing individu dan memisahkan sesuatu yang tidak kompatibel dengan pengkodean tunggal.
sumber
Karena mereka pada dasarnya adalah variabel global berorientasi objek, Anda biasanya dapat merancang kelas Anda sedemikian rupa sehingga Anda tidak membutuhkannya.
sumber