在ruby中直接使用实例变量是不好的forms?

你应该总是在ruby中创建访问者(用于阅读和/或写作)吗? 如果你有一个不打算在外面重用的类,我不能直接使用实例变量吗?

我遇到的一个问题是在测试中存根@instance_vars是有问题的。

在测试时,实例变量无关紧要。 您应该测试您的方法 ,以validation它们是否产生了正确的结果。

为属性定义reader方法时,将该属性公开给世界。 如果属性的值来自实例变量,数据库,文件,运行时计算等等,则无关紧要。 人们可以调用方法来获取值。

同样,当您为属性定义编写器方法时,如果需要,您可以让每个人都知道他们可以设置它。 价值在哪里并不重要。

只有您的方法定义您的公共API。 其他一切都是实现细节。

在类定义中,直接访问实例变量肯定没有坏处:

 @variable = :value 

如果您只需要简单的分配,就没有理由调用方法。 当然,有时您需要更复杂的function。 延迟初始化,例如:

 def variable @variable ||= :value end # ... variable.to_s 

如果您的方法仅供内部使用,则不应将其包含在公共API中。 将其标记为私人:

 private :variable 

说实话,Ruby中没有任何东西真正被锁定。 即使没有setter方法,人们也可以轻松篡改你的对象,如果他们真的想:

 class << (object = Object.new) private def variable; @variable end end object.variable # NoMethodError: private method `variable' called # send bypasses access control object.send :variable # => :value object.instance_variables # => [:@variable] object.instance_variable_get :@variable # => :value object.instance_variables.each do |variable| object.instance_variable_set variable, nil end object.instance_variable_get :@variable # => nil 

我认为当你想要在设置或执行获取/设置新值的任务之前validation新变量时,访问器可以帮助你。 如果您确定不需要它,我认为最好继续使用实例变量。 否则你可以在开头创建那些,所以你不必在以后拥有大量代码时创建它们,并且可以节省大量时间。

实例变量旨在在相关实例的上下文中使用。 如果您需要与其他对象或甚至其他实例交换数据, attr_accessor根据需要使用attr_readerattr_accessor ,如果不编写自己的方法来促进这一点。

访问器方法充当网守,为您提供validation外部调用方不会破坏内部状态的机会。 面向对象设计的一个原则是该对象承担筛选输入的责任。 如何处理错误输入取决于您,无论是忽略它,抛出exception,还是记录错误等等。

如果你没有处理错误的输入并因此而崩溃,它最终成为你的“错误”,你将成为堆栈跟踪的顶端。 之前拒绝错误的值会在问题发生时准确显示问题,而不是在执行过程中,当您可能忘记了该分配的来源时。

通常,您不希望人们访问您的数据,除非他们有充分的理由。 直接访问和修改另一个对象的实例变量是不好的forms。

有些语言甚至无法直接改变对象的内部状态,但Ruby在这方面非常随意。 但是,仅仅因为可以做某事并不意味着应该这样做。

当您定义访问者时,如果您在该实例的实现中使用它们,则由您决定。 有时直接访问它们更方便,调用@var而不是self.var ,但有时使用访问器提供实例变量不具备的附加function。 由于您只有一个控制点,它还可以在以后更轻松地重构您的应用程序。