【问题标题】:Single responsibility in smalltalkSmalltalk 中的单一职责
【发布时间】:2011-06-18 10:42:22
【问题描述】:

如果Single Responsibility Principle 适用于 OOP 并且 smalltalk(以及 &ruby 也是)被认为是最 OO 语言之一,为什么 Object 类可以响应这么多消息?

来自Object methodDict explore的几个:

  • 检查、探索、浏览、打印:打开:
  • 接受(所有对象的访客模式?)
  • copy、deepCopy、join、joinTo、at:、at: 修改:
  • asString、asFunction、asOrderedCollection(为什么不也 asSet?)
  • 海边的:asLink、asJson、asJavascript

这不是对象的责任(例如,用户域模型应该只对其私人消息、付款等感兴趣)

编辑:其中一些是有意义的(asString、asOrderedCollection、accept、notify),而另一些看起来很奇怪(at:、asFunction、deepCopy、join、joinTo)

【问题讨论】:

  • 哇,我们抱怨 .NET 的 Object 类太大(总共只有 7 个方法)!
  • 嘿,Object.new 在 ruby​​ 1.9.2 中有 56 个方法。
  • Seaside(基于pharo smalltalk)图片中Object methodDict中有370个方法:-)
  • 好吧,Smalltalk 已经过时了。您为什么认为单一责任原则被发明了?

标签: ruby oop object smalltalk


【解决方案1】:

您必须考虑 Smalltalk 的模块化特性。即,方法定义独立于类定义,因此Object 上的方法可以与它们相关的应用程序(例如,Seaside)打包。这些扩展方法不是基本系统的一部分,所以它们只是从它们所属的包的角度向它们的类添加职责。其中许多方法都是简单的双重调度点:如果 anObject asFoo 只是简单地委托给 Foo fromObject: anObject,我不会说它给类增加了太多责任。

inspectcopydeepCopy 等反射方法在概念上在 Object 上占有一席之地,但我同意有更好的反射架构 (Mirrors)。

现在,Smalltalk 可能是具有优美原则的理想选择,但您必须对特定的实现持保留态度:)

Smalltalk 系统有演变成大型单体系统的趋势,因为更改基本系统非常容易,而且很容易将映像用作开发工件,绕过持续集成的良好实践。最后,很多这些有趣的班级责任是由于历史/现实原因造成的; Squeak 尤其如此,因为它主要是作为快速多媒体实验的平台而开发的,而不是用于软件工程教育或行业目的(Pharo 的目标是)。

【讨论】:

  • 感谢您的回答和有趣的阅读!对我来说,objectInstance class 似乎比reflectorInstance reflect objectInstance getClass PHP 这样做更合乎逻辑和方便,我只是不喜欢它(在某些情况下返回反射代理会很酷 - 对于特定类)跨度>
  • 这里的问题是类有双重作用:1)作为一个建模概念:让anObject class访问工厂方法、类变量等是有意义的。2)作为运行时机制/program 实体:这显然是编译器/版本控制/IDE 所需的元级别,但该域代码不应访问。
  • 我不同意你的观点——参见 ruby​​ 的 act_as_whatever 方法——它们动态地将方法添加到类中——你将如何实现这一点?即使对 attr_accessor 生成也很有用
  • Ruby 需要这些元编程方法,因为开发人员必须处理文本文件。在 Smalltalk 中,我们将正在运行的程序修改为活动对象,因此元编程是通过一次性 IDE 命令完成的,很少出现在域代码中。没有像 Lisp 那样的宏工具。对于访问器,我们只是告诉浏览器请生成它们,它会创建 2 个新方法。重构也是如此。对于更复杂的东西,如果需要,我们可以生成整个类,但这不是常见的做法。
  • 似乎是更好的方法(所有支持的消息都显示在 IDE 中) - 但我仍然认为该对象应该知道它的类并且可以使用它来做一些 db-mapping 的东西。编辑:IDE/编译器是对象,域类也是 - 为什么让它公开访问如此糟糕?
【解决方案2】:

几个原因:

  • Object 和 ProtoObject 是 Smalltalk 对象模型的基础,所以它们的职责很大,比如处理复制、序列化等,这很正常。
  • The law of Demeter 在这里可能更重要:如果不是 Object 本身,谁来处理这些功能?
  • 其中许多函数用于调试和表示目的。您可以在没有浏览、探索和检查的情况下工作(但它们真的很有用)。

基本上,所有这些消息都代表了一个对象可以做的所有事情,而且你可以做很多事情。

【讨论】:

    【解决方案3】:

    因为在 Smalltalk 中 - 一切 都是对象,而根 Object 类本质上必须管理所有系统行为,包括类层次结构(因为所有类都是对象)和元类层次结构。

    权力越大,责任越大。

    在其他系统中,对象只是整个系统的一个子域,Object 不必做太多事情,因此不需要赋予那么多命名的职责。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-16
      • 2011-11-16
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多