【问题标题】:Rails 'service objects' best practice - class method or instantiateRails“服务对象”最佳实践——类方法或实例化
【发布时间】:2014-07-16 12:13:38
【问题描述】:

我正在按照我一直在研究的研讨会实施“服务对象”,我正在构建一个 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).m​​ethod 有什么原因吗?我认为它提供了更清洁的服务等级,但我不确定这种方法的技术细节以及它是否有缺点。

编辑:或选项 3 - 我要解决这一切都错了,有更好的方法 :)

【问题讨论】:

  • 你认为 2 行不通,你使用类方法 self.user_subscribed_subs(client) 并设置实例变量 @client = client 现在这个 @client.subscribed_subreddits 引发错误,因为 @client 返回 nil
  • 它确实有效,但我没有考虑实例变量,你说得对,我应该把它们拿出来。我很快就对这篇文章进行了更改,但忘记更改了,抱歉。

标签: ruby-on-rails ruby


【解决方案1】:

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

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

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

【讨论】:

  • 同意实例变量的令人不安的使用,我没有考虑到这一点。我自己确实更喜欢“课堂版本”,并且我正在努力使这个演示应用程序尽可能“正确”。我只是想确保以新的课堂方式接近它不是一个很大的禁忌,所以感谢您的意见!
【解决方案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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    相关资源
    最近更新 更多