はかせのラボ

私の頭の中を書いていく雑記ブログです

C++ 今日のリファクタリング ~マジックナンバー~

あいさつ

どうも、はかせです。
今回は久しぶりのリファクタリングです。

やったこと

マジックナンバーの掃除と冗長な書き方をしていたところの書き直しです。

えっ?これだけかって?
はい。これだけです。

いや私もこれだけだなんて思いたくないですよ?
ただ書き直してたらまぁマジックナンバーや冗長な書き方が出るわ出るわでorz

そんな感じで機能的にも見た目的にも一切進展がありません。
いつも通りですねw
ただそれだけだとあれなんで、
マジックナンバーについて書いてみたいと思います。

マジックナンバー

直訳すると魔法の数字です。
一般的にマジックナンバーは悪だとされています。

コードの中に意味を持っている数字がそのままある状態ですね。
コードにするとこんな感じですかね

mScore += 10;

スコアの変数に10点足されているみたいですね。

マジックナンバーが悪だといわれる理由は
・意味が確定しない
・変更もれがおきやすい

ことです。

10という数字はどういう意味の10なのかコード上からは読み取れません。
それが10点なのか10回なのかはたまた別の意味があるのか。
(スコアという変数に足しているからおそらく10点だろうというあたりは付けられますけどね)

仮に10点だったとしてもそれがのちに20点に変更された場合
この10点足しているコードを
手作業で全て探して変更しなければなりません。
おまけにVisualStudioとかIDEのコード補完の恩恵を受けることもできません。
これでミスや漏れを無くせというほうが無理な話です。

なので上のコードは

AddScore = 10;
mScore += AddScore;

こんな感じに書き直したらいいと思います。
こうすれば10という数字は
加算される点数を表していることがわかりますし、
加算される点数が変更されるときはAddScoreに入れる数字を変えるだけで済みます。
どれだけ色々なところで使っていても全てAddScoreでやっていれば漏れはありません。

マジックナンバーの掃除はこんな感じでやりました。
ただし
・調整中でなおかつそこでしか使っていない
・変数化して持つと膨大な数の変数定義が必要

な場合には後回しにしたり
コメントで済ましたりすることが多いです・・orz

特に今やっているようなオブジェクトの位置とかだと
それを変数化してプログラムで持つと大量の変数が必要になってしまうため
ちょっとな・・てなります。
こういう時は外部データに書き出して読み込んで適用させるっていうやり方が一番だと思います。

冗長な書き方

うまい言い方がわからないのでこういう言い方をしました。
ようはこういうコードのことです。

void Hoge()
{
    if(somethingFlg)
    {
        //何かの処理が長々続いている






    }
}

最初にif文で判定して真の場合のみ処理をしていますね。
このコードの何が冗長かというと
・ネストが1つ増えている
・偽の場合どうするか最後までみないとわからない

という点です。

ネストは深いとコードが追いづらくなるのはプログラム書いてる人なら
おそらく体感的にわかっていることだと思います。
偽の場合どうするかは、
書いてる本人は何もしないと最初から分かっているので
ストレスないでしょうけど
読む人からすれば偽だったらどうするのかとモヤモヤする可能性があります。

どちらにしても読み手にやさしくないコードということです。
これを手っ取り早く解決するのがEarlyReturnと呼ばれる書き方です。

void Hoge()
{
    if(!somothingFlg) return;
    //何かの処理が長々続いてる
}

これならばネストは少なくなりますし
偽の場合は処理をしないっていうことが最初に分かるので
モヤモヤも減ります。

あとがき

今回はコードの書き方テクニック的な何かでした。
マジックナンバーも冗長な書き方も急いで開発していたり、
仕様変更が重なると徐々に増えていくんですよね。

なんで気づいたタイミングで適時やっていくといいと思います。
後回しにしていると今回の私みたく1日のほとんどをその作業でとられてしますので。(戒め)

それでは今回はこの辺でノシ