前回は「右に長いコードは書かない」というお話をしました。では右に長いコードになってしまうときはどのように対処していけばいいのか,というお話を今回はしていきたいと思います。
改行しても右に長いコードには変わりない
改行した場合
まず最初に考えられる対処法は,改行するということですね。前回の右に長いコードを改行してみましょう。
//改行しても右に長いコードには変わりない ProductSqlServer.GetProducts() .Where(x => x.Price > 100) .ToList().ForEach(x => dtos.Add(new ProductDto(x)));
ただ,改行しても左から右に読んでいく量は同じなので,読んでいく量,脳みそに覚えておかないといけない量は特に変化がなく,大した改善にはなっていませんね。まぁ改行しないよりは,している方がマシ程度です。ですので,改行したから右に長いコードではなくなったということにはなりません。
どこかで切る
対処法としては,どこかで切る必要があります。例えば,ToList()まででいったん切ります。次のように,ToList()までの結果をproducts1に受けて,その後,products1.ForEach・・・とします。
var products1 = ProductSqlServer.GetProducts().Where(x => x.Price > 100).ToList(); products1.ForEach(x => dtos.Add(new ProductDto(x)));
こうすると,いったんToList()が終わった段階で思考を切ることができますね。いままでは,ProductSqlServerをGetProducts()して,Whereで100より大きいやつをListにして,それを回してProductDtoにする・・・とすべてを脳みその中に放り込んでいたものを,「Priceが100より大きいリストがproducts1」ということで,ここで思考を切ることができ,脳みそは,いったん忘れて,次のForEachに移ることができます。こういった感じで,思考をいったん切ることで,読みやすさは大きく変わります。
ToListが冗長
先ほどはToListの部分で切ることで,思考を切ることができて,右に長いコードがある程度改善しました。ただ,この例でいうと,このToList()自体が,冗長なので,その部分も解説しておきます。
//ListのForEachをするためにToListするのは冗長 var products1 = ProductSqlServer.GetProducts().Where(x => x.Price > 100).ToList(); products1.ForEach(x => dtos.Add(new ProductDto(x)));
このToListがForEachするために変換しているとすれば,非常に冗長です。要するに,products1.ForEachのForEachは,List<T>にだけ存在するメソッドなので,Whereを取得されたIEnumerable<T>をList<T>に変換していますが,ListのForEachではなく,通常のforeach文を使えば,Listに変換する必要がなくなるので,ToListをする必要がありません。ですので,List<T>のForEachをするためだけにToListを呼び出しているのであれば,これも無駄に右に長くしているコードの元凶になっているので,あえてToListする必要はありません。
隣のとなりまでしか訪ねない
①のようにToListをやめて,Whereの結果をproduct2に受けていったん切ります。
//GOOD:隣のとなりまでしか訪ねない var products2 = ProductSqlServer.GetProducts().Where(x => x.Price > 100);//① foreach (var product in products2) //② { dtos.Add(new ProductDto(product)); }
次に②のように通常のforeach文を使用してproduct2をぐるぐる回してdtos.Add・・・の部分を実施すれば,結果は同じになります。こうすることで,ProductSqlServerから始まる文は,GetProductsのWhereの部分でいったん完結しているので,ProductSqlServerの隣の隣に収まっているといえます。そこまで完結させておいて,次はそれをぐるぐる回す,②の部分に移るので,脳みそで覚えておくことは,格段に少なくなっているといえます。隣のとなりまでしか訪ねないということを目安にして,うまく文を切っていくことを検討してみてください。
ラムダを覚えても右に長くしない
今回解説した通り,右に長いコードになる場合は,どこかで切れないかを考えてみてください。ラムダ式等を覚えたり,新しい書き方を覚えたりすると,使いたくなって,つい右に長いコードを書きがちです。新しい書き方がすべてにおいて正義ではないし,最初に言った通り,何秒で理解できるかが大事なので,新しい書き方だからOKという感じではなく,総合的に判断して使っていただいた方がいいと思います。
右に長くなるという事はクラスをうまく分割できていない
最後に余談ですが,本書はオブジェクト指向に関しては触れずに,シンプルに書き方を解説することを目的としていますが,右に長くなるコードの原因の1つとして,うまくクラスが分割できていないという可能性があります。例えば今回の例でいえば,ProductSqlServerのGetProductsでPriceの引数を受ける関数があれば,
ProductSqlServer.GetProducts().Where(x => x.Price > 100)
の部分を,
ProductSqlServer.GetProductsByPrice(100);
とすることもできます。これだとお隣さんに尋ねるだけなので,大変シンプルに読むことができます。今回はオブジェクト指向やデザインパターンの話はしないので,クラス分割にはあまり言及しませんが,そういった部分も原因としてはあると思うので,本書以外にも,そういった部分を勉強していただいてもいいかと思います。