在Ruby中使用面向对象的方法

时间:2013-05-09 17:24:36

标签: ruby oop class mixins

我有两个课程,Class AClass B

我最近注意到他们共享了很多相同的代码。例如:

def viewable_by?(user)
  super || clinic.has_staff_member?(user) || user.system_admin? || self.person == user.person
end

我想最小化类之间重复的代码。但是在重构中,我发现其中大部分内容并不完全适合于单一责任原则中完全属于一个类的一个类。我想把它全部放在一个模块中,但这些方法将与时间格式化,查看权限和其他一些事情有关。

在我看来,我有几个选择。 (我打赌你可以推荐其他人。)从面向对象的角度来看,我应该选择哪种方法?为什么?

  1. 使用两个类之间共享的单个模块。有可能 没有具体的单一责任,但它确实清理了 代码显着,并将其保存在一个地方。
  2. 创建小类并将两个类作为模块混合使用。他们 将会有一个单一的责任,但会有很多 他们,其中一些可能只有一种方法。好像是浪费。
  3. 或许使用演示者来处理时间格式化等问题 权限模块在两个类之间共享。也许“更干净” 但方法无处不在。
  4. 我尚未考虑的另一种可能性?
  5. 修改

    此问题之前曾提到Clinic::AppointmentClinic::Visit类,而不是A和B.答案可能指的是约会和访问。

2 个答案:

答案 0 :(得分:3)

这是一个很好的问题,因为它可以很好地处理项目的整体结构。我了解AppointmentVisit是分开的内容,Visit不需要与Appointment相关联。

对于授权方法,例如viewable_by?,我建议将所有授权移到其他地方 - 您可能想要检查cancan结构,这对许多Rails项目都有效,并且很可能会工作适用于任何应用程序,甚至可以自行编写授权系统。部分地,我的答案是使用(3)

但是,由于并非所有由两个类共享的代码都是出于授权目的,我会尝试对一组方法进行分类,并为您能想到的每一类方法提供答案。对于具有类似行为的方法类,我会尝试封装在模块中并包含它(所以就像(1)一样,但是在较小的部分)。例如,一个模块HasVisitors使用got_on_time?was_conclusive?等方法(好吧,也许不是最好的例子,但你得到它)。如果您的模型具有更广泛的范围,例如大多数课程中都存在Authorization,那么现在是时候转到(3)

我建议你停下来再思考一下除了Visit之外你应该有一个Appointment课程和它的关系,但不是现在。到家后,玩得开心,从头上取下,然后第二天再思考。

答案 1 :(得分:0)

如果你转移职责,设计会更清楚吗?例如user.can_view?(资源)