Groovy探索之闭包 五
《Groovy探索之闭包》进入到第五篇,重点来讲讲闭包和模式的关系。我们知道,在Java界,设计模式是名声在外了。由于模式有很好的扩展性,我们通常很喜欢使用它们。但在Java语言中使用模式,我们最大的抱怨就是代码臃肿;由于过于对依赖进行过多的拆分,造成类个数成倍增加。一句话,扩展性虽然好,但编码的效率却低。
比如说,我们在Java中常用到的Collections.sort(Collection collection,Comparator comparator)方法,就使用到了策略模式,所谓“策略模式”,就是对算法的封装。而Collections.sort(Collection collection,Comparator comparator)方法中,对比较算法进行了封装。
具体说来,Collections.sort(Collection collection,Comparator comparator)方法有了明确的排序算法,但它却不能确定具体的比较算法,因为不知道“Collections.sort(Collection collection,Comparator comparator)”方法的使用者会使用JavaBean的哪个属性进行比较,也不知道是比大,还是比小。因此,它必须把比较算法封装起来,交给使用者自己来实现。
有了上面的想法,JDK就这样来实现了。
首先,它定义了一个接口:
public
interface
Comparator {
public
int
compare(Object node1,Object node2);
}
这样一个接口,它定义了使用者的输入参数,必须是两个对象进行比较;比较的结果必须返回一个int类型。
然后,sort方法就可以实现了,我假设JDK使用了一个简单的排序算法:
public
class
Collections {
public
static
void
sort(List list,Comparator comparator)
{
for
(
int
i=0;i<list.size()-1;i++)
{
for
(
int
j=i+1;j<list.size();j++)
{
if
(comparator.compare(list.get(i), list.get(j))>0)
{
Object obj = list.get(i);
list.set(i, list.get(j));
list.set(j, obj);
}
}
}
}
}
上面,我就模拟了
sort
方法的实现过程,它使用的就是一个典型的策略模式。但是,我们在
Groovy
语言中,我只需要这么实现:
class
Collections {
def
static
sort
(List list,Closure closure)
{
(
0
..<list.
size
()-
1
).
each
{
i ->
(i+
1
..list.
size
()).
each
{
if
(closure.
call
(list[i],list[it])>
0
)
{
def
obj = list[i]
list[i] = list[j]
list[j] = obj
}
}
}
}
}
可以看到,在Groovy语言中的策略模式的实现省略了封装策略的接口,而使用闭包来代替了它。这样的用法当然更加方便和灵活。
如果有人认为使用接口更好,其实接口定义了一种契约,可以明确的告诉使用者它的输入参数和输出参数。而闭包则不能明确告诉使用者输入参数和输出参数。那么你也可以继续使用接口,但至少该接口的使用者可以更灵活一些,他可以使用闭包来实现你的接口,这也是闭包带来的好处。
其他的模式,如
Command
模式
,也可以使用上述方法进行简化。其实,有很多时候,用闭包来代替接口是不大可能的,但是在
Groovy
语言种,我们确实能够使用闭包来实现接口,这样的实现比使用实体类来实现接口更为方便,比使用内部类来实现接口更为灵活。至于怎么来使用闭包实现接口,我在《Groovy探索之闭包 三
》里面已经讲到过,这里就不再重述了。