ここに戻ります。あなたはコードのきびきびとした詳細に集中しているが、大きな絵は見当たらない。ループの例の1つを見てみましょう。
int offset = 0;
while(true)
{
Record r = Read(offset);
if(r == null)
{
break;
}
// do work
offset++;
}
何ですか このコード意味はですか?意味は「ファイル内の各レコードに何らかの作業を行う」です。しかし、それはコードがどのように見えるかではありません。コードは「オフセットを維持します。ファイルを開きます。終了条件なしでループに入ります。レコードを読み取ります。ヌル性をテストします。」作業に着手する前にすべてのこと!あなたが尋ねるべき質問は、「このコードの外観をそのセマンティクスと一致させるにはどうすればよいですか?」です。このコードは次のようになります。
foreach(Record record in RecordsFromFile())
DoWork(record);
これで、コードは意図どおりになりました。 メカニズムをセマンティクスから分離する。元のコードでは、メカニズム-ループの詳細-セマンティクス-各レコードに対して行われる作業を混同します。
今、私たちは実装する必要があります RecordsFromFile()
。それを実装する最良の方法は何ですか? 誰も気にしない?これは誰もが見ているコードではありません。基本的なメカニズムコードであり、その10行の長さです。好きなように書いてください。これはどう?
public IEnumerable<Record> RecordsFromFile()
{
int offset = 0;
while(true)
{
Record record = Read(offset);
if (record == null) yield break;
yield return record;
offset += 1;
}
}
今、私たちは 遅延計算された一連のレコードをているので、あらゆる種類のシナリオが可能になります。
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);
等々。
ループを書くときはいつでも、「このループはメカニズムのように、またはコードの意味のように読まれますか?」と自問してください。答えが「メカニズムのようなもの」である場合、そのメカニズムを独自のメソッドに移動し、コードを記述して、意味をより明確にします。