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

Ric*_*dAE 6 ruby ruby-on-rails

我正在按照我一直在研究的工作室实现"服务对象",我正在构建一个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
Run Code Online (Sandbox Code Playgroud)

叫:

@subreddits = SubListFromUser.new(@client).user_subscribed_subs
Run Code Online (Sandbox Code Playgroud)

或者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
Run Code Online (Sandbox Code Playgroud)

叫:

@subreddits = SubListFromUser.user_subscribed_subs(@client)
Run Code Online (Sandbox Code Playgroud)

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

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

ela*_*ado 5

在许多情况下,您需要保留流程生命周期的状态,例如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
Run Code Online (Sandbox Code Playgroud)

作为类方法调用:

@subreddits = SubListFromUser.user_subscribed_subs(@client)
Run Code Online (Sandbox Code Playgroud)


Dav*_*ton 3

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

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

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