小编典典

Rails 中的 OO 设计:把东西放在哪里

all

我真的很喜欢 Rails(尽管我通常是 RESTless),而且我喜欢 Ruby 非常 OO。尽管如此,创建大型 ActiveRecord 子类和大型控制器的趋势是很自然的(即使您确实为每个资源使用了一个控制器)。如果您要创建更深层次的对象世界,您会将类(和模块,我想)放在哪里?我问的是视图(在 Helpers 本身中?)、控制器和模型。

Lib 没问题,我找到了一些解决方案让它在开发环境中重新加载,但我想知道是否有更好的方法来做这些事情。我真的只是担心类变得太大。另外,引擎怎么样?它们如何适应?


阅读 77

收藏
2022-05-26

共1个答案

小编典典

因为 Rails 根据 MVC 提供结构,所以很自然地最终使用为您提供的模型、视图和控制器容器。初学者(甚至一些中级程序员)的典型习惯用法是将应用程序中的所有逻辑都塞进模型(数据库类)、控制器或视图中。

在某些时候,有人指出“胖模型,瘦控制器”范式,中级开发人员匆忙从控制器中删除所有内容并将其扔到模型中,这开始成为应用程序逻辑的新垃圾箱。

事实上,瘦控制器是一个好主意,但推论——将所有东西都放在模型中,并不是最好的计划。

在 Ruby 中,您有几个很好的选择可以让事情变得更加模块化。一个相当流行的答案是只使用lib包含方法组的模块(通常隐藏在 中),然后将模块包含到适当的类中。这在您希望在多个类中重用的功能类别,但功能仍然在概念上附加到类的情况下会有所帮助。

请记住,当您将一个模块包含到一个类中时,这些方法将成为该类的实例方法,因此您最终仍然会得到一个包含大量方法的类,它们只是很好地组织到多个文件中。

这个解决方案在某些情况下可以很好地工作——在其他情况下,您将需要考虑在代码中使用不是模型、视图或控制器的类。

考虑它的一个好方法是“单一职责原则”,它表示一个类应该对单一(或少量)事物负责。您的模型负责将数据从应用程序保存到数据库。您的控制器负责接收请求并返回可行的响应。

如果您有不完全适合这些框的概念(持久性、请求/响应管理),您可能想考虑如何对有问题的想法进行建模。您可以将非模型类存储在 app/classes 或其他任何位置,然后通过执行以下操作将该目录添加到您的加载路径:

config.load_paths << File.join(Rails.root, "app", "classes")

如果您使用乘客或 JRuby,您可能还希望将您的路径添加到急切加载路径:

config.eager_load_paths << File.join(Rails.root, "app", "classes")

底线是,一旦你在 Rails 中发现自己提出这个问题,是时候加强你的 Ruby 技能并开始建模类,而不仅仅是 Rails 默认为你提供的 MVC 类。

更新:这个答案适用于 Rails 2.x 及更高版本。

2022-05-26