Dilema
Saya telah membaca banyak buku praktik terbaik tentang praktik berorientasi objek, dan hampir setiap buku yang saya baca memiliki bagian di mana mereka mengatakan bahwa enum adalah bau kode. Saya pikir mereka telah melewatkan bagian di mana mereka menjelaskan kapan enum valid.
Karena itu, saya mencari pedoman dan / atau kasus penggunaan di mana enum BUKAN bau kode dan pada kenyataannya konstruk yang valid.
Sumber:
"PERINGATAN Sebagai patokan, enum adalah bau kode dan harus di refactored ke kelas polimorfik. [8]" Seemann, Mark, Dependency Injection di .Net, 2011, hlm. 342
[8] Martin Fowler et al., Refactoring: Meningkatkan Desain Kode yang Ada (New York: Addison-Wesley, 1999), 82.
Konteks
Penyebab dilema saya adalah API perdagangan. Mereka memberi saya aliran data Tick dengan mengirimkan melalui metode ini:
void TickPrice(TickType tickType, double value)
dimana enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }
Saya sudah mencoba membuat pembungkus di sekitar API ini karena melanggar perubahan adalah cara hidup untuk API ini. Saya ingin melacak nilai dari setiap jenis centang yang terakhir diterima pada bungkus saya dan saya telah melakukannya dengan menggunakan Kamus ticktypes:
Dictionary<TickType,double> LastValues
Bagi saya, ini tampak seperti penggunaan enum yang tepat jika mereka digunakan sebagai kunci. Tetapi saya memiliki pikiran kedua karena saya memiliki tempat di mana saya membuat keputusan berdasarkan koleksi ini dan saya tidak bisa memikirkan cara bagaimana saya bisa menghilangkan pernyataan switch, saya bisa menggunakan pabrik tetapi pabrik itu masih memiliki beralih pernyataan di suatu tempat. Tampaknya bagi saya bahwa saya hanya memindahkan barang-barang tetapi masih berbau.
Sangat mudah untuk menemukan JANGAN enum, tetapi DO, tidak mudah, dan saya akan menghargai jika orang dapat berbagi keahlian, pro dan kontra.
Pikiran kedua
Beberapa keputusan dan tindakan didasarkan pada ini TickType
dan sepertinya saya tidak bisa memikirkan cara untuk menghilangkan pernyataan enum / switch. Solusi terbersih yang dapat saya pikirkan adalah menggunakan pabrik dan mengembalikan implementasi berdasarkan TickType
. Bahkan kemudian saya masih akan memiliki pernyataan switch yang mengembalikan implementasi antarmuka.
Di bawah ini adalah salah satu kelas sampel di mana saya ragu bahwa saya mungkin menggunakan enum yang salah:
public class ExecutionSimulator
{
Dictionary<TickType, double> LastReceived;
void ProcessTick(TickType tickType, double value)
{
//Store Last Received TickType value
LastReceived[tickType] = value;
//Perform Order matching only on specific TickTypes
switch(tickType)
{
case BidPrice:
case BidSize:
MatchSellOrders();
break;
case AskPrice:
case AskSize:
MatchBuyOrders();
break;
}
}
}
enums as switch statements might be a code smell ...