Design pattern中builder pattern算蠻常見的吧!之前自學Java FX時,有所謂的tabelviewbuilder, treeviewbuilder及menubuilder等,Java FX中builder object基本上就是不斷的呼叫方法然後回傳原builder物件,最後呼叫build()完成物件建置,Groovy裡面也有所謂SwingBuilder但就不提了,畢竟FX都出來了.....所以Groovy這邊要介紹的是如何builder pattern來builder up 巢狀的文件架構如node, XML或是HTML
一般而言,Groovy裡的builder方法都是xxxbuilder,方法就是node的tag或是名稱,tag的值以Map或是key/value表示,closure裡就是下一層文件
以NodeBuilder為例(建立object tree結構)
def brandList=['ASUS', 'GigaByte', 'MSI', 'ASRock','Elite']
println "Top $brandList.size Motherboard Brands"
def builder =new NodeBuilder() //new一個NodeBuilder物件
def pcBrands=builder.brands{ // brands就是root node
for(i in 1..brandList.size){
Brand(No:i){ // Brand是第二層
Manufacturer(brandList[i-1]) //Brand的下一層
} //每一層都用Closure包起來代表node
}
}
def writer =new StringWriter()
pcBrands.print(new PrintWriter(writer))
def result = writer.toString()
print result
執行結果
Top 5 Motherboard Brands
brands() {
Brand(No:1) {
Manufacturer('ASUS')
}
Brand(No:2) {
Manufacturer('GigaByte')
}
Brand(No:3) {
Manufacturer('MSI')
}
Brand(No:4) {
Manufacturer('ASRock')
}
Brand(No:5) {
Manufacturer('Elite')
}
}
以產生XML為例,使用groovy.xml.MarkupBuilder,跟nodeBuilder不同的是只是方法名稱不同,其餘大同小異
def writer =new StringWriter()
def brandList=['ASUS', 'GigaByte', 'MSI', 'ASRock','Elite']
def builder =new groovy.xml.MarkupBuilder(writer)
//跟nodeBuilder差別只在名稱不同(MarkupBuilder()
def pcBrands=builder.Brands(Topic:"Top $brandList.size Motherboard Brands"){
// brands就是root node, 另外對於XML來說(tag:property)
for(i in 1..brandList.size){
Brand(No:i){ // Brand是第二層
Manufacturer(brandList[i-1]) //Brand的下一層
} //每一層都用Closure包起來代表node
}
}
def result = writer.toString()
print result
執行結果:
<Brands Topic='Top 5 Motherboard Brands'>
<Brand No='1'>
<Manufacturer>ASUS</Manufacturer>
</Brand>
<Brand No='2'>
<Manufacturer>GigaByte</Manufacturer>
</Brand>
<Brand No='3'>
<Manufacturer>MSI</Manufacturer>
</Brand>
<Brand No='4'>
<Manufacturer>ASRock</Manufacturer>
</Brand>
<Brand No='5'>
<Manufacturer>Elite</Manufacturer>
</Brand>
</Brands>