5

我正在编写一些代码,但它最终对我来说太丑陋了。无论如何我可以重构它以便我不使用嵌套的 if 语句?

def hours_occupied(date)
  #assuming date is a valid date object    
  availability = get_work_hours(date)
  focus = "work"

  if availability.nil
    availability = get_family_hours(date)
    focus = "family"

    if availability.nil
      availability = get_friend_hours(date)
      focus = "friends"
    end
  end
end

我知道我可以为可用性做这样的事情

availability = get_work_hours(date) || get_family_hours(date) || get_friend_hours(date)

但是如何相应地设置焦点变量?

4

4 回答 4

7

我会做类似以下的事情,因为它清楚地表明每种情况都是相互排斥的:

def hours_occupied(date)
  if availability = get_work_hours(date)
    focus = "work"
  elsif availability = get_family_hours(date)
    focus = "family"
  elsif availability = get_friend_hours(date)
    focus = "friends"
  end
end
于 2013-06-19T15:01:13.930 回答
3

我会写:

def hours_occupied(date)
  focus = if (availability = get_work_hours(date))
    "work"
  elsif (availability = get_family_hours(date))
    "family"
  elsif (availability = get_friend_hours(date))
    "friends"
  end
  # I guess there is more code here that uses availability and focus.
end

但是,我不确定对不同类型使用不同的方法是否是一个好主意,这会使代码更难编写。使用Enumerable#map_detect的不同方法:

focus, availability = [:work, :family, :friends].map_detect do |type|
  availability = get_hours(date, type)
  availability ? [type, availability] : nil
end
于 2013-06-19T15:20:05.853 回答
2

另一种方法是在需要时重新分配值:

def hours_occupied(date)
  availability, focus = get_work_hours(date), "work"
  availability, focus = get_family_hours(date), "family" unless availability
  availability, focus = get_friend_hours(date), "friend" unless availability
end

或使用迭代器:

def hours_occupied(date)
  availability = focus = nil
  %w(work family friend).each {|type| availability, focus = self.send(:"get_#{type}_hours", date), type unless availability}
end
于 2013-06-19T18:40:11.153 回答
1

一种情况何时也是一种选择:

focus = case availability
when get_work_hours(date)
  "work"
when get_family_hours(date)
  "family"
when get_friend_hours(date)
  "friends"
end
于 2013-06-19T15:42:37.393 回答