Smalltalk公共方法与私有/受保护方法

12

我注意到Smalltalk语言没有私有/受保护方法的概念。所有方法都是公共的。作为一个Java/C++背景的人,我认为这是一种根本性的弱点,因为任何在Smalltalk中创建的应用程序都可以完全被操纵。我猜你可以依靠命名约定来记录公共API,并在方法前缀中指示它们为私有(我相信Squeak就是这样做的),但它仍然是完全开放的。

相对于使用显式访问修饰符控制方法调用的访问权限,这种方法是否有任何好处?

4个回答

18

实际上,Smalltalk的做法是将私有方法放在“private”类别中。这表示您不应该使用这些方法,但当然并没有强制执行。

这是设计上的考虑 - 这是一种特性而不是缺陷。从一开始,Smalltalk就被设计成一个开放的系统。

一些优点:

  • 如果我必须这么做 - 也许库设计者没有预见到我必须要暴露某些特定的东西 - 我仍然可以调用那些私有方法。显然,这不是轻率行事的事情:相反,需要慎重、谨慎地使用,知道这是一种策略性的解决方案。
  • 语言简洁性。
  • (根据Alexandre Jasmin的评论) Smalltalk没有区分你作为程序员能做什么和语言/环境能做什么。这意味着Smalltalk图像公开了构建自己的检查器/调试器/任何其他工具所需的所有东西,而无需使用我们可以做到这一点但你不能的技术来提供特殊工具。

1
另一个优点是实时检查/操作/调试系统状态。如果需要,甚至可以使用 #instVarNamed:访问私有实例变量。 - Alex Jasmin
确实,#storeString 经常会产生使用 #instVarAt:put: 的代码,这也是其中一个危险的工具。 - Frank Shearar
1
David Parnas,1970年,《关于将系统分解为模块所使用的标准》。C语言,1969-1973年,通过不在头文件中公开函数来控制可见性。 - Frank Shearar
1
@DesolatePlanet Smalltalk的方法是一种妥协,它允许用户在常见情况下将您的组件视为黑盒子,但仍然赋予他们在您未涉及/预见的情况下进行所需操作的自由(这似乎总是会发生,至少对我来说是这样)。在Smalltalk中,许多在其他语言中限制用户的事情都依赖于信任。这是我使用Smalltalk的原因之一-我知道我有自由以任何我需要的方式塑造系统,而不仅仅局限于那些内置的功能。 - Sean DeNigris
1
@Sean 我认为这不是一种妥协,而是符合Smalltalk实现理念的公理:一个开放的系统。 - Frank Shearar
显示剩余4条评论

7

私有和受保护的方法实际上是像C++、Java和C#这样的语言的一个重要弱点。它们基本上告诉其用户:我不想学习和发展。这样做的后果(以及更多的早期绑定)是,这些语言需要更多的BDUF,因此对于现代(敏捷)开发过程来说可用性较差。


2
状态由属性定义,您的方法应该是公共的,如果您觉得它们应该是私有的,那么您可能应该创建一个不同的类。面向对象理论不支持私有方法,这只是一种概念,我认为它是由语言引入的,它是糟糕实践、难以维护和无法测试代码的主要来源之一。 - fd8s0
2
@Angel,我在转换到Smalltalk后10年的Java和Delphi时发现,私有和受保护的方法会破坏可扩展性和重用性。你可能想尝试一下并学习真正的面向对象编程。fd8s0 +1 - Stephan Eggermont
方法可以有很多用途。作为对象接口的一部分提供服务是最突出的。但是,方法也可以是最低级别的分解的一部分。提取私有方法是一种非常有用的重构技术,当您想要命名其他方法的某个部分以使其更易读时使用。然而,如果这个私有方法开始被使用,它实际上会破坏这种情况下的可扩展性。在方法级别上,私有是一个有用的概念。也许这种对私有方法的使用是由于复杂的企业代码与像Java这样的语言表达能力较低相结合,但它确实有其用途。 - virgo47
@fd8s0 点赞,非常有趣的观点!您能否提供一些链接/参考资料来支持您的说法“面向对象理论不支持私有方法”?谢谢。 - lambdas
我不擅长阅读书籍,但是因为他们在大学使用的那本书只是某个人写的(这不像代数理论),所以我和斯蒂芬一样,它可能全部来自Smalltalk,该语言并没有强制实施可访问性,据我记得,面向对象的主要目标是拥有小的对象,它们有自己的职责,如果你开始链接私有方法,那通常会变得非常复杂,并且它没有任何意义,因为其他对象无法通过它与您的对象“交谈”,我个人无法阅读私有方法,当我看到一个时,我将代码标记为垃圾/需要重新思考。 - fd8s0
显示剩余3条评论

4
第一个问题是什么是私有/受保护的访问修饰符?从根本上说,这不是关于安全性或保密性。它是关于向用户公开正确的接口。基于此,使用受保护/私有类别和专门用于该目的的语言结构之间几乎没有区别。
我甚至会说,具有私有/受保护的可见性修饰符比实际解决问题更加复杂。
除此之外,我认为私有/受保护的可见性不是对这个 问题 的好答案。

-3
至少,Smalltalk 应该有一个文本约定,即以“下划线”开头的方法名禁止在对象之外调用。不幸的是,我认为“下划线”不允许作为方法名的第一个字符。

在一些Smalltalk方言中,选择器中允许使用下划线。从历史上看,下划线被用作左箭头(赋值运算符)的替代符号。 - Frank Shearar
4
使用私有类别可以更自然地以 Smalltalk 的方式实现这一点。 - Davorin Ruševljan
1
我会参考被接受的答案来解释为什么这不是一个好主意。它会鼓励写糟糕的代码。有一些开发人员极力反对拥有许多类的想法,但这正是面向对象编程(OOP)的核心,即拥有许多可以重复使用的小类。 - fd8s0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接