Kami memiliki kelas yang menyimpan informasi konfigurasi untuk aplikasi. Itu dulu tunggal. Setelah beberapa tinjauan arsitektural, kami diberitahu untuk menghapus singleton tersebut. Kami memang melihat beberapa keuntungan dari tidak menggunakan tunggal dalam pengujian unit karena kami dapat menguji konfigurasi yang berbeda sekaligus.
Tanpa tunggal, kita harus meneruskan contoh di mana-mana dalam kode kita. Ini menjadi sangat berantakan jadi kami menulis pembungkus tunggal. Sekarang kita mem-porting kode yang sama ke PHP dan .NET, saya bertanya-tanya apakah ada pola yang lebih baik yang dapat kita gunakan untuk objek konfigurasi.
sumber
Cara terbaik adalah menggunakan pola Pabrik. Saat Anda membuat instance baru dari kelas Anda (di pabrik), Anda dapat memasukkan data 'global' ke dalam objek yang baru dibangun, baik sebagai referensi ke satu instance (yang Anda simpan di kelas pabrik) atau dengan menyalin yang relevan data ke objek baru.
Semua objek Anda kemudian akan berisi data yang digunakan untuk hidup di singleton. Saya rasa tidak ada banyak perbedaan secara keseluruhan, tetapi ini dapat membuat kode Anda lebih mudah dibaca.
sumber
Saya mungkin menyatakan yang sudah jelas di sini, tetapi adakah alasan mengapa Anda tidak dapat menggunakan kerangka kerja injeksi ketergantungan seperti Spring atau Guice ? (Saya yakin Spring juga tersedia untuk .NET juga sekarang).
Dengan begitu, kerangka kerja dapat menyimpan satu salinan objek konfigurasi, dan kacang Anda (layanan, DAO, apa pun) tidak perlu khawatir mencarinya.
Ini adalah pendekatan yang biasanya saya ambil!
sumber
Jika Anda menggunakan Spring Framework , Anda bisa membuat kacang biasa. Secara default (atau jika Anda secara eksplisit mengatur
scope="singleton"
) hanya satu contoh kacang dibuat dan contoh itu dikembalikan setiap kali kacang digunakan dalam ketergantungan atau diambil melaluigetBean()
.Anda mendapatkan keuntungan dari instance tunggal, tanpa penggandengan pola Singleton.
sumber
Alternatifnya adalah menyampaikan apa yang Anda butuhkan alih-alih meminta objek untuk sesuatu.
sumber
jangan mengumpulkan tanggung jawab ke satu objek konfigurasi karena akan berakhir di objek yang sangat besar yang sulit dipahami dan rapuh.
Misalnya jika Anda membutuhkan parameter lain untuk kelas tertentu Anda mengubah
Configuration
objek, kemudian mengkompilasi ulang semua kelas yang menggunakannya. Ini agak bermasalah.Coba refactoring kode Anda untuk menghindari objek umum, global, dan besar
Configuration
. Meneruskan hanya parameter yang diperlukan ke kelas klien:harus diubah menjadi:
sebuah kerangka kerja injeksi ketergantungan akan membantu banyak di sini, tetapi tidak stricly diperlukan.
sumber
Anda dapat mencapai perilaku tunggal yang sama dengan menggunakan metode statis. Steve yegge menjelaskannya dengan sangat baik di posting ini .
sumber
Apakah kelas yang hanya berisi metode dan kolom statis mungkin? Saya tidak yakin persis seperti apa situasi Anda, tetapi mungkin ada baiknya untuk memeriksanya.
sumber
Tergantung pada tooling / framework, dll. Yang digunakan. Dengan alat injeksi ketergantungan / ioc, seseorang sering kali masih bisa mendapatkan kinerja / pengoptimalan tunggal dengan meminta wadah di / ioc menggunakan perilaku tunggal untuk kelas yang diperlukan - (seperti antarmuka IConfigSettings) dengan hanya membuat satu instance kelas. Ini masih bisa diganti untuk pengujian
Alternatifnya, seseorang dapat menggunakan pabrik untuk membuat kelas dan mengembalikan instance yang sama setiap kali Anda memintanya - tetapi untuk mengujinya, ia dapat mengembalikan versi stub / tiruan
sumber
Tinjau kemungkinan untuk membuat konfigurasi sebagai antarmuka panggilan balik. Jadi, kode sensitif konfigurasi Anda akan terlihat:
Kode system-init akan terlihat:
sumber
Anda dapat menggunakan framework injeksi dependensi untuk mengurangi kesulitan dalam meneruskan objek konfigurasi. Yang layak adalah ninject yang memiliki keuntungan menggunakan kode daripada xml.
sumber
Mungkin juga tidak terlalu bersih, tetapi Anda mungkin bisa meneruskan bit informasi yang ingin Anda ubah ke metode yang membuat singleton - daripada menggunakan
Anda dapat memanggil
createSingleton(Information info)
secara langsung pada startup aplikasi (dan dalam setUp-Methods dari tes unit).sumber
Lajang tidak jahat tetapi pola desainnya cacat. Saya memiliki kelas yang saya hanya ingin membuat satu contoh selama runtime tetapi ingin membuat beberapa contoh terisolasi selama pengujian unit untuk memastikan hasil deterministik.
D menggunakan Spring, dll, adalah pilihan yang sangat bagus tetapi bukan satu-satunya pilihan.
sumber