Buraya bir adım atacağım. Kodun seçici ayrıntılarına yoğunlaşıyorsunuz ancak büyük resmi kaçırıyorsunuz. Örnek döngülerinize bir göz atalım:
int offset = 0;
while(true)
{
Record r = Read(offset);
if(r == null)
{
break;
}
// do work
offset++;
}
Bu kodun anlamı nedir ? Anlamı "bir dosyadaki her kayıt için biraz çalışma". Ancak kod böyle görünmüyor . Kod "ofseti koru. Bir dosya açın. Son koşulu olmayan bir döngü girin. Bir kayıt okuyun. Boşluk testi yapın." Bütün bunlar işe başlamadan önce! Sormanız gereken soru şudur: " Bu kodun görünümünü anlamıyla eşleştirebilir miyim? " Bu kod şöyle olmalıdır:
foreach(Record record in RecordsFromFile())
DoWork(record);
Şimdi kod niyetinde olduğu gibi okunur. Mekanizmalarınızı anlambiliminizden ayırın . Orijinal kodunuzda, mekanizmayı - döngünün ayrıntıları - anlambilim ile - her kayıt için yapılan işi karıştırırsınız.
Şimdi uygulamak zorundayız RecordsFromFile()
. Bunu uygulamanın en iyi yolu nedir? Kimin umrunda? Kimsenin bakacağı kod bu değil. Temel mekanizma kodu ve on satır uzunluğunda. İstediğiniz gibi yazın. Buna ne dersin?
public IEnumerable<Record> RecordsFromFile()
{
int offset = 0;
while(true)
{
Record record = Read(offset);
if (record == null) yield break;
yield return record;
offset += 1;
}
}
Artık tembel olarak hesaplanmış bir kayıt dizisini manipüle ettiğimize göre, her türlü senaryo mümkün hale geliyor:
foreach(Record record in RecordsFromFile().Take(10))
DoWork(record);
foreach(Record record in RecordsFromFile().OrderBy(r=>r.LastName))
DoWork(record);
foreach(Record record in RecordsFromFile().Where(r=>r.City == "London")
DoWork(record);
Ve bunun gibi.
Bir döngü yazdığınızda, kendinize "bu döngü bir mekanizma veya kodun anlamı gibi mi okuyor?" Diye sorun. Cevap "bir mekanizma gibi" ise, o mekanizmayı kendi yöntemine taşımaya çalışın ve anlamı daha görünür hale getirmek için kodu yazın.