小编San*_*ozi的帖子

Mixins vs scala中的成分

在java世界中(更确切地说,如果你没有多重继承/ mixins),经验法则很简单:"赞成对象组合而不是类继承".

如果你还考虑mixins,我想知道它是否/如何改变,特别是在scala中?
mixins被认为是多重继承的方式,还是更多的类组合?
是否还有一个"赞成对象组成超类组成"(或其他方式)指南?

当人们使用(或滥用)mixins时,我已经看到了一些例子,当对象组合也可以完成这项工作时,我并不总是确定哪一个更好.在我看来,你可以用它们实现非常相似的东西,但也有一些差异,一些例子:

  • 可见性 - 使用mixins,一切都成为公共API的一部分,而不是组合的情况.
  • 冗长 - 在大多数情况下,mixins不那么冗长,也更容易使用,但情况并非总是如此(例如,如果你也在复杂的层次结构中使用自我类型)

我知道简短的回答是"它取决于",但可能有一些典型的情况,当这个或那个更好.

到目前为止,我可以提出一些指导原则(假设我有两个特征A和B,A想要使用B中的一些方法):

  • 如果你想用B中的方法扩展A的API,那么就是mixins,否则就是组合.但是,如果我创建的类/实例不是公共API的一部分,它就无济于事.
  • 如果你想使用一些需要mixins的模式(例如Stackable Trait Pattern),那么这是一个简单的决定.
  • 如果你有循环依赖,那么mixins与self类型可以提供帮助.(我尽量避免这种情况,但这并不容易)
  • 如果你想要一些动态的,运行时决定如何组合然后对象组合.

