如果end_user无法访问应用程序的源代码,为什么我们还需要将一些方法私有化?
我正在阅读Pragmatic Agile Web Development with Rails,我不明白为什么我们需要将以下方法私有化(即使在阅读了解释之后):
private
def current_cart Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
cart = Cart.create
session[:cart_id] = cart.id
cart
end
end
它说,它永远不会允许Rails将其作为一种操作提供,但作为一名程序员,我为什么要自己做呢?
正如您所说,可能没有外部原因将其私有化。然而,它也可以防止你或其他使用你代码的人意外地使用你不应该使用的方法
如果你愿意的话,把它看作是对自己未来行为的一次理智检查。
它旨在鼓励良好的实践和良好的代码。
这个想法是你的代码有两个独立的部分:
"在线上"(公开)。这是与世界其他地方的接口。这是API,在使用对象实例时会在其中进行调用。一旦创建,您就知道THIS是更改可能影响代码当前使用的区域。
"离线(私有)。这是详细逻辑所在的地方。可以自由更改和重构这些代码,而不会对公共接口产生任何影响。
它可能有助于指导你的测试写作
- 私有方法可以进行测试,也可以不进行(单元)测试
- 公共方法对单元测试和集成测试都更令人鼓舞,因为它是公共的,这意味着它是该代码的公众形象,而且由于它是公开的,它可能会在未来的任何其他点被调用,因此拥有良好的测试以确保它继续像广告中所说的那样工作是至关重要的
它可能有助于提高安全性,因为您可以更好地控制谁调用私有方法(即,只有同一类中的公共方法调用它们)。
这可能有助于减少名称冲突,因为您在公共空间中的名称较少。
最终用户可能无法访问您的代码,但您团队中的其他人肯定可以访问它,他们可能会更改它。
封装的另一个好处是,它允许一个类("服务器")与另一类("客户端")签订合同,以提供一些服务,而只需要了解"服务器"类的一些信息,如方法签名和返回类型。只有当要求和返还的合同保持不变时,收益才能实现。因此,在你的例子中,由于A类违反了合同,因此没有任何好处。
类A不应该将int类型更改为float,而应该创建另一个float类型的新变量供其他类使用,这样类B就不会被"破坏",或者它们之间的契约也不会被破坏。类C可以引用新的float变量,类B仍然可以引用旧的int变量,每个人都很高兴。更好的是,根据需要,方法将用于检索值,如:"getUsersAddress"one_answers"getUSersPhoneNumber"。
良好封装的真正好处是,类A可以从上到下完全重写,只要遵守关于类A应该做什么的约定(具有方法"getUsersAddress"one_answers"getUSersPhoneNumber"),那么类B和C中的所有内容都可以正常工作。仔细思考暴露的内容以及如何暴露。在公开之前,需要仔细考虑经常发生变化并破坏其他类的事情。良好的封装意味着隐藏预期经常更改的内容,以避免破坏其他类。
它说,它永远不会允许Rails将其作为一种行动,
嗯,这是Rails Conroller类的吗?你正在读的这本书是为Rails2.x写的吗?
在Rails2.x中,默认情况下,控制器中的任何公共方法都可以由访问url/name_of_Controller/name_of_method的人触发。
但你的控制器中有一些方法是你不希望网络上的任何人触发的,它们不是"动作方法"。因此,在Rails2.x中,您将它们标记为protected
或private
,而不是公共的。"操作方法"是指您打算通过URL直接触发的方法。
在Rails3.x中,路由通常发生了变化,只有您明确路由到的某些方法可以通过URL触发。然而,将控制器中的非操作方法标记为受保护的或私有的可能仍然有意义:
- 从略读资料中可以更清楚地看出,哪些方法是行动方法,哪些不是
- 作为一种预防措施,以防有人以允许URL触发那些不打算作为操作方法的方法的方式更改路由
或者出于其他答案提到的代码组织的一般原因,这些原因并不是Rails控制器类所特有的。
如上所述有几个原因。ruby中这种封装的有趣之处在于,它可能会被违反。
请参阅"send"方法及其兄弟"public_send"。
关于使用这种方法的一种非常常见的元编程技术,请参阅:
动态查找器