SE(たぶん)の雑感記

一応SEやっている筆者の思ったことを書き連ねます。会計学もやってたので、両方を生かした記事を書きたいと考えています。 でもテーマが定まってない感がすごい。

if文について思うこと(良くない使い方)

プログラミングするなら、if文は必ず使いますよね。
意味は分かりやすいですよね、if文。

ざっくりしたif文説明

if (明日休み?) {
    //休み
    夜更かし();
} else {
    //休みじゃないとき
    寝る();
}

きっと、「今から寝るか」決めているのでしょう。

「明日休み?」の部分がboolean(真偽値)で、その判定結果で「夜更かしする」か「寝る」か決めています。 これだけなら、とってもわかりやすいですね。

複雑にしてみる

今から寝るかどうか、ほかの決定基準が増えました。

if (新しいゲームを買ってきた?) {
    //ゲームは最優先だ!
    夜更かし();

    ゲームする();
} else if (新しい本買ってきた?) {
    if (明日休み?) {
        //休み
        夜更かし();

        本を読む();
    } else {
        //休みじゃないとき
        寝る();
    }
} else if (飲みに誘われた?) {
    if (相手は仲のいい友達?) {
        夜更かし();

        飲みに行く();
    } else {
        寝る();
    }
}

なんか、ごちゃごちゃしてきましたね。
日本語で書いているので、まだ意味は分かりますね。
要するに、やりたいことがあったら、それを優先して行っています。
やることで、判断基準を変えてみています。







考察

上の、「複雑にしてみる」のif文、実は最初のif文と意味が変わっているんですよね。
気付いたでしょうか?

変わった内容は、

ゲームも本も買わず、飲みにも誘われなかったら、何もしなくなっている

です。

ifが乱立することで、ソースの見通しが悪くなったのです。

他の人がソースを見た場合

「複雑にしてみる」のif文。はたしてこれは「仕様」でしょうか?
この変更を知らない第三者から見て、それは判定できません。

プログラムっぽく書いてみる

public void SettingmeState(Person me) {

    if (me.HasBuyNewVideoGame()) {
        //ゲームは最優先だ
        me.WantToSleep = false;

        me.PlayVideoGame();
    } else if (me.HasBuyNewBook()) {
        if (Tomorrow.IsHoliday(me)) {
            //休み
            me.WantToSleep = false;

            me.ReadBook();
        } else {
            //休みじゃないとき
            me.WantToSleep = true;
        }
    } else if (me.InviteToEat()) {
        var invite = inviteRepository.FindByInvitee(me);
        if (invite.IsFriend) {
            me.WantToSleep = false;

            me.GoToEat();
        } else {
            me.WantToSleep = true;
        }
    }
}

まぎれもないクソコードが誕生した…

問題点は、

  • このメソッドは何がしたいのか、メソッド名から読み取れない
    SettingMyStateってなんだよ…
  • 「my.WantToSleep」が設定されないことがある
    このメソッドを呼び出した後、寝るのか起きてるのかわからない

じゃあどうすれば…!

なんというか、適当に書いちゃったおかげで、正解を用意していないのですが…
悪いところを列挙すると、こんな感じでしょうか。

  • 処理内で、「寝るかどうか」の判定と「次に何をするか」の判定を行っている
  • このメソッドが何をしたいのかわからない
  • 結果返そうとしているのに、戻り値がない
  • if文多い

ここは、「次に何をしたいのか」という観点で解決してみます。

public interface IAction{

    void Execute();
}

public IAction NextAction(Person me){

    if (me.HasBuyNewVideoGame()) {
        //ゲームは最優先だ
        return new PlayAction();
    } else if (me.HasBuyNewBook()) {
        if (Tomorrow.IsHoliday(me)) {
            return new ReadBookAction();        
        }
    } else if (me.InviteToEat()) {
        var invite = inviteRepository.FindByInvitee(me);
        if (invite.IsFriend) {
            return new EatAction();
        } 
    }

    //やることが無かったら寝る
    return new SleepAction();
}

前よりは、「いつ何がしたいのか」と「いつ寝るのか」が明確になったように思います。
(そもそも、何をしたいかぐらいPersonが返せよ、とは思う)

if文はわかりやすいけど、使い過ぎには注意、というお話です。