1

我有两个班,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. 我还没有考虑过的另一种可能性?

编辑

这个问题之前提到过Clinic::AppointmentClinic::Visit班,而不是A和B。答案可能是指约会和访问。

4

2 回答 2

3

这是一个巧妙的问题,因为它很好地处理了项目的整体结构。我理解AppointmentandVisit是分开的东西,Visit不需要链接到Appointment.

对于授权方法,例如viewable_by?,我建议将所有授权移到其他地方 - 您可能需要检查cancan结构,该结构在许多 Rails 项目中运行良好,并且很可能适用于任何应用程序,甚至自己编写授权系统。因此,在某种程度上,我对您的回答是使用(3).

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

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

于 2013-05-09T18:20:07.287 回答
0

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

于 2013-05-09T21:02:08.143 回答