Rails:将方法设为私有的主要原因是什么?

时间:2012-01-12 03:25:29

标签: ruby-on-rails ruby methods private

如果end_user无法访问应用的源代码,为什么我们仍然需要将某些方法设为私有?

我正在阅读使用Rails的实用敏捷Web开发,我无法理解为什么我们需要将以下方法设为私有(即使在阅读了解释之后):

private
  def current_cart Cart.find(session[:cart_id])
   rescue ActiveRecord::RecordNotFound 
   cart = Cart.create 
   session[:cart_id] = cart.id
   cart
   end 
end

它说它永远不会允许Rails将它作为一个动作提供,但作为一个程序员,为什么我自己会这样做?

5 个答案:

答案 0 :(得分:6)

正如您所说,可能没有外部理由将其设为私有。但是,它也会阻止您 - 或其他人使用您的代码 - 意外地使用您不应该使用的方法。

如果愿意的话,请将其视为对自己未来行为的完整性检查。

答案 1 :(得分:2)

它旨在鼓励良好实践和良好的代码。

这个想法是你的代码有两个独立的部分:

"在线以上" (上市)。这是与世界其他地方的接口。这是API,在使用对象的实例时进行调用。一旦创建,您就知道这是更改可能影响代码当前使用的区域。

"在线下(私人)。这是详细逻辑所在的位置。此代码可以自由更改和重构,而不会对公共接口产生任何影响。

它可能有助于指导您的考试写作

  • 私人方法可能会或可能不会(单位)测试。
  • 公共方法对单元测试和集成测试都更为鼓舞,因为公共事实意味着它作为公共代码服务于公共代码,因为公共方法可以从未来的任何其他方面调用,所以进行了很好的测试,以确保它继续像宣传的那样工作是必不可少的。

它可能有助于安全性,因为您可以更好地控制私有方法(即只有同一个类中的公共方法调用它们)。

由于公共空间中的名称较少,因此可能有助于减少名称冲突。

答案 2 :(得分:0)

最终用户可能无法访问您的代码,但您团队中的其他人肯定可以访问它,他们可能会更改它。

封装的另一个好处是,它允许一个类(“服务器”)与另一个类(“客户端”)签订合同,以提供一些服务,只需要知道关于“服务器”的一些事情。 “类如方法签名和返回类型。只有当所需要的合同和返回的合同保持不变时,才能实现这种好处。因此,在您的示例中,由于合同被A类破坏,因此没有任何好处。

而不是类A将int类型更改为float,类A应该为其他类创建另一个float类型的新变量,以便类B不会“破坏”或者它们之间的合同不会中断。 C类可以引用新的float变量,而B类仍然可以引用旧的int变量,每个人都很高兴。更好的是,方法将用于检索诸如“getUsersAddress”和“getUSersPhoneNumber”之类的值,具体取决于所需的内容。

良好封装的真正好处是,A类可以完全从上到下重写,只要合同能够被尊重A类预期要做的事情(有方法“getUsersAddress”和“getUSersPhoneNumber”) ),然后B类和C类的一切都是一样的。仔细考虑暴露的内容及其暴露方式。在暴露之前,需要仔细考虑经常变化并打破其他类别的事情。良好的封装意味着隐藏预期会经常更改的内容,以避免破坏其他类。

答案 3 :(得分:0)

  

它表示永远不会允许Rails将其作为一个动作提供,

嗯,这是在Rails Conroller类吗?你正在为Rails 2.x编写的那本书吗?

在Rails 2.x中,默认情况下控制器中的任何公共方法都可以由访问url / name_of_controller / name_of_method的人触发。

但是你的控制器中有一些方法你不希望网络上的任何人触发,它们不是'行动方法'。所以在Rails 2.x中,你将它们标记为protectedprivate,这些不公开。 “action method”表示您打算通过URL直接触发的方法。

在Rails 3.x中,路由通常已更改,以便只有您明确路由到的某些方法可通过URL触发。但是,将Controller中的非动作方法标记为受保护或私有可能仍然有意义:

  • 从浏览源中可以更清楚地了解哪些方法是行动方法,哪些方法不是
  • 作为预防措施,以防有人以这样的方式更改路由,以允许URL触发那些不打算作为操作方法的方法

或者由于其他答案提到的代码组织的一般原因,这些原因并不特定于Rails控制器类。

答案 4 :(得分:0)

如上所述,有几个原因。关于ruby中这种封装的有趣之处在于它可以被违反。

请参阅“send”方法及其兄弟“public_send”。

对于使用此方法的非常常见的元编程技术,请参阅:

dynamic finders