リーダブルコード

C#リーダブルコード #05_IFとELSEがある時は肯定系をIF否定形をELSEにする

ここからは判断系をやっていきます。if文がメインになってきます。

ProductSqlServerにExistsメソッドの追加

1つ目の解説に入る前に,ProductSqlServerにExistsメソッドを追加しておきます。存在チェックのイメージなので,あればTrue,なければFalseとなるはずですが,ここでは簡易的に必ずTrueを返却するようにしています。ここではExistsメソッドがあるということが重要です。

public static class ProductSqlServer
{
    public static IEnumerable GetProducts()
    {
        var result = new List();
        result.Add(new Product(10, "p10", 100, 2));
        result.Add(new Product(20, "p20", 200, 6));
        result.Add(new Product(30, "p30", 300, 4));
        return result;
    }

    public static bool Exists()
    {
        return true;
    }
}

IFとELSEがある場合はIFはTrueの時に入る

それでは本題に入りましょう。IFとELSEがある場合はIFはTrueの時に入るというお話です。「肯定系の時にif文の中に入ろうね!」というお話です。先ほど作成した,ProductSqlServerのExistsを呼び出しています。ProductSqlServerにデータがあったらTrueになるようなケースを考えてみてください。

//判断(IF分)
//IFとELSEがある場合はIFはTrueの時に入る
private void IFとELSEがある場合はIFはTrueの時に入る()
{
    //GOOD:肯定系で中に入る
    if (ProductSqlServer.Exists())
    {
        //肯定系(データがある時)
        Console.WriteLine("処理...");
    }
    else
    {
        //否定形(データがない時)
        Console.WriteLine("処理...");
    }
}

この場合,Existsなので,存在しているか?ということなので,存在している場合は肯定系ということになります。このように,存在している場合にif文の中に入り,否定形(存在していない)場合にelseに入るようにします。これはご説明するまでもなく,脳みその構造上,誰もがその方がしっくりくると思います。これを逆にすると,気持ちが悪いコードになります。

BAD:Elseが肯定系になっている

先ほどの例を逆にした場合は次のようになります。

if (!ProductSqlServer.Exists())
{
}
else
{
    //BAD:Elseが肯定系になっている
}

一行目は否定を表す「!」ビックリマーク「!ProductSqlServer.Exists()」が付いていることに注意してください。Existsの否定形です。否定形の場合にif文に入り,ExistsがTrueの時にelseに入っています。これもご説明するまでもなく,気持ち悪さと読みづらさを感じていただけると思います。後述しますが,否定の否定はBADコードです。Existsに「!」をつけて,否定しておいて,さらにelseで否定するわけですから,「存在していなかった時ではないとき」という否定の否定になるので,大変読みづらいコードになります。

GOOD:IFしかないときは否定形でもOK

if文しかない場合は,否定形でもOKです。次のようなパターンです。

//GOOD:IFしかないときは否定形でもOK
if (ProductSqlServer.Exists())
{
}

//GOOD:IFしかないときは否定形でもOK
if (!ProductSqlServer.Exists())
{
}

if文が1つしかない場合は,肯定系でも否定形でもどちらでもOKです。1つしかないわけですから,「ある時」でも「ない時」でもどちらでも脳みそは混乱しません。ですので,単発の場合,1つしか判断が無い場合は気にせずどちらでも書いてください。

GOOD:boolは肯定系で返す

今度は呼ばれる側「ProductSqlServer側」を見てみましょう。最初に書いたExistsメソッドはGOODです。boolを返却する場合は,普通に考えてこちらがTrueだろうというものをTrueにする必要があります。IsNormalなら正常の時にTrueだし,データ有無ならデータありの時にTrueなわけです。boolを返却する際は,肯定系の方を積極的に使ってください。

public static class ProductSqlServer
{
    ・・・

    //GOOD:boolは肯定系で返す
    public static bool Exists()
    {
        return true;
    }

    //NOTBAD:否定形boolを返さない
    public static bool NotExists()
    {
        return true;
    }
}