在很多情况下,mixins似乎更容易(和/或更简洁),但我很确定它们也有一些陷阱,比如"神级"和其他两篇artima文章中描述的其他:第1 部分,第2部分(BTW it在我看来,大多数其他问题与scala不相关/不那么严重.

你有更多这样的提示吗?

scala composition mixins

77
推荐指数
2
解决办法
8391
查看次数

Scala中的动态混合 - 是否可能?

我想要实现的是正确实施

def dynamix[A, B](a: A): A with B
Run Code Online (Sandbox Code Playgroud)

我可能知道B是什么,但不知道A是什么(但如果B有自我类型,那么我可以在A上添加一些约束).scala编译器对上面的签名很满意,但我还不知道实现的样子 - 如果可能的话.

我想到了一些选择:

  • 使用反射/动态代理.
    • 最简单的情况:A是Java级别的接口+我可以实例化B并且它没有自我类型.我想这不会太难(除非我遇到一些令人讨厌的意外问题):
      创建一个新的B(b),还有一个实现A和B的代理,并使用委托给a或b的调用处理程序.
    • 如果B无法实例化,我仍然可以创建它的子类,并按照上面的描述进行操作.如果它也有自我类型,我可能需要一些代表团到处,但它可能仍然有效.
    • 但是,如果A是具体类型并且我找不到合适的接口呢?
    • 我会遇到更多问题(例如与线性化相关的东西,或者帮助Java互操作性的特殊构造)?
  • 使用一种包装代替mixin并返回B [A],a可从b访问.
    不幸的是,在这种情况下,调用者需要知道嵌套是如何完成的,如果混合输入/包装多次完成(D [C [B [A]]])可能会非常不方便,因为它需要找到正确的嵌套级别可以访问所需的功能,所以我不认为它是一个解决方案.
  • 实现编译器插件.我没有经验,但我的直觉是它不会是微不足道的.我认为Kevin Wright的autoproxy插件有一个类似的目标,但它不足以解决我的问题(但是?).

你有其他可能有用的想法吗?你会推荐哪种方式?期待什么样的"挑战"?
或者我应该忘记它,因为目前的Scala限制是不可能的?

我的问题背后的意图:说我有一个业务工作流程,但它不是太严格.一些步骤具有固定顺序,但其他步骤没有,但最后必须完成所有步骤(或者其中一些步骤需要进一步处理).
更具体的例子:我有一个A,我可以添加B和C. 我不在乎先做哪个,但最后我需要A带B和C.

评论:我对Groovy不太了解,但是我想出了这个问题,我想这或多或少与我想要的一样,至少在构思上.

scala mixins

40
推荐指数
1
解决办法
7167
查看次数

您是否应始终使用Java编写接口代码

我理解编码到接口的原理 - 将实现与接口分离,并允许交换接口的实现.

我应该编写我编写的每个类的接口代码还是过度杀伤?我不想将项目中的源文件数量增加一倍,除非它确实值得.

我可以使用哪些因素来决定是否按接口编码?

java oop interface

36
推荐指数
3
解决办法
1万
查看次数

scala中的自我类型继承

说我有以下特征:

trait A

trait B { this: A => }

trait C extends B // { this: A => }
Run Code Online (Sandbox Code Playgroud)

编译器错误:illegal inheritance; self-type C does not conform to B's selftype B with A
如果我取消注释自我类型注释,编译器很高兴.

我认为很明显为什么C也需要这种自我类型.我不明白为什么它不能从A"继承"它,如果编译器已经知道它需要它?

我认为当你使用具有复杂层次结构的自我类型时,它可以减少冗长,特别是如果你混合了大量的特征,每个特征都有自己的自我类型.

我想可能有一个很好的理由当前的行为,我只是找不到/弄清楚它是什么.

起初我认为它可能与mixin线性化有关,但在我看来它并没有在这里发挥(即使我有更多的特征与更复杂的自我类型混合).

在某些情况下会引起歧义吗?如果是这样,为什么在没有歧义的情况下它不能起作用?

或者它与正确实施它的一些困难有关?

我可以找到关于这个主题的一些讨论(比如自我类型不是继承的),但是他们大多只是陈述问题并得出结论是没有太多解释和/或解决方案(如果存在)的情况.

inheritance scala mixins self-type

9
推荐指数
1
解决办法
1752
查看次数

基于Play框架中的查询参数进行路由

我的Web应用程序将从外部系统触发.它将调用我的应用程序的一个请求路径,但对不同类型的请求使用不同的查询参数.

其中一个参数是"动作",它定义了要做的事情.其余的参数取决于"行动".

所以我可以得到这样的请求参数:

action=sayHello&user=Joe
action=newUser&name=Joe&address=xxx
action=resetPassword
...
Run Code Online (Sandbox Code Playgroud)

我希望能够在路由文件中对其进行类似的编码以进行播放,因此它可以执行基于查询参数的路由以及尽可能多的其他参数验证.

我所拥有的是具有大量可选参数的所有这些可能性的路由.处理它的动作以大模式匹配开始,以进行调度和参数验证.

谷歌搜索和检查SO只是弹出了大量的样本,其中params以某种方式编码在请求路径中,因此多个路径被路由到相同的操作,但我想反过来:一个路径路由到不同的操作.

我的一位同事说我们可以有一个"调度程序"动作,只根据"动作"参数重定向.它会比当前的解决方案更具结构性,但它不会消除应该有选择地传递给下一个动作的可选参数的长列表,所以我希望有人知道一个更好的解决方案:-)

BTW调用我的应用程序的外部系统是由另一家公司开发的,我对此设计没有任何影响,因此不能改变我的应用程序触发方式.

scala playframework-2.0

8
推荐指数
1
解决办法
7196
查看次数

在scala中使用我的函数 - 在函数上应用隐式转换

当我想使用隐式方法将函数转换为其他函数时,我遇到了一些问题.

我正在Scala 2.8中实现一个小型DSL用于测试目的.它应该支持实例上的各种检查(断言,如果你喜欢).整个DSL有点复杂,但下面的简化示例显示了我的问题:

object PimpMyFunction {

  class A(val b: Int)

  def b(a: A) = a.b

  class ZeroCheck(f: A => Int) {
    def isZeroIn(a: A) = f(a) == 0
  }

  implicit def fToCheck(f: A => Int): ZeroCheck = new ZeroCheck(f)     

  def main(args: Array[String]) {
    val a0 = new A(0)
    val a1 = new A(1)

    println(fToCheck(b).isZeroIn(a0))
    println(fToCheck(b).isZeroIn(a1))

    println(b.isZeroIn(a0)) 
  }
}
Run Code Online (Sandbox Code Playgroud)

前两个的println线(当我明确地调用转换方法)编制,做工精细,但最后一个(当我想依靠implicits)产生错误:
Compile error: missing arguments for method b in object PimpMyFunction; follow this method with '_' if you …

scala implicit scala-2.8

3
推荐指数
1
解决办法
693
查看次数