我的杞人忧天

victor_jan 2009-12-18
最近才开始了解一下Scala, 看到他的代码确实会省很多关于how的代码。但看着看着也有点担心了。就因为他很多东西写起来太简单,反而感觉会造成同样功能代码大家到处各自写各自的问题。这对于一个项目来讲,好像又不是太好。
如:
val compare = (x: Int, y: Int) => x > y
list sortWith compare

确实太简单, 封成class有点过分。但如果有一天,有人想修改排序规则,那就要漫天找了, 如果大家都这样用的话。当然,上面的例子并不恰当,但问题却是这样。

如果像下边的,则对以后修改更好。但上边的写法太简单了,你还会像下边这样写吗?
class AComparator {
def compare(x: Int, y: Int) = x > y
}
list sortWith (new AComparator).compare
iaimstar 2009-12-18
你应该首先想明白一个语言适合的场所
包括开发人员的数量和素质,项目的周期和要开发的范围

很多语言不是用来解决所有问题的,会有他自己的实用范围
Eastsun 2009-12-18
我更喜欢这样写:
list sortWith { _>_ }
或者复杂一点
list sortWith { (x,y) => x>y }

不用去找排序规则了,直接在原地改就是。

LZ是复杂的东西用多了,反而不习惯简单的方式。
fineqtbull 2009-12-18
有点明白LZ的意思,在x>y这种判断逻辑在多处用到时,为了达到这种逻辑的重用和将来维护时的统一修改目的,的确是在一个地方统一定义比较好。看看下面这个object的方法如何,定义虽然复杂了一点,但引用时非常简单,以后修改起来也方便。

scala> object Comparer extends Function2[Int, Int, Boolean] {
     | override def apply(v1 : Int, v2 : Int) = v1 > v2
     | }
defined module Comparer

scala> List(2, 3, 1) sort Comparer
res4: List[Int] = List(3, 2, 1)
Eastsun 2009-12-18
如果说是为了重构,那么定义一个compare有什么不妥的?
只需将compare方法的定义放在一个object中
object Utils {
    val compare = (x: Int,y: Int) => x > y
}


使用的时候只需引入compare:
import Utils.compare

list sortWith compare


想修改排序逻辑,只要修改compare的定义即可。
先比之下,定义一个AComparator类有哪些好处?
fineqtbull 2009-12-18
Eastsun 写道
如果说是为了重构,那么定义一个compare有什么不妥的?
只需将compare方法的定义放在一个object中
object Utils {
    val compare = (x: Int,y: Int) => x > y
}


使用的时候只需引入compare:
import Utils.compare

list sortWith compare


想修改排序逻辑,只要修改compare的定义即可。
先比之下,定义一个AComparator类有哪些好处?

恩,还是这种方法好,不用定义显示的类或单例(匿名类还是有的),和我的定义object的方法异曲同工,而且更加简洁,在重用方面也没有问题。

引深开来还可以有这种实现
scala> object Utils {
     | def compare(v1 : Int, v2 : Int) = v1 > v2
     | }
defined module Utils

scala> List(2, 3, 1) sort Utils.compare
res5: List[Int] = List(3, 2, 1)
night_stalker 2009-12-18
API 设计需要遵守一个很简单的数学原理:使用越频繁的东西,写法就应该越简单。在几页纸里面找东西永远比在一本书里好找。写一堆 compare comparator …… 想搜出来在什么地方反而很麻烦。

“如果有一天有人想修改排序规则”是彻底的伪需求 …… 吃饱了没事干? 如果有一天有人不想用 AComparator 了,通通换成 BComparator 呢?
很明显 sortWith / sortBy 只是签名耦合,比实体耦合灵活得多,更容易扩展。任何函数只要签名是 (Int, Int) => Boolean 就能用作比较器;任何对象,不管是什么类,只要定义了签名为 (Int, Int) => Boolean 的这么一个函数,都能用作比较器 —— 不需要新建一个类就能重用已有比较方式,超级简单,why not?

sortBy 的逻辑在 99% 都是比较简单的,一眼就明白的,不用翻到 XComparator 的定义中去,读起来多流畅啊。至于那 1% 的情况,你也可以自造一个 XComparator,或者用已有的不叫 XComparator 的任何东西,而且不依赖于任何接口,多清爽啊。

另外,后头它做的事情,和实现 IComparable 接口很相似,不过这种事情很机械重复,交给计算机做最好了,比手动做的容易而且不好出错。
fineqtbull 2009-12-18
签名耦合 ,这个比较好理解,同样的还有Scala中的structural type吧。
Global site tag (gtag.js) - Google Analytics