yuyanegishi / issue_check

0 stars 0 forks source link

リーダブルコードの要約 #7

Open yuyanegishi opened 5 years ago

yuyanegishi commented 5 years ago

読みやすいコードである必要性

読みやすいコードにする目的は、チームでの開発を円滑にすることにある。読みやすい、また意味がわかりやすいコードであることで、他者(自分も含めて)がコードの理解や修正を行いやすくなる。

読みやすいコードとは

変数

# 修正前のコード

# コースリスト: コース ID => [ コース名, 単位数 ]
courses = [ { 'M2001' => [ '数学2-1', 4 ] },
            { 'E1001' => [ '英語1', 2 ] },
            { 'H3001' => [ '歴史3-1', 3 ] } ]

# 教師リスト: 教師 ID => [ 教師名, [ 担当コース ID のリスト ] ]
teachers = [ { 1 => [ '佐藤', [ 'T4004', 'E1001' ] ] },
             { 2 => [ '鈴木', [ 'M2001', 'M2002' ] ] },
             { 3 => [ '田中', [ 'E1001', 'M2001' ] ] } ]

hash_table = Hash.new    # hash_tableというデータ構造はわかるが、変数名だけでは中身に何が入っているか検討がつかない

teachers.each do | hash1 |
    hash1.values[0][1].each do | item1 |
        if hash_table.key?(item1)
            hash_table[item1] << hash1.values[0][0]
        else
            hash_table[item1] = [hash1.values[0][0]]
        end
    end
end

courses.each do | hash2 |
    if hash_table.key?(hash2.keys[0]) 
        puts "#{hash2.values[0][0]} => #{hash_table[hash2.keys[0]]}"
    else
        puts "#{hash2.values[0][0]} => 担当教師無し"
    end
end
# 修正後のコード

# コースリスト: コース ID => [ コース名, 単位数 ]
courses = [ { 'M2001' => [ '数学2-1', 4 ] },
            { 'E1001' => [ '英語1', 2 ] },
            { 'H3001' => [ '歴史3-1', 3 ] } ]

# 教師リスト: 教師 ID => [ 教師名, [ 担当コース ID のリスト ] ]
teachers = [ { 1 => [ '佐藤', [ 'T4004', 'E1001' ] ] },
             { 2 => [ '鈴木', [ 'M2001', 'M2002' ] ] },
             { 3 => [ '田中', [ 'E1001', 'M2001' ] ] } ]

courseid_teacher = Hash.new    # courseid_teacherという表記から、コースIDと教師のデータが入っていることが想像しやすい

teachers.each do | teacher_list |
    teacher_list.values[0][1].each do | id |
        if courseid_teacher.key?(id)
            courseid_teacher[id] << teacher_list.values[0][0]
        else
            courseid_teacher[id] = [teacher_list.values[0][0]]
        end
    end
end

courses.each do | course_list |
    if courseid_teacher.key?(course_list.keys[0]) 
        puts "#{course_list.values[0][0]} => #{courseid_teacher[course_list.keys[0]]}"
    else
        puts "#{course_list.values[0][0]} => 担当教師無し"
    end
end
# 修正前のコード

class TestClass

  attr_accessor :name, :str

  def initialize(name)
    @name = name
    @str = ""
  end

  def make_hello
    @str = "Hello, World. I am #{@name}.\n"
  end

  def hello
    puts @str
  end

  # インスタンス変数を使用していないメソッドがたくさんある

end
# 修正後のコード

class TestClass

  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def make_hello
    @@str = "Hello, World. I am #{@name}.\n"
  end

  def hello
    puts @@str
  end

  # その他メソッドは変数strが見えない

end

インデントの活用

# テスト2−2の一部抜粋

#素数判定関数の生成
def prime?(num)
  if num < 2
    return false
  else
    2.upto(Math.sqrt(num)) do | i |
        if  num % i == 0
            return false
        end
    end
    return true
  end
end

コメントの活用

# Rails Turtorial抜粋

# ユーザーがログインしていればtrue、その他ならfalseを返す
def logged_in?
  !current_user.nil?
end

# 永続的セッションを破棄する
def forget(user)
    user.forget
    cookies.delete(:user_id)
    cookies.delete(:remember_token)
end

# 現在のユーザーをログアウトする
def log_out
    forget(current_user)
    session.delete(:user_id)
    @current_user = nil
 end

制御フロー

# 左:調査対象 右:比較対象
if length >= 10

# 左:比較対象 右:調査対象
if 10 <= length
# 条件文①
def test_check(num1, num2)
  if num1 == 0 || num2 == 0
    result = false
  else
    result = true
  end
  return result
end
# 条件文②
def test_check(num1, num2)
  return false if num1 == 0 || num2 == 0
  return true
end

テストと読みやすさ

その他