Grails最佳實踐
> 轉(zhuǎn)自infoq
> 這里的建議是專門針對Grails 2.0的,盡管其中的大多數(shù)是多個版本都適用的。
控制器
---
1. 不允許控制器充當(dāng)其他角色??刂破鞯慕巧褪墙邮軅魅氲恼埱?、檢查權(quán)限等、問Domain或Service要結(jié)果、將結(jié)果用所需的格式(如 HTML、JSON或XML)返回給請求者。要讓控制器保持苗條。別讓它執(zhí)行業(yè)務(wù)邏輯、查詢或更新。
2. 如果一個控制器代表了一個單一的Domain Class,使用標(biāo)準(zhǔn)的命名公式`Controller`為控制器命名。
避免代碼重復(fù) - 通用的操作應(yīng)該提取成閉包或者方法。
3. 將復(fù)雜的數(shù)據(jù)綁定劃分為一個Command對象。可以讓Command對象豐富些(就像富Domain Class)。創(chuàng)建一個有層次的Comand對象在某些情況下也是有用的。
服務(wù)
---
1. 服務(wù)是復(fù)雜業(yè)務(wù)邏輯或粗粒度代碼的最佳候選。如果有必要,服務(wù)API可以很容易的暴露成一個RESTful/SOAP Web服務(wù)。
2. 服務(wù)缺省為事務(wù)性的,但是如果服務(wù)的方法沒有更新持久化存儲,可以設(shè)置為非事務(wù)性的。
視圖
---
1. 盡量保持視圖的簡單 - 在這一層,抵制放置業(yè)務(wù)或數(shù)據(jù)庫邏輯的誘惑。
2. 使用布局(Layout)保證應(yīng)用的所有頁面或者頁面子集有一個統(tǒng)一的外觀。
3. 讓你的視圖保持DRY(別重復(fù)你自己)。將重復(fù)內(nèi)容放在模板中。
4. 對通用的UI元素,使用自定義的TagLib。
Domain
---
1. 最好將模型Domain特定的邏輯放在自己的Domain中。符合“單個Domain加少數(shù)依賴”的任何代碼都應(yīng)該被放到自己的Domain Class里。但僅限于那個Domain相關(guān)的邏輯,處理多個Domain的更復(fù)雜業(yè)務(wù)邏輯屬于服務(wù)。
2. 為了重用公共局部查詢或者分解復(fù)雜邏輯,使用命名查詢,并根據(jù)需要把它們組合起來,就像常見的jQuery函數(shù)鏈?zhǔn)秸{(diào)用一般。
3. 別在Domain文件夾下混入其他的通用工具類或數(shù)值對象,它們應(yīng)該呆在`src/groovy`目錄下。如果這些類需要支持驗證,可以用`@Validateable`對其進行注解。
4. 使用有意義的構(gòu)造函數(shù)實例化Domain對象,避免任何不必要的狀態(tài)并只構(gòu)造有效的對象。
TagLib
---
1. 保持各標(biāo)簽的精簡。一個標(biāo)簽可以調(diào)用其他標(biāo)簽,如果需要,一個標(biāo)簽可以分解成可重用的子標(biāo)簽。
2. TagLib可以被認為是MVC架構(gòu)中視圖層的一部分,但深入Domain內(nèi)部組裝或者格式化數(shù)據(jù)顯示也是可以接受的。依舊遵循(即不是完全禁止)最小化與Domain直接交互的原則。
3. 它應(yīng)該包含更多的邏輯,而非渲染;雖然有少許渲染還是不錯滴。
4. 為了更好的組織結(jié)構(gòu),可以使用多個自定義的TagLib。
測試
---
1. 較之集成測試,更偏愛單元測試。不僅因為它們運行/調(diào)試更快,而且能更好地強制松耦合。服務(wù)的測試比較特殊,使用集成測試會更好些。
2. 在單元測試中,使用`save(validate:false)`保存沒有完全裝入的對象。
Config.groovy
---
1. 將所有環(huán)境特定的配置放在Config.groovy,如serverURL、每個環(huán)境下各異的常量等等。
2. 將個人配置內(nèi)容(比如本地數(shù)據(jù)庫用戶名或密碼等等)放在`Config.groovy`文件中,并加入到版本控制系統(tǒng)的忽略列表中,以便每個團隊成員能夠根據(jù)自己的特定需求覆蓋配置。
3. 雖有些爭議,但我們建議設(shè)置`grails.gorm.failOnError = true`,這樣只要保存對象時Domain校驗失敗就會拋出一個異常。由此,你就不再需要檢查是否保存成功。
4. 在Grails 2.0中,缺省`grails.hibernate.cache.queries = true`,毋須添加`cache:true`就會自動緩存查詢。把它設(shè)為`false`,只在真正有助于提高性能時才緩存。
雜項
---
1. 理解并堅持Grails的慣例,因為Grails就是慣例驅(qū)動的。使用這些慣例會讓你的開發(fā)者生活更輕松。
2. 在不同的包中組織Grails的制品,別用`com.businessname.appname.domain`和`com.businessname.appname.controller`。否則在FooController中,我們將最終需要導(dǎo)入Foo類。 既然Grails已經(jīng)將這些制品放在了不同目錄下,它們就不需要再被分離了。
3. fixtures插件可以在開發(fā)時用來初始化數(shù)據(jù)。
4. 將你應(yīng)用的可重用部分開發(fā)成Grails插件。這些插件可以獨立測試,還可以消除你的應(yīng)用的復(fù)雜性。如果你認為其他人會需要這些插件,你還可以把插件發(fā)布到公共的插件庫中。
5. 更新腳手架模板以生成你的項目特定的視圖和控制器。
6. 青睞動態(tài)腳手架,而不使用靜態(tài)腳手架,除非前者不滿足你的需求。例如,如果僅需要修改“save” action,你可以僅重載“save” action,在運行時動態(tài)生成其他腳手架代碼。
7. 總在DataSource.groovy中設(shè)置數(shù)據(jù)庫的重連屬性是很好的習(xí)慣。參考代碼:
dataSource {
properties {
maxActive = 30
minIdle = 1
numTestsPerEvictionRun = 3
testOnBorrow = true
testWhileIdle = true
testOnReturn = true
validationQuery = "SELECT 1"
minEvictableIdleTimeMillis = (1000 * 60 * 5)
timeBetweenEvictionRunsMillis = (1000 * 60 * 5)
}
}
8. 總保證自己應(yīng)用中含有一個外部的配置文件(那怕是一個空文件),這樣,在產(chǎn)品環(huán)境中需要覆蓋任何配置時都無需重新生成一個新的WAR文件。
9. 如果你想對你所使用的插件進行小的改動,例如改變quartz監(jiān)控插件的list.gsp以符合應(yīng)用主題,那么不要因為這點小改動而把插件源代碼包含到項目里,你可以遵循相同的目錄結(jié)構(gòu)或包重載這些文件。原因是應(yīng)用的優(yōu)先級比插件高。
10. Domain中所有自定義的校驗可以放在一個共享的校驗文件中,以便其他Domain重用這些約束。參考代碼:
class Validators {
static final confirmPasswordValidator = { value, command ->
if (command.password != command.confirmPassword) {
return 'command.confirmPassword.error.mismatch'
}
}
static def requiresAtleastOne = {val, obj->
if(!val?.size()){
return "default.requires.atleast.one"
}
}
}
class MyDomain {
...
static constraints = {
items(validator: requiresAtleastOne)
}
}
11. 在應(yīng)用中安裝任何的插件,最好在`BuildConfig.groovy`文件中聲明,而不是使用`install-plugin`命令。
浙公網(wǎng)安備 33010602011771號