mixin系统的背后动机之一是消除传统的依赖注入。这种“组件风格(component style)”编程的高潮是是.

    在我们的使用中,我们发现Scala本身删除了很多经典(构造函数)依赖注入的语法开销,我们更愿意就这样用: 它更清晰,依赖仍然植根于(构造)类型,而类构造语法是如此微不足道而变得轻而易举。有些无聊,简单,但有效。对模块化编程时使用依赖注入,特别是,组合优于继承—这使得程序更加模块化和可测试的。当遇到需要继承的情况,问问自己:在语言缺乏对继承支持的情况下如何构造程序?答案可能是令人信服的。

    依赖注入典型的使用到 trait (译注:可以理解为和Java中Interface相似)

    这是常见的注入工厂 — 用于产生其他对象的对象。在这些例子中,更青睐用简单的函数而非专有的工厂类型。

    1. mkStream(PublicTweets).subscribe { tweet => publicCount += 1 }
    2. mkStream(DMs).subscribe { tweet => dmCount += 1 }
    3. }

    保持traits简短并且是正交的:不要把分离的功能混在一个trait里,考虑将最小的相关的意图放在一起。例如,想象一下你要做一些IO的操作:

    1. trait IOer {
    2. def read(n: Int): Array[Byte]

    分离两个行为:

    可以将它们以混入(mix)的方式实现一个IOer : new Reader with Writer…接口最小化促使更好的正交性和更清晰的模块化。

    Scala有很丰富的可见性修饰。使用这些可见性修饰很重要,因为它们定义了哪些构成公开API。公开APIs应该限制,这样用户不会无意中依赖实现细节并限制了作者修改它们的能力:
    它们对于好的模块化设计是至关重要的。一般来说,扩展公开APIs比收缩公开的APIs容易的多。差劲的注释(annotation)也能危害到你代码向后的二进制兼容性。(译注:comments和annotation都可翻译成注释,但意义不同。annotation在Java和Scala有特定的含义)

    private[this]

    1. private val x: Int = ...

    它对这个类的所有实例来说都是可见的(但对其子类不可见)。大多情况,你想要的是 private[this] 。

    1. private[this] val: Int = ..

    这个修饰限制了它只对当前特定的实例可见。Scala编译器会把private[this]翻译为一个简单的字段访问(因为访问仅限于静态定义的类),这样有时有助于性能优化。

    单例类型

    在Scala中创建单例类型是很常见的,例如:

    在这种情况下,可以通过声明返回类型来限制可见性:

    1. ...
    2. }

    不要在正常情况下使用结构类型。结构类型有着便利且强大的特性,但不幸的是在JVM上的实现不是很高效。
    然而——由于实现的怪癖——它提对执行反射(reflection)供了很好的简写形式。

    1. val obj: AnyRef