11

Scala 有两种表达对象组合的工具:原始的自我类型概念和众所周知的琐碎组合。我很好奇我应该在哪些情况下使用。

它们的适用性存在明显差异。自我类型要求你使用特质。对象组合允许您在运行时使用 var 声明更改扩展。

抛开技术细节,我可以想出两个指标来帮助对用例进行分类。如果某些对象用作复杂结构(例如树)的组合器,或者仅具有几个类似类型的部件(1 辆汽车与 4 个轮子的关系),则应该使用组合。有极端相反的用例。让我们假设一个特征变得太大而无法清楚地观察它并且它被分裂了。在这种情况下,您应该使用自类型是很自然的。

这些规则不是绝对的。您可能需要做额外的工作来在这些技术之间转换代码。例如,您可以用 Product4 上的自键入替换 4 个轮子组合。您可以使用Cake[T <: MyType] {part : MyType}而不是Cake { this : MyType => }蛋糕模式依赖项。但这两种情况似乎都违反直觉,并且会给您额外的工作。

虽然有很多边界用例。一对一的关系很难决定。是否有任何简单的规则来决定哪种技术更可取?

自类型使您的类抽象,组合使您的代码冗长。self-type 给你混合命名空间的问题,也给你额外的免费打字(你不仅得到了两种元素的混合物,还有被称为汽油炸弹的汽油发动机油混合物)。

我该如何选择它们?有哪些提示?

更新:

让我们讨论以下示例:

适配器模式。它对自编和组合方法有什么好处?

4

1 回答 1

3

以下提示来自启发式方法(当算法方法不切实际时使用的试错法解决问题的方法),并且不受任何公式的支持(基于数学的推理)。

***此处给出的提示应参考随附的提示进行评估,没有提示是区分组合和自键入用例的完美规则。

(虽然遵循下面提到的提示,但我不在乎或关注代码的冗长或行数或编程工作输入。)

组合(字典含义):将部分或元素组合成一个整体的行为(琐碎组合)

trait(字典含义):显着的特征或品质

Trivial Composition 的提示(可以通过超子类机制或关联关系来实现)(例如 Car 和 Wheels):

  • 可以离散计数(例如车轮)

  • 可以进一步分类(基于不同的标准)(例如车轮 - 合金车轮,钢轮等)

  • 可以添加或删除(注:我们说轮子停止时,实际上是轮子的转速停止了,当我们说心脏停止时,实际上是心脏的搏动速度变为零了)

  • 一般适用于few(宇宙中有些车辆有些机械有轮子)(few可以是10-15,也可以是几百万——解释一下让我们理解这个说法:当地质学家谈时间,说前段时间时,意思是几百万几年前,这取决于实际的主题)

自我类型(特征)的提示(例如汽车和速度):

  • 它是一维的(不是物理方面),可以绘制在数轴上(无论物理单位是什么)(例如速度)

  • 哪个不能自然地进一步分类(例如速度)(或者至少你不会进一步分类)这里,自然这个词用来传达含义,分类它你必须取决于你自己的标准,并且会有一个明确的将其分类为数百万个子类型的可能性。移动,你可以拥有数百万个移动子特征......像之字形移动,旋转和前进,......(具有各种排列组合的百万可能性)。

  • 可以增加或减少或停止(例如速度、愤怒、爱等)

  • 在非常遥远的课程中通常可以看到/可以看到(例如光速,地球速度,跑步者的速度)

  • 一般适用于许多(宇宙中大多数(这里每个)物体都有速度)

    软件开发就像创造自己的宇宙,作为创造者,你定义了一切。在您的域(您自己的宇宙)中遥远的类中会看到一个特征。

请注意,对于用于琐碎作文的部分,我没有看到任何语言(我知道的很少)中的任何特定词(这里是 trait 的对应词)。

进一步说明:

要获得答案,您需要深入了解软件开发的面向类或面向对象的哲学,并且需要了解编程语言(如 java 和 scala(或更多))的创建者的思想和逻辑在这些语言中灌输了面向类或面向对象的范式。

您需要的另一件事是对语义(通过对意义和形式的变化进行分类和检查来研究意义或语言发展的研究)的深入理解,我们用来描述现实世界和关键字背后的语义(在编程语言中) ) 我们作为程序员使用。

我相信,当我们创建课程时,我们希望将现实世界体现为软件。该类成为现实世界中某些事物的表示,可能是汽车、人类、星星、梦想、思想或想象等。

当有人说“轮子”时,你会清楚地看到它的形状和应用,你会想到驱动轮或在道路上滚动的轮子。轮子永远是某事的一部分。它可以用离散的数字来计算。轮子可以根据材料、应用、尺寸等标准进一步分类。轮子一样的东西符合琐碎组合的条件。

当有人说“速度”时,你不会有任何清晰的画面……没有形状……没有颜色……但你可以将它与宇宙中任何移动的(相对论)部分联系起来。这是一个特点,特质。速度不是任何事情的一部分。它可以在那里,也可以不在那里。它可以绘制在一条线上(方向 + 或 - )。很难对“速度”进行分类。速度之类的东西符合特质。

在我看来,

如果我们将 Car 作为一个类(对象),“速度”之类的特性应该作为 scala 中的特性。和“轮子”一样的零件,组件应该作为“琐碎的组合”进入。类似“速度”的特征不会有自然分类,其中“车轮”可以有很多类,它们本身是独立的对象(实际上)。

如果我们把 Human 作为一个类(Oject),“愤怒、哭泣、大笑等”。类似的行为应该作为特征和“手、腿、大脑、心脏等”。应该作为“琐碎的组合”进入,因为它们本身是独立的对象(实际上)。

如果我们想到名字,它可以给任何人和任何人命名,例如我们最近的星星有一个名字“太阳”,最高的山有一个名字“喜马拉雅”,我的狗有一个名字“洛基”,河流有一个名字“亚马逊” “....”名字“是一个特征,不应该被认为是“琐碎的作文”。

如果我们想到心,动物的心就是它们的一部分。必须将其视为“微不足道的构图”,而不是作为特征。

什么是类?

类是特定对象的描述或蓝图。

什么是对象?

对象是可以通过类定义来描述的现实。

(鸡蛋还是母鸡?哪个先出现?)我相信,软件工程师首先想到对象,然后(描述它们或制作它们)(从蓝图)定义类。(请注意IN Object Oriented Modeling and Design - Class and Object 是相辅相成的存在。)问题(http://en.wikipedia.org/wiki/Circle-ellipse_problem)因为后者与继承或子类型多态性有关。)

接口:使单独的、有时不兼容的元素能够有效协调的东西

软件开发就像创造自己的宇宙,作为创造者,你定义了一切。组合应该优先于继承。(四人组 - 设计模式)

于 2012-06-17T17:12:02.323 回答