Baru-baru ini, saya lebih suka memetakan 1-1 hubungan menggunakan Dictionaries
daripada Switch
pernyataan. Saya merasa sedikit lebih cepat untuk menulis dan proses mental lebih mudah. Sayangnya, saat memetakan ke instance objek baru, saya tidak ingin mendefinisikannya seperti ini:
var fooDict = new Dictionary<int, IBigObject>()
{
{ 0, new Foo() }, // Creates an instance of Foo
{ 1, new Bar() }, // Creates an instance of Bar
{ 2, new Baz() } // Creates an instance of Baz
}
var quux = fooDict[0]; // quux references Foo
Mengingat konstruk itu, saya telah membuang siklus CPU dan memori membuat 3 objek, melakukan apa pun yang mungkin mengandung konstruktor mereka, dan akhirnya hanya menggunakan salah satu dari mereka. Saya juga percaya bahwa memetakan objek lain fooDict[0]
dalam hal ini akan menyebabkan mereka merujuk hal yang sama, daripada membuat contoh baru Foo
seperti yang dimaksudkan. Solusinya adalah dengan menggunakan lambda sebagai gantinya:
var fooDict = new Dictionary<int, Func<IBigObject>>()
{
{ 0, () => new Foo() }, // Returns a new instance of Foo when invoked
{ 1, () => new Bar() }, // Ditto Bar
{ 2, () => new Baz() } // Ditto Baz
}
var quux = fooDict[0](); // equivalent to saying 'var quux = new Foo();'
Apakah ini sampai pada titik di mana itu terlalu membingungkan? Sangat mudah untuk melewatkannya ()
pada akhirnya. Atau apakah pemetaan ke fungsi / ekspresi merupakan praktik yang cukup umum? Alternatifnya adalah menggunakan sakelar:
IBigObject quux;
switch(someInt)
{
case 0: quux = new Foo(); break;
case 1: quux = new Bar(); break;
case 2: quux = new Baz(); break;
}
Doa mana yang lebih bisa diterima?
- Kamus, untuk pencarian lebih cepat dan lebih sedikit kata kunci (huruf besar dan kecil)
- Switch: Lebih umum ditemukan dalam kode, tidak memerlukan penggunaan fungsi <> objek untuk tipuan.
sumber
fooDict[0] is fooDict[0]
). dengan kedua lambda dan saklar ini tidak terjadiJawaban:
Itu hal yang menarik dari pola pabrik . Saya suka kombinasi Kamus dan ekspresi lambda; itu membuat saya melihat wadah itu dengan cara yang baru.
Saya mengabaikan kekhawatiran dalam pertanyaan Anda tentang siklus CPU seperti yang Anda sebutkan di komentar bahwa pendekatan non-lambda tidak memberikan apa yang Anda butuhkan.
Saya pikir salah satu pendekatan (beralih vs. Kamus + lambda) akan baik-baik saja. Satu-satunya batasan adalah bahwa dengan menggunakan Kamus, Anda membatasi jenis input yang dapat Anda terima untuk menghasilkan kelas yang dikembalikan.
Menggunakan pernyataan switch akan memberi Anda lebih banyak fleksibilitas pada parameter input. Namun, jika ini menjadi masalah, Anda bisa membungkus Kamus di dalam metode dan memiliki hasil akhir yang sama.
Jika ini baru untuk tim Anda, komentari kodenya dan jelaskan apa yang terjadi. Meminta peninjauan kode tim, menuntun mereka melalui apa yang telah dilakukan dan membuat mereka menyadarinya. Selain itu, terlihat baik-baik saja.
sumber
case 0: quux = new Foo(); break;
menjadicase 0: return new Foo();
yang sejujurnya mudah ditulis dan jauh lebih mudah dibaca daripada{ 0, () => new Foo() }
C # 4.0 memberi Anda
Lazy<T>
kelas, yang mirip dengan solusi kedua Anda sendiri, tetapi berteriak "inisialisasi malas" lebih eksplisit.sumber
Secara gaya saya pikir keterbacaan sama di antara mereka. Lebih mudah untuk melakukan injeksi ketergantungan dengan
Dictionary
.Jangan lupa bahwa Anda harus memeriksa apakah kunci ada saat menggunakan
Dictionary
, dan harus memberikan cadangan jika tidak.Saya lebih suka
switch
pernyataan untuk jalur kode statis, danDictionary
untuk jalur kode dinamis (di mana Anda dapat menambah atau menghapus entri). Kompiler mungkin dapat melakukan beberapa optimasi statis denganswitch
yang tidak dapat dilakukan denganDictionary
.Menariknya,
Dictionary
pola ini adalah apa yang kadang-kadang dilakukan orang dengan Python, karena Python tidak memilikiswitch
pernyataan. Kalau tidak, mereka menggunakan rantai if-else.sumber
Secara umum, saya tidak akan memilih keduanya.
Apa pun yang dikonsumsi ini harus bekerja dengan a
Func<int, IBigObject>
. Kemudian sumber pemetaan Anda dapat berupa Kamus atau metode yang memiliki pernyataan beralih atau panggilan layanan web atau beberapa pencarian file ... apa pun.Sedangkan untuk implementasi, saya lebih suka Kamus karena itu lebih mudah dire-refored dari 'kamus kode keras, kunci pencarian, hasil kembali' untuk 'memuat kamus dari file, kunci pencarian, hasil kembali'.
sumber