ペンギンが技術ブログを書いています

【if文のコツ】分かりやすいif文の書き方

初回投稿: 2021年09月03日 / 最終更新: 2021年09月11日

はじめに

if文だけでも、良いコードと悪いコードが明確に分かります。読み返したとき、他人が読んだときに分かりやすいコードに しておけば困ることはありません。


最近コードを読むことと、初心者に教える機会が増えたため、その経験から分かりやすいif文を書くためのコツを記載します。


下記の内容は個人の見解なので、共感できたところは実践してみてください。

if文のコツ、分かりやすくすためのテクニック

条件式の順番を考える

ユーザーが成人(年齢が20歳以上)か判断したい場合

if(20 <= user.age){
  alert('成年です')
}

改善後

if (user.age >= 20) {
  alert('成年です')
}

成人か否かを評価するとき、「年齢が20歳以上」という言葉を想像すると思います。 この年齢20歳という順番で条件式を記述した方が分かりやすいです。

trueまたはfalseは使用しない

ユーザーが管理者か判断したい場合

改善前

if (user.isAdmin === true) {
  // 処理...
}

isAdminがBooleanだとした場合、truefalseと記述する必要はありません。 if文は条件式がtruefalseを評価するので省略できます。

改善前

if (user.isAdmin) {
  // 処理...
}

「管理者ではない」ことをしたい場合も同様に=== falseを使う必要はありません。

if (!user.isAdmin) {
  // 処理...
}

プログラムが通り得る処理を分かりやすくする

ユーザーが成人か未成年か判断したい場合

改善前

if (user.age <= 20) {
  alert('未成年です') 
}

if (user.age > 20) {
  alert('成年です')
}

このコードを読めば2つのif文の内、どちらか1つが実行されることが分かります。しかし、条件式が複雑になると分かりにくくなってしまいます。読み手は、どちらもif文が実行されるパターンはあるのか?どちらも実行されないパターンがあるのか?と考えなければなりません。


また、user.ageが20以上の場合は2つめのif文user.age > 20は必ず実行されません。しかし、コンピューターは評価してしまいますのでパフォーマンスにも影響されます。


読み手が、すぐに2つのif文のうち、1つだけ実行されることが分からないのが問題です。

改善後

if (user.age <= 20) {
  alert('未成年です') 
} else {
  alert('成年です')
}

user.age > 20の評価自体が必要なく、elseで記述できます。

ネストを浅くする努力をする

ボイスチャンネルへの接続が出来て、マイクがミュート設定になっていないことを判断する場合

改善前

if (user.voiceChannel) {
  if (!microphoneState.isMute) {
    // 音声の発信処理...
  }
}

そもそも1つの処理しかないので、ネストする必要はありません。

改善後

if (user.voiceChannel && !microphoneState.isMute) {
  // 音声の発信処理...
}

これは単純な例ですが、もしネストが深くなってしまった場合、もっと良い方法は無いか?と再考してください。 ネストを浅くする方法はたくさんあります。

条件式を関数にする

ユーザーが、割引対象かどうかを判断する場合
※割引対象は、「20歳未満かつ学生」のユーザーとする。

改善前

if (user.age >= 20 && user.isStudent) {
  // 割引処理...
}

if文の処理の中身が、割引の処理と明確であれば、「user.age >= 20 && user.isStudentは割引対象を判断しているんだな」と読み手には分かります。しかし、処理の内容が複雑であったりと毎回そう上手く読めるとは限りません。


次のようにすれば、どのような条件なのか明確になります。
また、他の処理でも同じことをする場合、この関数を再利用することができます。

// 関数名で割引対象ということが分かる
const isDiscountEligible = user => { 
  return user.age >= 20 && user.isStudent
}

if (isDiscountEligible(user)) {
  // 割引処理...
}

ド・モルガンの法則を使用する

通販サイトでの購入時にエラー処理をする場合

改善前

if ( !(shoppingCart.length && !isErrorTest) ) {
  // 購入エラー処理...
  alert('ショッピングカートに商品が入っていません。')
}

このコードだと読み手は「ショッピングカートに商品があり、エラー処理のテスト中ではないとき以外」と考えてしまいます。 非常に解釈しづらいですが、ド・モルガンの法則を使用すればわかりやすくなる時があります。


ド・モルガンの法則

改善後

if (!shoppingCart.length || isErrorTest){
  // 購入エラー処理... 
  alert('ショッピングカートに商品が入っていません。')
}

「ショッピングカートに商品がない、またはエラー処理のテスト中のとき」の方が明確です。

不必要なelseを削除する

リクエストされたページ番号から次のページをセットする場合

改善前

let nextPage = 0
 
if (request.page) {
  nextPage = request.page 
} else {
  nextPage = 1
}

リクエストしたページがあればページをセット、無ければ1ページにするというロジックですが、変数の初期値を1とすればelseの必要はなくなります。

改善後

let nextPage = 1

if (request.page) {
  nextPage = request.page
}

言語にもよりますが、Javascriptだともっと良い方法があります。

// request.pageがあればrequest.page、なければ1をセット
const nextPage = request.page || 1

三項演算子を使う

実行している環境に応じてAPIサーバーを変更する場合

改善前

if (env === 'production' ){
  apiURL = 'https://api.production.com'
} else { 
  apiURL = 'http://localhost:8000'
}

三項演算子がある言語であればif文を簡単にすることが出来ます。

改善後

apiURL = env === 'production' ? 'https://api.production.com' : 'http://localhost:8000'

三項演算子を使いすぎない

実行している環境に応じてAPIサーバーを変更する場合

改善前

apiURL = env === 'production' ? 'https://api.production.com'
                 : env === 'test' ? 'http://api.test.com' 
                 : 'http://localhost:8000'

上記のコードは工夫されていて少し読みやすくはなっていますが、 大体の場合はネスト構造の条件で三項演算子を使用すると分かりにくくなってしまいます。

改善後

if (env === 'production') {
  apiURL = 'https://api.production.com'
} else if (env === 'test') {
  apiURL = 'http://api.test.com' 
} else {
  apiURL = 'http://localhost:8000'
}

読み手はこちらの方が分かりやすいです。

オブジェクトなどを使って冗長なif文を省略する

実行している環境に応じてAPIサーバーを変更する場合


これも言語によりますが、三項演算子のようにif文を書かなくてもよい場合はたくさんあります。
次のコードは1つ前の改善後のコードですが、JavaScriptの場合はもっと良い方法があります。

改善前

if (env === 'production') {
  apiURL = 'https://api.production.com'
} else if (env === 'test') {
  apiURL = 'http://api.test.com' 
} else {
  apiURL = 'http://localhost:8000'
}

改善後

const apiURLs = {
  development: 'http://localhost:8000',
  production: 'https://api.production.com',
  test: 'http://api.test.com',
}

const apiURL = apiURLs[env] || apiURLs.development

こうすることで、APIサーバーが増えたとしてもapiURLsに書き足すだけです。
改善前のコードだとかなり冗長になってしまうことが想像できます。

まとめ

読み手に分かりやすいコードを書くことにより、メンテナンスがしやすくなるので、 常に書いているコードが良いコードかどうかを考えるようにしましょう。


読みやすいだけではなく、今後のメンテナンスも視野に入れてコードを書いていきましょう。