gpt4 book ai didi

ruby-on-rails - 在 Ruby 中,是否有可接受的方法将类拆分为更小的、可组合的混入(知道父类)?

转载 作者:行者123 更新时间:2023-12-04 04:00:27 28 4
gpt4 key购买 nike

我发现 Ruby 中的某些类,尤其是 Ruby on Rails 中的 User 类,有变得非常庞大的趋势。这本身是可以管理的,但如此大的类(class)的测试文件也变得庞大。

为了尝试和划分这种复杂性,我想从几个子类中组成用户类。

class User < ApplicationRecord
include User::AuthMixin
include User::EmailsMixin
include User::SettingsMixin
end

从技术上讲这是可行的,但是这意味着 Mixins 最终引用了 User 对象上的一堆属性,而它们实际上一无所知。以这个 EmailsMixin 为例,它将所有围绕每个用户的多封电子邮件的逻辑划分开来:

module User::EmailsMixin

def email
primary_email.try :value
end

def update_email value
email = emails.build value: value
self.primary_email = email
end
...
end

这可行,但闻起来不太好......

虽然这一切都有效,但感觉就像难闻的代码。为什么 User::EmailsMixin 应该引用一个它不知道的 primary_email?这将是 mixins 的本质——它们都是引用父对象(在本例中是 User)的属性。

不仅如此,现在我正在使用 Sorbet Typechecking 它没有通过类型检查。 Sorbet 准确地指出了这个错误,并指出 Method primary_email does not exist on User::EmailsMixin。这当然是正确的。

所以我有三个问题:

  1. 这是划分代码的合理范例吗?请注意,这不是可以移入服务对象的代码,它直接与用户对象的属性相关(如上所述)
  2. 如果这是一个合理的范例,是否有一种方法可以在每个混入中引用父对象?有没有办法说“这个模块实际上是用户对象的一部分,稍后将被包含/合并”
  3. 如果这不是将大量类分解为较小类的合理方法,那么我还应该考虑如何这样做(重申一下,服务对象不会在代码需要 访问父属性)

最佳答案

如果不查看所有代码并根据您的用例进行重构,就无法给出具体答案。

在我看来,混入(或 Rails 问题)应该非常谨慎地使用。它们对减少代码的表面积没有任何作用(公共(public)接口(interface)仍然是相同的“逻辑大小”),它们只是用来隐藏东西并使东西更难找到。这与深度继承变得笨拙的原因相同——一个类的“逻辑大小”是它本身加上它的所有父类(super class)。将代码移动到另一个文件不会改变它。

在不知道您的代码在做什么的情况下,我将提出一个经常适用的盲目建议:将持久性与领域逻辑分开。例如,我认为将 #email#update_email 保留在 User 中是很好的,因为它们处理持久性,并且让它们靠近模型很好 b/c 接口(interface)/w 数据库是模型的责任。

但是,如果您正在寻找放置 #validate_email 方法的地方,UserEmail 模型都不是一个好地方放上去。

总是有不止一种方法来划分您的应用程序,正如您所注意到的,纯粹按职责(电子邮件、身份验证、设置)划分,意味着您不是 数据访问/持久性,即“一切都需要访问 User 属性”。

如果按数据划分,您会发现这些模块不需要 需要访问User 的(所有)属性。 Auth 可能只需要loginhashed_pa​​ss设置可能只需要一个散列。

随着逻辑从 User 中移出,您需要将数据传递出去以进行处理并在完成时检索结果——这是您要维护的组件之间的数据接口(interface)。如果它开始变得复杂,也许数据接口(interface)本身应该是一个类/数据类型。如果开始需要传递太多参数,请考虑组件之间的边界是否在正确的位置。

警告——许多 Rails 库没有做出这种区分,通常建议您include/extend 您的模型以访问它们的功能,因此您必须如果您想使用它们,请找到一种方法来使用它们。

关于ruby-on-rails - 在 Ruby 中,是否有可接受的方法将类拆分为更小的、可组合的混入(知道父类)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63115683/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com