NOTBAD:否定形boolを返さない

NotExistsのようなメソッドは積極的に書かない方がいいでしょう。脳みその構造上,「ある時」と「ない時」であれば,「ある時」を基準にした方が,すんなり受け入れられると思います。ただし,絶対ダメとも思います。「ない時」が自然な場合もあります。積極的に「無いこと」を調べたいようなシナリオの場合はNotExistsが自然な場合もあると思うので,NOTBADとしています。

NOTBAD:データがないとき

先ほど作成したNotExistsを使うときはこのようになります。

//NOTBAD:データがないとき
if (ProductSqlServer.NotExists())
{
}

このような場合も絶対ダメとは言えませんね。

BAD:否定の否定はしない

先ほど少し触れましたが,「否定の否定はしない」ということは大事なことです。私の場合はこれをされると,脳みそが熱くなり,やがて停止してしまいます。

//BAD:否定の否定はしない
if (!ProductSqlServer.NotExists())
{
    //データがなくないとき???
}

NotExistsという否定系のメソッドに対して,「!」で否定しています。「データがなくないとき」と言われても「???」となってしまいます。データがなくないということは,「データがある」ということなので,そこは素直に「データがある」と言いましょう。恋愛のように「君みたいな子,嫌いじゃない」みたいな表現はやめましょう。

リーダブルコードC#

#01_はじめに

#02_プロジェクトの作成
#03_右に長いコードを書かない_隣のとなりまでしか訪ねない
#04_隣のとなりまで_右スクロールより縦スクロールの方がいい
#05_IFとELSEがある時は肯定系をIF否定形をELSEにする
#06_比較する時は変数を左_定数を右にする
#07_複数の比較を1回のif文でやらない
#08_booの比較でTrueやFalseを書かない
#09_否定の否定はしない
#10_型チェックはasを使う
#11_メソッドはできるだけ早く抜ける_返却する値を無駄に変数に入れない
#12_対象外の時はすぐに抜ける
#13_都合が悪いケースはガードする
#14_必ずやりたい処理はfinallyを使う
#15_比較演算子はできるだけクラスにさせる
#16_ifの中括弧の省略はしない
#17_if文のリーダブルコードまとめ
#18_名前の付け方
#19_意図が明確な名前を付ける
#20_名前は素直に付ける_連想ゲーム的な名前を付けない
#21_1つの事しかしていなければ短い名前でも理解できる
#22_長いクラス名の扱い方
#23_単数形と複数形で表現する
#24_対になる言葉の組み合わせを決めておく
#25_業務で使う名前は統一する
#26_名前を統一するための辞書ツール作成
#27_メンバー変数にアンダーバーを付ける
#28_ハンガリアン記法を使わない
#29_メソッド内の変数をメソッド最初に全部宣言しない
#30_メソッド内の変数は直前に宣言する
#31_ループの変数はループ内で宣言する
#32_変数を使いまわさない
#33_boolの戻り値はどちらがTrueかをわかるようにする
#34_解放が必要なオブジェクトにはusingを使う
#35_varを推奨する場合
#36_メソッド名の付け方
#37_voidとFunctionを意識する
#38_インテリセンスを意識した名前にする
#39_生成メソッドはCreate_型変換はToを使う
#40_無駄に変数に入れて返却しない
#41_重複をなくす
#42_リージョンで区切らない
#43_アクセス修飾子とsealedを付ける
#44_クラス名はソリューションエクスプローラーで並べることを意識する
#45_クラス名は名詞か名詞句で命名する
#46_クラス名で継承元や特性を表現する
#47_メソッド内にコメントを書かない
#48_分かりづらい部分はメソッド化をしてメソッド名で想いを伝える
#49_コードを読んだ人が「えっ?」と思うことが予想される場所にだけコメントを付ける
#50_コメントで悪いコードを取り繕うことはできない
#51_未実装機能はTODOコメントを書く
#52_リーダブルコードまとめ