8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Keisuke Death MarchAdvent Calendar 2023

Day 18

簡単に明日から読みやすいコードを書くコツを考えてみた

Last updated at Posted at 2023-12-18

はじめに

現在プログラミングスクールRUNTEQに通っています。

久々にリーダブルコードを読んだので、改めて読みやすいコードを書くためにはどう意識すればよいか少しまとめていきます。

名前に情報を詰め込む

変数は名前に情報を詰め込む必要があります。

例えば、2時間後に締め切りによって条件分岐させるプログラムを考えるとします。

アンチパターン
# 現在時刻を取得
now = Time.now

# 2時間後を計算
two_hours_later = now + (60 * 60 * 2)

# 締め切りが2時間後かどうかを判断
if now < two_hours_later
  puts "まだ締め切りまで時間があります。"
else
  puts "締め切り時間を過ぎています。"
end

上記ですが、2時間後をtwo_hours_laterという変数に代入していますが、これは意味がありません。

このnow + (60 * 60 * 2)どんな目的で用いるのかを考える必要があります。

# 現在時刻を取得
now = Time.now

# 締め切りを設定(現在時刻から2時間後)
study_deadline = Time.now + (60 * 60 * 2)

# 締め切りが2時間後かどうかを判断
if study_deadline > now
  puts "まだ締め切りまで時間があります。"
else
  puts "締め切り時間を過ぎています。"
end

今回は2時間後が勉強の締め切りだったので、study_deadlineという変数名にする事でより文脈が分かりやすくなります。

要約する

例えば、こんなコードがあるとします。

if request.user.id == document.owner_id
  # ドキュメントを編集できる
end

この例だと、簡単に読めそうですが変数を5つ使って条件を判定しています。
requestuseriddocumentowner_idが一致している時、という分岐から、「これは何を意味してるんだ、、?」と少し考えるのに時間がかかります。

この分岐は何を意味しているかというと、自分のドキュメントかどうかということを意味しているので、一度要約変数に代入することで、読み手の負荷を下げることにも繋がります。

user_owns_document = (request.user.id == document.owner_id)
if user_owns_document
  # ドキュメントを編集できる
end

条件分岐の並び順

条件分岐は単純な条件、かつ肯定形から分岐をさせていく事が良いです。

アンチパターン
if a != b 
 #aとbが「合致しない時」の処理
else
 #aとbが「合致する時」の処理
end
if a = b 
 #aとbが「合致する時」の処理
else
 #aとbが「合致しない時」の処理
end

一致してない場合の条件分岐を書く場合はRubyではunlessを用いる事が良さそうです。

print "数値を入力してください: "
num = gets.to_i
puts "#{num}は負の数です。" unless num >= 0

無関係の下位問題を抽出する

コードには単一責任の原則という原則があり、クラスや関数への責任は一つにしましょうという原則です。

例えば、ユーザーの年齢を計算し、その結果に基づいてメッセージを出力するメソッドがあるとします。

def calculate_age_and_display_name(birth_year, name)
  current_year = Time.now.year
  age = current_year - birth_year

  if age >= 20
    puts "#{name}さん、あなたは成人です。"
  else
    puts "#{name}さん、あなたは未成年です。"
  end

  puts "あなたの名前は#{name}です。"
end

calculate_age_and_display_name(2000, 'Yamada')

このプログラムでは、年齢の計算名前の表示という2つの責任(役割)を持っています。
責任(役割)が増えるごとに見通しが悪くなり、思わぬバグを生み出す温床になります。
また、関数名と実際の処理の内容が乖離してしまうことも考えられるので、責任(役割)事にメソッドに切り出す事が良いでしょう。

def calculate_age(birth_year)
  current_year = Time.now.year
  age = current_year - birth_year
end

def display_message(age, name)
  if age >= 20
    puts "#{name}さん、あなたは成人です。"
  else
    puts "#{name}さん、あなたは未成年です。"
  end

  puts "あなたの名前は#{name}です。"
end

age = calculate_age(2000)
display_message(age, 'Yamada')
8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?