Rails的服务对象的最佳实践 - 类方法或实例化

时间:2014-07-16 12:13:38

标签: ruby-on-rails ruby

我正在按照我一直在研究的工作室实现'服务对象',我正在构建一个reddit API应用程序。我需要对象返回一些东西,所以我不能只执行初始化程序中的所有内容。我有这两个选项:

选项1:类需要实例化

class SubListFromUser

  def user_subscribed_subs(client)
    @client = client
    @subreddits = sort_subs_by_name(user_subs_from_reddit)
  end

  private

  def sort_subs_by_name(subreddits)
    subreddits.sort_by { |sr| sr[:name].downcase }
  end 

  def user_subs_from_reddit
    @client.subscribed_subreddits :limit => 100
  end

end

跟:

@subreddits = SubListFromUser.new(@client).user_subscribed_subs

或者Option2将它作为一种类方法:

class SubListFromUser

  def self.user_subscribed_subs(client)
    sort_subs_by_name(client, user_subs_from_reddit)
  end

  private

  def self.sort_subs_by_name(subreddits)
    subreddits.sort_by { |sr| sr[:name].downcase }
  end 

  def self.user_subs_from_reddit(client)
    client.subscribed_subreddits :limit => 100
  end

end

跟:

@subreddits = SubListFromUser.user_subscribed_subs(@client)

在这种情况下,什么是“最佳做法”?有没有理由我不应该使用object.new(args).method?我认为它提供了一个更清洁的服务类,但我不确定这种方法的技术性,如果它有缺点。

编辑:或者选项3 - 我认为这一切都错了,并且有更好的方法:)

2 个答案:

答案 0 :(得分:2)

在Ruby中,我发现没有太大区别。

我发现在“静态”版本中使用类变量有点令人不安。

我认为类版本可能会通过子类化带来更多创意重用,但除非事情设计得尽可能正确,否则会带来一系列令人头疼的问题。

答案 1 :(得分:2)

在许多情况下,您需要为流程生命周期保留状态,例如client。而不是让它旅行"通过你需要它的所有方法,作为一个参数,将它保持为类变量更有意义。但为了更清晰的语法,我建议将两种方法结合起来:

class SubListFromUser
  def initialize(client)
    @client = client
  end
  private_class_method :new # only this class can create instances of itself

  def user_subscribed_subs
    @subreddits = sort_subs_by_name(user_subs_from_reddit)
  end

  private

  def sort_subs_by_name(subreddits)
    subreddits.sort_by { |sr| sr[:name].downcase }
  end 

  def user_subs_from_reddit
    @client.subscribed_subreddits :limit => 100
  end


  class << self
    def user_subscribed_subs(client)
      new(client).user_subscribed_subs # create instance of this class and run a process
    end
  end
end

作为班级方法召集:

@subreddits = SubListFromUser.user_subscribed_subs(@client)