我创造了一场灾难。请指出一个编码策略来重构这个

时间:2011-02-28 05:01:36

标签: ruby refactoring

更新

到目前为止,我已经大幅削减了它:

  # Gets the user's Wall
  # I used object methods so they can be called by other methods, such as #second_wall()
  def read_wall(fbuserid)
     @result ||= graph.get_connections(fbuserid, 'feed')
  end

  def second_wall(fbuserid)
     @second ||= @result.next_page
  end

  def third_wall(fbuserid)
     @third ||= @second.next_page
  end

  def fourth_wall(fbuserid)
       fourth ||= @third.next_page
   end

  # Collects your friends' wall Posts and puts the IDs into an array
  # the number array contains method names that will be called
  # This is done to read 100 wall posts
  def get_post_ids(fbuserid)
     var = []   
     number = [read_wall(fbuserid), second_wall(fbuserid), third_wall(fbuserid), fourth_wall(fbuserid)]
     number.each do |iterate|
        num ||= iterate
        for i in 0..25
           if find_nil(num, [i,'id']).nil? == false
              var << num[i]['id']
           end
        end
     end

最初,我在基本方法#read_wall()中拥有所有内容。我不确定数组发生了什么,但是当我尝试时:

array = result + second + third + fourth。我只留下原始结果的数据。所以我创造了这场灾难。 你可以帮我重构吗?

   # Gets the user's Wall
      def read_wall(fbuserid)
         result ||= graph.get_connections(fbuserid, 'feed')
      end

  def second_wall(fbuserid)
     result ||= graph.get_connections(fbuserid, 'feed')
     second ||= result.next_page
  end

  def third_wall(fbuserid)
       result ||= graph.get_connections(fbuserid, 'feed')
       second ||= result.next_page
       third ||= second.next_page
  end

  def fourth_wall(fbuserid)
        result ||= graph.get_connections(fbuserid, 'feed')
        second ||= result.next_page
        third ||= second.next_page
        fourth ||= third.next_page
   end

  # Collects your friends' wall Posts and puts the IDs into an array
  def get_post_ids(fbuserid)
     x ||= read_wall(fbuserid)
     var = []
     for i in 0..25
        if find_nil(x, [i,'id']).nil? == false
           var << x[i]['id']
        end
     end

     second_wall ||= second_wall(fbuserid)
       for i in 0..25
          if find_nil(second_wall, [i,'id']).nil? == false
             var << second_wall[i]['id']
          end
       end

      third_wall ||= third_wall(fbuserid)
        for i in 0..25
           if find_nil(third_wall, [i,'id']).nil? == false
              var << third_wall[i]['id']
           end
        end

      fourth_wall ||= fourth_wall(fbuserid)
         for i in 0..25
            if find_nil(fourth_wall, [i,'id']).nil? == false
                 var << fourth_wall[i]['id']
            end
         end

      @get_post_ids = var
  end

2 个答案:

答案 0 :(得分:0)

作为提示,而是在四个不同的数组上重复循环体四次,你可以创建一个数组数组。

而不是:

for x in array1
  function1(x);
end

for x in array2
  function1(x);
end

你可以这样做:

[array1,array2].each do |array|
  for x in array 
    function1(x)
  end
end

答案 1 :(得分:0)

在这种情况下,为每个特定页面添加辅助函数看起来像代码味道。如果你经常提到说user.second_wall并且需要一个快速的方法来实现它,这可能并不总是一个问题。但是,通过链接每个这样的功能,

read_wall -> second_wall -> third_wall -> fourth_wall

逐渐难以扩展和维持这一点。也许有一个基本功能可以检索给定任何用户和所需范围的墙贴。

get_wall_posts(user_id, range)

要获得前100个墙贴,并且映射id会看起来像,

first_100_posts = get_wall_posts(some_user, 0...100);
first_100_ids = first_100_posts.map { |post| post['id'] }

重构最重要的部分之一是为标识符提供良好的名称。 variterate等名称通常不会对代码说太多。它与评论类似,如果不是更糟,

// increment i by 1
i++;

一致性同样重要。执行类似事情的方法组应以一致的方式命名。 read_wallsecond_wall似乎与我断开连接,因为其他方法中缺少动词readread_second_wall听起来更像是一个更好的名字,而且与其他内容更为一致。

当前设计需要考虑的另一件事是对象一致性。目前,一些方法通过一个过程(获得前100或4页的帖子)而不是它们各自的角色相互关联,使它们彼此依赖。在不调用second_wall的情况下调用read_wall会产生不同的结果,因为result属性尚未初始化。这可能导致很难找到错误,因为还有另一个维度要跟踪 - 对象是否按预期顺序使用。

尝试尽可能地限制功能的副作用。如果必须按特定顺序使用对象,则使用state模式或任何类似的模式来确保。