我发现 Ruby 中的某些类,尤其是User
Ruby on Rails 中的类,有变得非常庞大的趋势。这本身几乎是可管理的,但如此大类的测试文件也变得庞大。
为了尝试区分这种复杂性,我想从几个子类组成用户类。
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 的本质——它们都引用父对象(在这种情况下是用户)上的属性。
不仅如此,现在我正在使用 Sorbet Typechecking 它没有通过类型检查。Sorbet 准确地指出了这个错误并指出Method primary_email does not exist on User::EmailsMixin
。这当然是真的。
所以我有三个问题:
- 这是划分代码的合理范例吗?请注意,这不是可以移动到服务对象中的代码,它直接与用户对象上的属性相关(如上所述)
- 如果这是一个合理的范例,是否有办法在每个 mixin 中引用父对象?有没有办法说“这个模块实际上是用户对象的一部分,稍后将被包含/合并”
- 如果这不是将大量类分解为更小的类的合理方法,那么我应该如何考虑这样做(重新迭代,服务对象不会在这里剪切它,因为代码需要访问父属性)