Ruby on rails 这是重构ActiveRecord fat模型的正确方法吗?

Ruby on rails 这是重构ActiveRecord fat模型的正确方法吗?,ruby-on-rails,refactoring,separation-of-concerns,Ruby On Rails,Refactoring,Separation Of Concerns,例如,如果我有这个ActiveRecord模型: app/models/order.rb class Order < ActiveRecord::Base # model logic end require "lib/someclass.rb" 这是从模型中重构/提取逻辑的好方法吗? 或者使用关注类、服务类或其他什么?就像很久以前有人告诉我的那样: 代码重构不是随机移动代码的问题 在您的示例中,这正是您正在做的:将代码移动到另一个文件中 为什么不好? 通过这样移动代码,您将使原始类变

例如,如果我有这个ActiveRecord模型:

app/models/order.rb

class Order < ActiveRecord::Base
  # model logic
end
require "lib/someclass.rb"
这是从模型中重构/提取逻辑的好方法吗?
或者使用关注类、服务类或其他什么?

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

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

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

为什么不好?

通过这样移动代码,您将使原始类变得更加复杂,因为逻辑被随机拆分为其他几个类。当然它看起来更好,一个文件中的代码越少视觉效果越好,但仅此而已

喜欢组合而不是继承。使用这样的混音器就是要求“清理”一间凌乱的房间,将杂物倒入六个单独的垃圾抽屉,然后砰地关上。当然,从表面上看,它看起来更干净,但垃圾抽屉实际上使识别和实现澄清域模型所需的分解和提取变得更加困难

那我该怎么办?

你应该问问自己:

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

当某个操作满足以下一个或多个条件时,我将访问服务对象:

  • 行动是复杂的
  • 该操作跨越多个模型
  • 该操作与外部服务交互
  • 行动不是基础模型的核心问题
  • 执行该操作有多种方式
提取表单对象

当一个表单提交可以更新多个模型时,您可能需要创建一个表单对象

这样可以将所有表单逻辑(名称约定、验证等)放在一个位置

提取查询对象

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

提取演示者/装饰者

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


多亏了这篇博文,我才把它们放在一起。

将代码保持在同一个类中会移动逻辑,但不会提取它

外部化回调声明具有误导性和潜在危险性。回调被充分滥用;强迫读者查找相关文件是残忍的

没有一般的方法来回答这个问题;“最佳”重构取决于实际重构的内容。不过,生命周期信息应该是明显而精确的


关注点、服务、装饰器、外观等都是支持重构的好机制。如果不知道正在重构什么,就不可能提供关于什么是“最好的”的有意义的建议。

这种分离是完全没有意义的。若你们必须解构一个模型,那个就去关注它。@sevensacat,你们能解释一下为什么它毫无意义吗?因为这意味着你们毫无理由地将一个类拆分成多个文件。这样做并没有使模型更薄,只是使代码库更复杂。
class Order
  before_save :something
  # more logic here
end