https://qiita.com/jun1s/items/5f60bbb886626d897abc?utm_source=Qiitaニュース&utm_campaign=eddbec1c54-Qiita_newsletter_505_03_09_2022&utm_medium=email&utm_term=0_e44feaa081-eddbec1c54-34388437#メソッドを宣言的に書く
コードが意図をそのまま表しており、バグの入り込む余地がありません。
これまでのような宣言的なコードの書き方をしていくと、メソッドも宣言的に書けるようになっていきます。
メソッドの中身がreturn文だけになる感じです。
public class Logic1
{
private List<Uriage> _list;
public Logic1(List<Uriage> list)
{
_list = list;
}
public decimal GetUriageByItemCd(string itemCd)
{
return _list
.Where(uri => uri.ItemCd == itemCd)
.Sum(uri => uri.Value);
}
}
上記のような形まで宣言的に書ける場合、もっと省略して、メソッド自体を =>
を使って次のように書けます。
public class Logic1
{
private List<Uriage> _list;
public Logic1(List<Uriage> list)
{
_list = list;
}
public decimal GetUriageByItemCd(string itemCd) =>
_list
.Where(uri => uri.ItemCd == itemCd)
.Sum(uri => uri.Value);
}
なんだかかっこいい感じですが、慣れるまではぎょっとしてしまうかもしれませんね。
ループの中でDBにINSERTしているケースなど、「最終的な副作用自体が処理の主目的」であるケースがあります。 このような場合はもちろん、全てを宣言的に書くことはできません。
しかし、INSERTする前のデータの集計や整形処理などは宣言的に書き、最後にループを回してINSERTする部分だけforeachで書くなど、可能な限り宣言的に書く対応をした方が良いでしょう。
副作用がある部分以外の処理を宣言的に書いておく
// 絞り込み・グルーピング・集計処理
var list = listInput
.Where(row => 絞り込み条件)
.GrupBy(row => グルーピング条件)
.Select(group => 集計処理)
.ToList();
// DB保存用の写像変換
var listForDB = list.Select( row => DB用写像変換 ).ToList();
// DBへの保存
foreach (var row in listForDB)
{
InsertToDB(row);
}
上記のように目的ごとに段階を踏んで宣言的に記述しておくと(これをパイプ処理と言います)、もしこの後「DBに保存する際の変換処理に変更が入った」場合でも、その影響範囲を特定しやすくなります。
また、上記の処理と同時に帳票出力を行いたい場合でも、既存の処理に影響を与えずに処理を書くことができるでしょう。
帳票出力処理を後から追加
// 絞り込み・グルーピング・集計処理
var list = listInput
.Where(row => 絞り込み条件)
.GrupBy(row => グルーピング条件)
.Select(group => 集計処理)
.ToList();
// DB保存用の写像変換
var listForDB = list.Select( row => DB用写像変換 ).ToList();
// DBへの保存
foreach (var row in listForDB)
{
InsertToDB(row);
}
// 帳票出力用の写像変換
var listForReport list.Select( row => 帳票用写像変換 ).ToList();
// 帳票出力
foreach (var row in listForReport)
{
OutputReport(row);
}
もしDBへの保存処理の中に絞り込み処理とDB用写像変換を全部ループで書いていたら・・・と考えると、ぞっとしませんか?
もしループで書いていたら…ここに帳票出力処理を追加してください