First they ignore you
then they ridicule you
then they fight you
then you win
    -- Mahatma Gandhi
Chinese => English     英文 => 中文             
随笔-221  评论-1047  文章-0  trackbacks-0
Q: 什么是闭包(Closure)?
A: 我们可以把closure简单地理解为语句块,下面让我们来看一下方法声明和closure定义的相似点:
方法声明:
def sayHello(name) {
    println name
}

sayHello(
"山风小子")

closure定义:
def sayHello = { name ->
    println name
}

sayHello(
"山风小子")

通过代码比较,大家看出相似点了吧。
closure比方法更灵活,可以作为参数传入方法(这点类似于C++中的方法指针),而方法比如本例中的sayHello方法可以通过.&操作符来获得方法闭包
def sayHello(name) {
    println name
}

def sayHelloMethodClosure 
= this.&sayHello
sayHelloMethodClosure(
"山风小子")

def hello(c) {
    c("Daniel")
}

hello(sayHelloMethodClosure)

所以在Grails中大量的使用clsoure。


Q: ?.是什么

A: ?. 是‘安全引用符’,举例来说:
在Java中,为了程序的鲁棒性(robust),在对一个对象进行操作之前,我们会判断它是否为null
if (null != obj) {
  obj.doSomething();
}

而在Groovy就方便多了,您可以用?.来达到上面的目的
obj?.doSomething()

等价于
obj == null ? null : obj.doSomething()
如果obj为null,则obj?.doSomething()的结果为null,否则就正常执行与Java无异:)

实例:
def obj = null
println obj
?.hello() // 打印出null
由于obj为null,所以就不执行hello(),即便obj中没有定义hello这个方法也不会报错 :)


Q: it是什么?
A: 如果您没有在Groovy的Closure中定义任何变量,那么Groovy会自动帮您定义一个it变量。
举例来说:
// 此处的a为自己定义的变量
def c = { a -> 
    println a
}
c(
"Hello, world")

注意上下两段代码的区别,下面的Closure没有定义任何变量,当要引用传入的参数时,用it来表示
// 此处的it是Groovy自动帮我们定义的变量
def c = {
    println it
}
c(
"Hello, world")


Q: @Property是什么?
A: 这是以前旧版Groovy的写法,用来定义成员变量,但由于大家反应它太丑了,所以在Groovy1.0+中已不建议使用,请用def替代它。


Q: 如何定制closure的字符串表示?
A: 定制类的字符串表示一般是通过重写(override)toString方法来完成的:
class A {
    String toString() {
        
"I am A"
    }
}

def a 
= new A()
println 
"$a"

但定制closure的字符串表示,则稍微特殊一点,是通过it << "closure的字符串表示",
在Groovy1.1中,"$closure"会将StringWriter的一个实例传给closure的隐式变量it,并引起closure的执行
如果仅仅是closure()的话,并不会有StringWriter实例传给closure的隐式变量it
def c = {
    println 
"closure is executed."
   
// 将这条语句看作toString方法就可以了,注意要使用if (it) {}来判断一下 :)
   
if (it) {
        it << "I am a closure c"
    }
}

println 
"$c"

结果如下所示,闭包c先被执行,然后才执行println打印出closure的字符串表示
closure is executed.
I am a closure c



Q: 出现在闭包中的owner是什么?
A: owner其实就是‘拥有’此闭包的一个对象,举例来说:
class A {
    def c 
= {
         println 
"c's owner: $owner"
        
if (it) {
            it 
<< "closure c"
        }

        def innerC 
= {
            println 
"innerC's owner: $owner"
        }
    }

    String toString() {
        
'class A'
    }
}
def a 
= new A()
def innerC 
= a.c()
innerC()
运行结果:
c's owner: class A
c's owner: class A
innerC's owner: closure c


Q: 为什么Grails比Rails更适用于企业应用?(摘自《对Grails之误解》)
A: 原因很多,最显著的两个原因就是Spring和Hibernate。到目前为止,有不计其数的组织在采用Spring和HIbernate,他们都有既有的Spring上下文环境,以及已经构造好的Hibernate领域对象等。

在我开始参与Grails项目之前,我就经历过同样的情况。我们设计Grails的目的就是为了让它和这些框架尽可能无缝地整合起来。因此,我们打个比方,你可以把一个用Java编写的Hibernate领域模型及其对应的配置文件直接扔进Grails应用中,然后就可以使用动态的查询方法,并且直接使用GORM了。

此外,Grails控制器使用了标准的Servlet API对象(如request、response和session等),因此可以和其它的Servlet一起使用。毕竟,掀起它的盖头之后,我们会发现它不过是一个Spring MVC应用。另一方面,Rails几乎是按照和EJB2一样的方式设计的(在我发现这点时,怎一个“震惊”二字了得!)。也就是说,你在扩展 ActiveController和ActiveRecord等框架对象时,你也就被绑定在了这套框架上。

在Rails里面根本就不存在领域模型的说法,Rails的模型就是数据库表。这当然是一件好事了,但在企业内部,同一个领域模型可能会在许多不同的应用中服用,比如说桌面应用和Web应用。在Java里,这实际上是非常成熟完善的,通过把类对象及相应映射文件打包成一个JAR文件即可。

Q: 用Grails开发的Web应用如何进行部署?
A: 执行‘grails war’将Web应用打成war包,然后就可以将应用部署到任何符合J2EE规范的Web服务器上了。


To be continued...

附:朝花夕拾——Groovy & Grails
posted on 2007-04-28 16:21 山风小子 阅读(2271) 评论(5)  编辑  收藏 所属分类: Groovy & Grails