5

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

应用程序/模型/order.rb

class Order < ActiveRecord::Base
  # model logic
end
require "lib/someclass.rb"

库/somelass.rb

class Order
  before_save :something
  # more logic here
end

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

4

2 回答 2

14

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

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

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

为什么不好?

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

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

那我该怎么办?

你应该问自己:

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

提取服务对象

当操作满足以下一个或多个标准时,我会使用服务对象:

  • 动作复杂
  • 行动跨越多个模型
  • 该操作与外部服务交互
  • 动作不是底层模型的核心关注点
  • 有多种执行动作的方式

提取表单对象

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

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

提取查询对象

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

提取演示者/装饰者

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

更多关于装饰器

感谢这篇博文帮助我把这些放在一起。

于 2013-08-13T11:09:21.197 回答
1

将代码保留在同一个类中会移动逻辑,而不是提取它。

外部化回调声明具有误导性和潜在危险。回调被滥用得够多了;强迫读者搜索相关文件是残忍的。

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

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

于 2013-08-13T11:22:42.170 回答