为什么Rails会为每个请求创建一个控制器?

meg*_*gas 22 controller ruby-on-rails

从我之前的问题中我了解到Rails为每个请求创建一个控制器实例.

我的问题是,因为这个主题与我正在研究的项目的设计有关:

为什么Rails会创建一个新的实例

class SomeController < ApplicationController; end
Run Code Online (Sandbox Code Playgroud)

处理每个传入的请求?为什么不创建单例对象并将请求转发给这个?这似乎更有效,因为我们不会浪费资源来分配和清理请求对象?

mea*_*gar 38

实例化新控制器实例的开销是微不足道的,这意味着两个完全不相关的请求之间没有意外共享状态.处理器时间的任何"节省"都会被产生毁灭性错误的可能性所抵消.

请记住,控制器用于存储特定于请求的状态.重复使用控制器将要求您@variable在每个操作开始时重置您设置的每一个.否则,类似的事情@is_admin = true可能会被设置并且永远不会被清除.你实际上引入的不那么人为的错误会更加微妙,并且会影响开发人员的时间.

你看到没有的优化.某些东西必须保持状态并在请求之间重置它,否则你就会遇到意外共享状态的噩梦.如果在请求之间保留控制器实例,则只需将维护/重置状态的工作推送到某个较低级别,其中答案可能仍然是为每个请求实例化某个状态管理类的新实例.计算机非常擅长分配和释放资源,所以在你真正知道这是一个瓶颈之前不要担心.在这种情况下,为每个请求实例化一个新控制器很容易是正确的选择.

在Rails的情况下,能够使用@variable = value是代码清晰度和可用性立场的主要胜利,并且这或多或少地需要在请求完成时丢弃控制器的每个实例.

  • 嗯......并不是说`@ foo`总是需要被清除,而是需要将控制器写成没有共享状态,比如Java servlet.您可以使用与Java中不同的机制(本地,请求等)将值传递给视图层.控制器仅用于存储特定于请求的状态*,因为*它们是按请求实例化的 - 但它并不是控制器概念所固有的; 其他框架以不同的方式做到了.我知道你知道,只是澄清. (4认同)
  • @DaveNewton 是的,我考虑过这个问题,但问题是关于性能的,所以我认为它包含在“某些必须重置请求之间的状态”中。要点是,保留控制器实例不会提高*性能*。您只是在四处移动分配/解除分配。 (2认同)