我有两个类,Class A
和 Class B
。
我最近注意到他们共享很多相同的代码。例如:
def viewable_by?(user)
super || clinic.has_staff_member?(user) || user.system_admin? || self.person == user.person
end
我想尽量减少类之间重复的代码。但是在重构中,我发现其中的大部分内容并不能很好地归入完全符合单一职责原则的类中。我想将它们全部放入一个模块中,但这些方法必须与时间格式、查看权限和其他一些事情有关。
在我看来,我有几个选择。 (而且我敢打赌您可以建议其他人。)从面向对象的角度来看,我应该采用哪种方法,为什么?
- 使用两个类之间共享的一个模块。它可能 没有特定的单一责任,但它确实清理了 大量编码,并将其全部保存在一个地方。
- 创建小类并将其作为模块混合到两个类中。他们 都会有一个单一的责任,但会有很多 它们,其中一些可能只有一种方法。看起来很浪费。
- 也许使用演示器来处理时间格式,以及 权限模块在两个类之间共享。也许“更清洁”, 但方法将无处不在。
- 另一种我尚未考虑的可能性?
编辑
这个问题之前提到了Clinic::Appointment
和Clinic::Visit
类,而不是A和B。答案可能是指约会和访问。
最佳答案
这是一个很好的问题,因为它很好地处理了项目的整体结构。我知道 Appointment
和 Visit
是分开的,Visit
不需要链接到 Appointment
。
对于授权方法,如viewable_by?
,我建议将所有授权移至其他地方 - 您可能需要检查 cancan结构,它在许多 Rails 项目中运行良好,并且很可能在任何应用程序中运行良好,甚至可以自己编写授权系统。所以在某种程度上,我对你的回答是使用 (3)
。
但是,由于并非这两个类共享的所有代码都用于授权目的,所以我会尝试对一组方法进行分类,并针对您能想到的每一类方法给出一个答案。对于具有类似行为的方法类,我会尝试封装在一个模块中并包含它(就像 (1)
一样,但在更小的部分)。例如,一个模块 HasVisitors
具有诸如 got_on_time?
和 was_conclusive?
之类的方法(好吧,也许不是最好的例子,但你明白了)。当您的模型具有更广泛的范围时,例如 Authorization
,它出现在您的大多数类中,那么是时候转到 (3)
了。
我建议你停下来再想一想你是否应该在 Appointment
和它的关系之外有一个 Visit
类,但不是现在。到家后,玩得开心,把它从头上拿下来,第二天再考虑。
关于ruby - 在 Ruby 中使用面向对象的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16467524/