作者:江南白衣
前篇:〈在Spring+Hibernate架構下,用動態語言寫業務類〉講述在Spring+Hibernate的架構下,因為動態語言所帶來的利益,把一部分業務類改用Groovy編寫並編譯成Java Class檔案。
而且,因為Groovy的強大與簡便,加上與Java親密無間的關係,一些架構類也可以逐漸考慮用Groovy編寫。
1.雖然多是星零的好處,但忽然間一整噸好處擺在面前還是很讓人感動的。
除了動態語言和閉包、MOP,Groovy其他的特性多是對J2SE中設計不合理的地方逐一進行修正,集合、IO、字串操作......雖然多是星零的好處,但忽然間以整噸好處擺在面前還是挺讓人感動的。
同時,Groovy完全相容Java文法,但又提供糖糖選擇的方式感覺很貼心。(Groovy唯一不支援的java文法就是Inner Class的定義和函數定義裡的"throws Exception" , 私生子的好處啊)
隱約覺得因為動態語言的無類型,還有閉包這樣帶著Lisp式FP的印記,加上MOP這樣的機制,可能會激發更大的變革發生。
1.動態類型
動態類型在Framework型項目中非常重要,多少設計模式嘔心瀝血,就是為了和這個類型搏鬥。
而且,如果你是把代碼編譯成java Class,健壯性不會減低太多。
2.閉包
fp的基礎,沒有閉包的C++用函數指標,java用匿名內部類,都比他差遠了。
詳看Matin Flower <閉包>文章的中文版 ,在一段檔案操作的Script中試演了一下,果然使代碼簡潔了好些。
3. MOP
Groovy的Team Leader-- Guillaume Laforge最喜歡的一樣特性,groovy 嵌入式XML文法的基礎,對屬性和方法訪問的intercept 機制。詳看另一篇blog。
又比如,在MOP下,DAO那一堆findByName,findByTitle不用再逐一實現了,實現一個findBy即可攔截其他子虛烏有的findByXXX。
4.強大的String類
a.可以直接在String中嵌入EL, "orderBy ${sortColumn}",省了好多"和+號。
b.hql 可以多行,不用寫N多"和+ , 寫sql時特別方便。
c.簡單整合了Regex
If ("name"==~ "na.*")
{println "match!"}
5. 集合與迴圈的文法
for (car in cars) { println car }
for ( e in map ) { x += e.value}
或者
car.each{print it}
集合也可以直接定義了,如
def myList = ["Rod", 3, Date()]
def myMap = ["Neeta":31, "Eric":34]
6.為JDK的基礎類擴充了一系列Helper方法
//原來StringTokenizer類的功能被簡單的整合到String類中了
names.tokenize(",").each{......}
其他基礎類的擴充見Groovy-JDK
7.簡化的Bean定義與賦值
//自動產生Getter和Setter
class Customer
{
Integer id;
String name;
}
//簡便的對象賦值
customer = new Customer(id:1, name:"calvin");
customer2 = new CUstomer(id:2);
重新使對象的屬性public,對java濫用getter,setter是一種修正。
8. Object內建的反射文法
customer.getAt("name") //得到屬性name,
customer.invokeMethod("someFunction") //調用方法someFunction
從此不再需要Apache BeanUtils。
9.GPath--內建的XML文法,和Fremarker類似。
傳說中JDK7.0的功能 jdom和Dom4j可以安息了
book = new XmlSlurper().parseText("<book writer='calvin'><title>D</title></book>")
println book.title;
println book[@writer];
println book.children().size();
10.運算子多載
//向數組添加對象
params << customer.getAt(it);
還有如C++的向String,InputStream添加對象.
還有集合類相加,如list1+list2
11.簡化了IO操作
12.省略了每行末尾的分號
既然每行都要的,何必多此一舉呢?
另外return語句也可以省略,不過我還是習慣寫:)
2.Groovy版CustomerDAO的樣本:
package com.itorgan.myappfuse.dao;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class CustomerDAOGroovy extends HibernateDaoSupport
{
public insert(customer)
{
getHibernateTemplate().save(customer)
}
public List getAllValid(sortColumn)
{
def hql = """from Customer customer
where customer.status='valid'
order by ${sortColumn}"""
def query = getSession().createQuery(hql)
return query.list()
}
public boolean isUnique(customer, uniqueColumnNames)
{
def params = []
def hql = "select count(*) from Customer customer where "
def first = true
uniqueColumnNames.tokenize(",").each
{
if (!first)
hql += " or "
else
first = false
hql+="customer.${it}=?"
params << customer.getAt(it)
}
def result = getHibernateTemplate().find(hql,params.toArray())
return ( result.get(0) == 0)
}
}