首页 > 代码库 > 大数据Scala编程.问题集(02)
大数据Scala编程.问题集(02)
大数据Scala编程.问题集(02)
by 高焕堂
洞庭国际智能硬件检测基地 & 中云大数据中心(IDC) 首席架构师
微博:@高焕堂_台北
Q-02: Scala语言的trait具有什么设计涵意?
Answer:
大家都知道接口(Interface)的概念,也知道一个类(Class)或一个模块(Module)能实现多个接口。就像一个房间可以有多个门,或一座四合院可以有多个门口一样。如下图:
将四合院的概念对应到软件上,一个软件的类可以实践多个接口,如下图:
现在,先拿一个类和一个接口的设计架构来看看,如下图:
在一般软件设计上,接口(Interface)意味着:它就是一个纯粹抽象类(Pure abstract class)。也就是说,它内含一个或多个抽象函数(Abstract function),而且是公用(Public)的函数。Gamma等人在其所着 Design Patterns书里主张:
"Program to an interface, not an implementation."
(针对接口而写编程,不要针对实现。)
这意味了,通常架构师(团队)会先设计好接口,然后工程师(团队)再依循接口的定义而开发实现代码。于是,架构师团队与工程师团队,两个团队之间是相互分工合作(Collaboration)的。
由于架构师团队里,也常常含有开发者(或架构师兼工程师),因而也常常会去写一些代码,来实现接口里的抽象函数,提供一些接口的默认行为(Default behavior)。此时,所设计的架构会变成为:
将上图里的IA接口和IA_impl类,看成一个整体,特别称之为特性(Trait),如下图:
以上是从架构设计的角度来思考的,若对应到Scala代码,可表示如下:
// trait的定义
trait TA {
def transact(){ //默认行为代码
onTransact // 调用抽象函数
}
def onTransact // 抽象函数
}
// class的定义
class EVAPlane extends TA {
var manufacturer : String = ""
var capacity : Int = 0
var mfr_date : String = ""
def pr_capacity {
println(capacity)
}
def onTransact {
println("this is onTransact.")
}
}
// myApp
object myApp {
def main( args: Array[String] ) {
val p1 = new EVAPlane
val p2 = new EVAPlane
p1.transact
p2.transact
}
由于Scala代码编译(Compile)时,会转换成为JVM引擎可执行的ByeCode,其受限于JVM引擎的单继承(Single inheritance)的限制。在Scala语言里,无法实践架构师的多重接口及其默认行为的架构设计,如下:
但是,却能善用Scala的Trait来实践之,如下:
Scala借重JVM引擎的多重接口实现(Implement)机制,以及对象委托(Delegation)机制来实践上图的trait extends机制;而不是依赖 JVM引擎原有的class extends机制。如下图:
运用了JVM引擎级别的Implement和Delegation机制来实践Scala源代码级别的trait extends机制。如下图:
这样,一方面架构师团队可以定义其接口(Interface),例如设计出下图里的IA和IB,并撰写其接口的默认行为(Default behavior)代码,如下图里的IA_impl和IB_impl类,并以Scala的trait形式表达出来。
然后,将该trait交给工程师团队去撰写EVAPlane类或其子类的实现代码。达成了架构师团队与工程师团队的美好分工合作了;也实践了 "Program to an interface, not an implementation."(针对接口而写编程,不要针对实现。)的设计原则。
請繼續學習:高老師的相關視頻
相关文章:大数据Scala编程问题集(01)
~ end ~
大数据Scala编程.问题集(02)