这是重构ActiveRecord胖模型的正确方法吗?

Yar*_*old 5 refactoring ruby-on-rails separation-of-concerns

例如,我有这个ActiveRecord模型:

应用程序/模型/ order.rb

class Order < ActiveRecord::Base
  # model logic
end
require "lib/someclass.rb"
Run Code Online (Sandbox Code Playgroud)

LIB/somelass.rb

class Order
  before_save :something
  # more logic here
end
Run Code Online (Sandbox Code Playgroud)

这是从模型重构/提取逻辑的好方法吗?或者可以使用关注类,服务类或其他东西?

Pie*_*ois 14

就像很久以前有人告诉我的那样:

代码重构不是随机移动代码的问题.

在您的示例中,这正是您正在做的事情:将代码移动到另一个文件中

为什么不好?

通过像这样移动代码,您将使原始类更复杂,因为逻辑被随机分成几个其他类.当然它看起来更好,一个文件中的代码更少在视觉上更好,但这就是全部.

宁愿组合物继承.使用像这样的mixins要求通过将杂乱的东西倾倒在六个独立的垃圾抽屉中并将它们关上来"清理"一个凌乱的房间.当然,它在表面看起来更干净,但垃圾抽屉实际上更难以识别和实现澄清域模型所必需的分解和提取.

那我该怎么办?

你应该问自己:

  • 哪些代码组合在一起,可能是新类/模块的一部分?
  • 将代码提取到其他地方有意义吗?
  • 我是否有一些在我的应用程序中共享的代码?
  • 我可以在代码库中提取循环模式吗?

提取服务对象

当某个操作符合以下一个或多个条件时,我会访问服务对象:

  • 行动很复杂
  • 该动作涉及多个模型
  • 该操作与外部服务交互
  • 该行动不是基础模型的核心问题
  • 有多种方法可以执行操作

提取表单对象

如果可以通过单个表单提交更新多个模型,则可能需要创建表单对象.

这使得所有表单逻辑(名称约定,验证等)都可以放在一个地方.

提取查询对象

您应该将复杂的SQL/NoSQL查询提取到自己的类中.每个查询对象负责根据标准/业务规则返回结果集.

提取演示者/装饰者

将视图逻辑提取到演示者中.您的模型不应该处理特定的视图逻辑.此外,它还使您能够在多个视图中使用演示者.

更多关于装饰者

感谢这篇博文,帮助我将这些内容整合在一起.