好久没写Scala的学习笔记了,前阵子看到UAP的概念,感觉在Java中应该是不常见的,记录一波备忘一下,以下是正文部分。 是什么(what) 统一访问原则(Uniform Access Principle),简称UAP。 是为了让上游在访问一个字段和访问一个无参数方法时,体会不到差别。通常来说,字段代表这个东西底层是有存储的,而方法代表这个东西是计算得来的。 所以Bertrand Meyer的原话是: All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation. 在Java中,很大体上这么理解:有一个叫Shape的类,明确能知道里面有width和height 2个字段,那么,当你调用shape.getArea()的时候,这个area可能来自于width*height,也可能来自于底层真实存在一个叫area的字段。 如果说Java是通过方法的形式来混淆字段和方法,那么在Scala中就是用字段的形式来混淆字段和方法。直接让上游通过shape.area来访问。为什么(why) 说实话,翻阅了不少资料,并不是很能理解这种做法的好处,大概是能提供更好的封装性吧?怎么做(how) 以Scala代码为例,可以这么定义:class Shape(val w: Int, val h: Int) { val area = w * h } 也可以这么定义(常规的定义一个空参方法):class Shape(val w: Int, val h: Int) { def area() = w * h } 以上两种,都可以通过shape.area来访问,无法感知到area是字段还是方法。 当然,我们还可以更进一步:class Shape(val w: Int, val h: Int) { def area = w * h } 注意,和第一种方式比,我们把val换成了def。 那么到底是采用def area()还是def area呢?一般来说,有如下约定:有副作用时带括号,否则不带括号。 同时,如果定义了字段area,就不能在定义方法area(),两者不能同时存在。特别说明 正常情况下,我们都应该遵守UAP。但是,如果字段是计算得到的,且有很大的开销。那么,就应该违背UAP,显式的提示用户。