İkilem
Nesneye yönelik uygulamalar hakkında birçok iyi uygulama kitabı okudum ve okuduğum hemen hemen her kitabın, numaraların kod kokusu olduğunu söyledikleri bir parçası vardı. Sanırım sayılar geçerli olduğunda açıkladıkları kısmı kaçırmışlar.
Gibi, enums bir kod kokusu DEĞİL ve aslında geçerli bir yapı DEĞİL yönergeleri ve / veya kullanım durumları arıyorum .
Kaynaklar:
"UYARI Genel bir kural olarak, numaralandırmalar kod kokularıdır ve polimorfik sınıflara yeniden konulmalıdır. [8]" Seemann, Mark, .Net, 2011, s. 342
[8] Martin Fowler ve ark., Yeniden Düzenleme: Mevcut Kod Tasarımının Geliştirilmesi (New York: Addison-Wesley, 1999), 82.
bağlam
İkilemin nedeni bir ticaret API'sı. Bu yöntemle bana bir Tick verileri akışı veriyorlar:
void TickPrice(TickType tickType, double value)
nerede enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }
Değişiklikleri kırmak bu API için yaşam biçimi olduğundan, bu API etrafında bir sarmalayıcı yapmayı denedim. Benim sarıcı üzerinde her son alınan kene türünün değerini takip etmek istedim ve bunu Ticktypes bir Sözlük kullanarak yaptım:
Dictionary<TickType,double> LastValues
Bana göre bu, anahtar olarak kullanıldıklarında bir enumun doğru kullanımı gibi görünüyordu. Ama ikinci düşüncelerim var, çünkü bu koleksiyona dayalı bir karar verdiğim bir yerim var ve anahtar ifadesini nasıl ortadan kaldırabileceğimi düşünemiyorum, bir fabrika kullanabilirim ama o fabrika hala bir ifadeyi bir yerde değiştir. Bana sadece bir şeyleri hareket ettiriyor gibiydim ama yine de kokuyor.
DON'T'ları bulmak kolay, ama DO'lar, o kadar kolay değil ve insanlar uzmanlıklarını, artılarını ve eksilerini paylaşabilirlerse memnun olurum.
Düşüne taşına verilen kararlar
Bazı kararlar ve eylemler bunlara dayanmaktadır TickType
ve enum / switch ifadelerini ortadan kaldırmanın bir yolunu düşünemiyorum. Aklıma gelen en temiz çözüm bir fabrika kullanmak ve bir uygulamaya dayanmaktır TickType
. O zaman bile hala bir arabirimin uygulanmasını döndüren bir anahtar deyimim olacak.
Aşağıda, yanlış bir numaralandırma kullanıyor olabileceğimden şüphe duyduğum örnek sınıflardan biri var:
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 ...