Rails 中的 OO 设计:把东西放在哪里 [英] OO Design in Rails: Where to put stuff

查看:30
本文介绍了Rails 中的 OO 设计:把东西放在哪里的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm really enjoying Rails (even though I'm generally RESTless), and I enjoy Ruby being very OO. Still, the tendency to make huge ActiveRecord subclasses and huge controllers is quite natural (even if you do use a controller per resource). If you were to create deeper object worlds, where would you put the classes (and modules, I suppose)? I'm asking about views (in the Helpers themselves?), controllers and models.

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

Lib is okay, and I've found some solutions to get it to reload in a dev environment, but I'd like to know if there's a better way to do this stuff. I'm really just concerned about classes growing too large. Also, what about Engines and how do they fit in?

推荐答案

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

Because Rails provides structure in terms of MVC, it's natural to end up using only the model, view, and controller containers that are provided for you. The typical idiom for beginners (and even some intermediate programmers) is to cram all logic in the app into the model (database class), controller, or view.

在某个时候,有人指出了胖模型,瘦控制器"范式,中级开发人员仓促地从他们的控制器中剔除所有内容并将其扔到模型中,模型开始成为应用程序逻辑的新垃圾桶.

At some point, someone points out the "fat-model, skinny-controller" paradigm, and intermediate developers hastily excise everything from their controllers and throw it into the model, which starts to become a new trash can for application logic.

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

Skinny controllers are, in fact, a good idea, but the corollary--putting everything in the model, isn't really the best plan.

在 Ruby 中,您有几个不错的选择可以使事情变得更加模块化.一个相当流行的答案是只使用包含方法组的模块(通常隐藏在 lib 中),然后将模块包含到适当的类中.如果您希望在多个类中重用某些类别的功能,但这些功能仍然在理论上附加到类中,这会有所帮助.

In Ruby, you have a couple of good options for making things more modular. A fairly popular answer is to just use modules (usually stashed in lib) that hold groups of methods, and then include the modules into the appropriate classes. This helps in cases where you have categories of functionality that you wish to reuse in multiple classes, but where the functionality is still notionally attached to the classes.

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

Remember, when you include a module into a class, the methods become instance methods of the class, so you still end up with a class containing a ton of methods, they're just organized nicely into multiple files.

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

This solution can work well in some cases--in other cases, you're going to want to think about using classes in your code that are not models, views or controllers.

一个很好的思考方式是单一职责原则",它说一个类应该负责单个(或少量)的事情.您的模型负责将数据从您的应用程序持久化到数据库.您的控制器负责接收请求并返回可行的响应.

A good way to think about it is the "single responsibility principle," which says that a class should be responsible for a single (or small number) of things. Your models are responsible for persisting data from your application to the database. Your controllers are responsible for receiving a request and returning a viable response.

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

If you have concepts that don't fit neatly into those boxes (persistence, request/response management), you probably want to think about how you would model the idea in question. You can store non-model classes in app/classes, or anywhere else, and add that directory to your load path by doing:

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

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

If you're using passenger or JRuby, you probably also want to add your path to the eager load paths:

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

最重要的是,一旦你在 Rails 中发现自己提出了这个问题,是时候加强你的 Ruby 印章并开始建模类,而不仅仅是 Rails 给你的 MVC 类默认.

The bottom-line is that once you get to a point in Rails where you find yourself asking this question, it's time to beef up your Ruby chops and start modeling classes that aren't just the MVC classes that Rails gives you by default.

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

Update: This answer applies to Rails 2.x and higher.

这篇关于Rails 中的 OO 设计:把东西放在哪里的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