Scala有两种表达对象组合的方法:原始的self-type概念和众所周知的简单组合。我想知道在哪些情况下应该使用哪个。
它们的适用性显然有所不同。Self-type要求您使用traits。对象组合允许您在运行时使用var声明更改扩展。
撇开技术细节不谈,我可以想出两个指标来帮助分类使用情况。如果某个对象被用作复杂结构(如树)的组合器或者只有几个类似类型的部分(1个汽车对4个轮子的关系),那么就应该使用组合。这里有一个极端相反的用例。假设一个trait变得太大以至于无法清晰地观察它并且被分裂了。很自然,你应该使用self-types来处理这种情况。
这些规则并不是绝对的。您可以为代码转换使用额外的工作。例如,您可以用Product4的self-typing替换4个轮子的组合。您可以使用`Cake[T <: MyType] {part: MyType}`而不是`Cake{this: MyType =>}`来处理蛋糕模式依赖项。但是,这两种情况都似乎违反直觉,并给您增加了额外的工作。
还有很多边界用例。一对一的关系非常难以决定。有没有简单的规则来决定哪种技术更可取?
self-type使您的类变成抽象的,组合使您的代码冗长。self-type给您带来了命名空间混合的问题,并且还让您免费获得了额外的类型(您不仅有两个元素的鸡尾酒,还有汽油机油鸡尾酒,即汽油弹)。
我该怎么选择它们?有什么提示吗?
更新:
让我们讨论以下示例:
适配器模式。使用自我类型和组合方法有哪些好处?
它们的适用性显然有所不同。Self-type要求您使用traits。对象组合允许您在运行时使用var声明更改扩展。
撇开技术细节不谈,我可以想出两个指标来帮助分类使用情况。如果某个对象被用作复杂结构(如树)的组合器或者只有几个类似类型的部分(1个汽车对4个轮子的关系),那么就应该使用组合。这里有一个极端相反的用例。假设一个trait变得太大以至于无法清晰地观察它并且被分裂了。很自然,你应该使用self-types来处理这种情况。
这些规则并不是绝对的。您可以为代码转换使用额外的工作。例如,您可以用Product4的self-typing替换4个轮子的组合。您可以使用`Cake[T <: MyType] {part: MyType}`而不是`Cake{this: MyType =>}`来处理蛋糕模式依赖项。但是,这两种情况都似乎违反直觉,并给您增加了额外的工作。
还有很多边界用例。一对一的关系非常难以决定。有没有简单的规则来决定哪种技术更可取?
self-type使您的类变成抽象的,组合使您的代码冗长。self-type给您带来了命名空间混合的问题,并且还让您免费获得了额外的类型(您不仅有两个元素的鸡尾酒,还有汽油机油鸡尾酒,即汽油弹)。
我该怎么选择它们?有什么提示吗?
更新:
让我们讨论以下示例:
适配器模式。使用自我类型和组合方法有哪些好处?