【问题标题】:Rails, service objects: pass entire object or just an IDRails,服务对象:传递整个对象或只是一个 ID
【发布时间】:2023-03-18 07:32:02
【问题描述】:

我正在将应用程序重构为服务对象,以使模型更小,实际代码文件更有条理。

为此,我正在使用对给定对象执行操作的服务对象。但是,我面临的一个难题是我是将整个对象传递给服务还是只传递一个 ID。

一个典型的例子是更新用户的电子邮件地址。我在模型中使用服务对象而不仅仅是方法的原因是,这封电子邮件还必须与不属于用户模型的外部 3rd 方系统同步。

class User::UpdateEmail
  # Passing entire user object
  def self.update_for_user(user, new_email)
    if user.update_attributes(email: new_email)
      # do some API calls to update email in external services
      true
    else
      false
    end
  end

  # Just passing user ID
  def self.update_for_user_id(user_id, new_email)
    user = User.find(user_id)
    if user.update_attributes(email: new_email)
      # do some API calls to update email in external services
      true
    else
      false
    end
  end
end

一个对另一个有什么好处吗?他们都“似乎”在做同样的事情,这对我来说只是个人喜好,但我很好奇我是否会遇到这样一种情况,即我传递了整个用户对象,并且在服务对象工作时它变得陈旧了就可以了。

如果我传入整个用户,那么调用服务对象的类需要进行检查以确保用户存在等等,而如果我只是传递一个 user_id,那么服务对象现在必须确保有效对象等

对于这种面向服务的操作,是否有公认的或预期的标准或模式?我想确保我在整个应用程序中使用一致的方法,并且以后也不要强迫自己陷入困境。

【问题讨论】:

    标签: design-patterns ruby-on-rails-4 service-object


    【解决方案1】:

    嗯...这取决于:

    如果您使用后台作业,您应该只传递 ID! 如果你不这样做......也许是对象,并且总是问你自己谁/是什么对它负责。

    如果您将事物传递给的对象是负责的对象并且必须知道它,那么也许该对象应该负责查找它,并且只需一个 id 就足够了。查找将在该负责对象中进行。

    如果您传递的对象接受任何对象并且不关心它是什么类型,因为它会动态处理它。 (当它出现时)然后可能是整个对象。取决于它有多大......

    你必须能够逐案判断,没有1-general-rule-or-solution,除了每个对象应该有一个单一的责任。甚至在红宝石中也可以弯曲或折断

    一般:

    尽量保持松散耦合、清晰和简单,每件事都有其单一的职责。 避免将不需要彼此了解或捆绑在一起的事物捆绑在一起。

    我建议您阅读:
    Practical Object-Oriented Design Sandy Metz 的 Ruby
    它有很好的例子,并清楚地解释了这些概念。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-30
      • 1970-01-01
      • 2013-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多