定义

特质能够要求混入它的类扩展自还有一个类型,可是当使用自身类型(self type)的声明来定义特质时(this: ClassName =>)。这种特质仅仅能被混入给定类型的子类其中。

如果尝试将该特质混入不符合自身类型所要求的类时,就会报错。

从技术角度上看。自身类型是在类中提到this时,对于this的如果性类型。从有用角度上看,自身类型指定了对于特质能够混入的详细类的需求。如果你的特质仅用于混入还有一个或几个特质。那么能够指定那些如果性的特质。

自身类型在依赖注入的应用

在通过组件构建大型系统,而每一个组件都有不同的实现的时候。我们须要将组件的不同选择组装起来。

通常组件之间存在某种依赖关系,比方,数据訪问组件可能会依赖日志功能。

每一个组件都描写叙述了它所依赖的其它组件的接口,而对实际组件实现的引用是在应用程序被组件起来的时候“注入”的。

对于Scala来说,能够通过特质和自身类型达到简单的依赖注入的效果。

自身类型实现依赖注入

对于日志功能trait Logger {def log(msg: String)},它有两个实现:ConsoleLoggerFileLogger

用户认证特质有对日志功能的依赖,用于记录认证失败:

trait Auth {
this: Logger =>
def login(id: String, password: String): Boolean
}

应用逻辑依赖于上述两个特质,如此定义:

trait App {
this: Logger with Auth =>
...
}

然后我们能够组装应用。object MyApp extends App with FileLogger("test.log") with MockAuth("users.txt")。这里将组件黏合成了一个大类型。

蛋糕模式实现组件配置设计

蛋糕模式能够给出更好的设计。对每一个服务都提供一个组件特质。

组件特质包括:

  • 不论什么所依赖的组件,以自身类型表述
  • 描写叙述服务接口的特质
  • 抽象的val。该val将被初始化成服务的一个实例
  • 能够有选择地包括服务接口的实现
trait LoggerComponent {
trait Logger {...}
val logger: Logger
class FileLogger(file: String) extends Logger {...}
...
} trait AuthComponent {
this: LoggerComponent => //自身类型使得能够訪问日志器 trait Auth {...}
val auth: Auth
class MockAuth(file: String) extends Auth {...}
...
}

这段代码中,我们使用自身类型表示认证组件对日志器组件的依赖。

通过在程序中进行组件配置能够让编译器帮助我们校验模块间的依赖关系:

object AppComponents extends LoggerComponent with AuthComponent {
val logger = new FileLogger("test.log")
val auth = new MockAuth("user.txt")
}

转载请注明作者Jason Ding及其出处

jasonding.top

Github博客主页(http://blog.jasonding.top/)

CSDN博客(http://blog.csdn.net/jasonding1354)

简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)

Google搜索jasonding1354进入我的博客主页

【Scala类型系统】自身类型(self type)引用的更多相关文章

  1. scala类型系统 type关键字

    和c里的type有点像. scala里的类型,除了在定义class,trait,object时会产生类型,还可以通过type关键字来声明类型. type相当于声明一个类型别名: scala> t ...

  2. Scala类型系统——高级类类型(higher-kinded types)

    高级类类型就是使用其他类型构造成为一个新的类型,因此也称为 类型构造器(type constructors).它的语法和高阶函数(higher-order functions)相似,高阶函数就是将其它 ...

  3. scala类型系统:24) 理解 higher-kinded-type

    首先我们从最基本的泛型来看: 现在我们对上面泛型中的类型参数再进一步,也是个泛型会如何呢? 可以看到,java中不支持类型参数也是泛型类型的情况,而scala支持.这是一个很重要的区别,scala在类 ...

  4. 第54讲:Scala中复合类型实战详解

    今天学习了scala的复合类型的内容,让我们通过实战来看看代码: trait Compound_Type1trait Compound_Type2class Compound_Type extends ...

  5. 第53讲:Scala中结构类型实战详解

    今天学习了scala的结构类型,让我们看看代码 class Structural {def open() = print("A class interface opened") } ...

  6. Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  7. Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  8. Scala的Option类型

    Scala的Option类型 为了让所有东西都是对象的目标更加一致,也为了遵循函数式编程的习惯,Scala鼓励你在变量和函数返回值可能不会引用任何值的时候使用Option类型.在没有值的时候,使用No ...

  9. 反射,得到Type引用的三种方式

    1.使用System.Object.GetType()得到Type引用 使用一个SportsCar实例得到类型信息 SportsCar sc=new  SportsCar(); Type t=sc.G ...

随机推荐

  1. adb pull 文件夹的时候注意

    传说之美 分享快乐 记录生活 学习探索 博客园 首页 新随笔 联系 管理 订阅 随笔- 75  文章- 0  评论- 19  Android 用adb pull或push 拷贝手机文件到到电脑上,拷贝 ...

  2. Spring 4.3.11.RELEASE文档阅读(二):Core Technologies_IOC

    在看这部分内容的时候,想了一些问题: 容器: 1,什么是容器 用来包装或装载物品的贮存器 2,容器能做什么 包装或装载物品 3,为什么需要容器 为什么要使用集装箱?如果没有容器会是什么样? 4,常见的 ...

  3. API生命周期

    这一系列的文章,主要是结合了参加Oracle code之后对于API治理的记录收获,以及回到公司后,根据公司目前的一些现状,对此加以实践的过程总结 API生命周期通常包括八个内容,而安全策略贯穿始终. ...

  4. 【Luogu】P3358最长k可重区间集问题(费用流)

    题目链接 这题费用瘤,数据貌似还是错的. 把线段抽象抽象拆成两个点,入点表示左端,出点表示右端,连上容量为1费用-长度的边. 不相交线段随便连下,源点向拆出的原点S'连费用为0容量k,然后跑费用流. ...

  5. localStorage的用法

    1.在HTML5中,本地存储是一个window的属性,包括localStorage和sessionStorage,前者是一直存在本地的,后者是伴随着session,窗口一旦关闭就消失了.二者用法完全相 ...

  6. HDU——2054A==B?

    A == B ? Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  7. 模仿锤子手机的bigbang效果

    <!DOCTYPE html> <html style="height: 100%"> <head> <meta http-equiv=& ...

  8. pstack

    pstree  linux 查看进程树 和 包含的线程 pstack 显示每个进程的栈跟踪

  9. MongoDB管理与监控

    https://blog.csdn.net/Chen_Victor/article/details/74855050 https://www.cnblogs.com/zhangyinguang/p/5 ...

  10. Jenkins自动化部署入门(一)

    开始使用 Jenkins 这一段时间,技术总监为了减少测试环境每次提交新增接口都要部署项目的时间,搞了一个jenkins持续集成github.docker,这样只要每次push代码都会自动部署,确实节 ...