將Gremlin Groovy轉換爲Gremlin Java應該不是很困難。我總是會反對這樣做,你會:
- 大大增加你的代碼的大小
- 使您的代碼的可讀性
- 使您的代碼更難維護
如果你工作在一家不會聽到外部編程語言的「Java商店」中,我認爲在這些問題上銷售人員並不難,只需要少量Gremlin在groovy和java中的差異示例(易於閱讀一個內容與幾百行代碼相比)。此外,Groovy可以放入一個標準的Maven項目中,或者與同一模塊中的java一起使用,也可以放入其他項目所依賴的單獨獨立模塊中。在大多數情況下,我更喜歡後者,因爲您將Groovy分離在一個包中,並且可以跨多個用例(例如應用程序,gremlin控制檯中的附加庫等)重用爲DSL。
也就是說,如果您仍然必須使用Java,我仍然會從編寫Groovy開始。使用Gremlin控制檯並正確使用遍歷算法。這聽起來好像您的兩個用例涉及循環,所以我們只能說,你的遍歷看起來像:
g.v(1).out.loop(1){true}{it.object.someProperty=="emitIfThis"}
因此,這將遍歷鏈從頂點「1」,直到我用盡鏈,標誌着通過第一個閉包中的「true」,然後在第二個閉包中發出與我的標準相匹配的任何頂點。一旦你已經定義並測試了Gremlin的大部分內容,就可以轉換爲Java了。
正如你知道,有GremlinPipeline
開始,第一部分是很容易轉換用途:
new GremlinPipeline(g.getVertex(1)).out()
正如你所看到的,Groovy的方法將幾乎映射到Java還算乾淨,直到你到達您需要關閉的一個點,並且loop
是需要一個的步驟之一。要使用Gremlin Java,您可能會發現查看javadoc的GremlinPipeline
很有用。
我使用了三個參數版本loop
- 標記爲「已棄用」(但對我們來說沒關係) - 您可以看到它here。第一個理由很簡單 - 一個整數,所以翻譯的第一部分是:
new GremlinPipeline(g.getVertex(1)).out().loop(1, closure, closure)
我已經離開的地方持有人,我們有其他兩個關閉。如果你以這種方式來看待它,它與我們的Groovy版本沒有什麼不同 - 語法稍有不同。
在Java 8之前,沒有內置到java語言中的閉包的概念。請注意,在TinkerPop3中,Gremlin發生了巨大變化,以利用我們現在擁有lambda的事實。但是當你在TinkerPop2中時,你必須使用PipeFunction
中的內置函數,它基本上代表了我們常規閉包的類型化版本。該PipeFunction
兩個參數循環是:
PipeFunction<LoopPipe.LoopBundle<E>,Boolean>
所以基本上,這是得到一個LoopPipe.LoopBundle
因爲其中包含有關環路的元數據,並期望你返回一個布爾值對象的功能。如果你理解了這個概念,那麼所有的Gremlin Java都會爲你打開,因爲在任何你看到常規關閉的地方,你都知道它下面只是某種形式的PipeFunction
,而且現在你可以閱讀PipeFunction
的期望從javadocs,這些語言翻譯應該很簡單。
第一封閉翻譯,我們要做的是,因爲它來的那麼簡單 - 我們只需要我們PipeFunction
返回true
:
new GremlinPipeline(g.getVertex(1)).out().loop(1,
new PipeFunction<LoopPipe.LoopBundle<Vertex>,Boolean>() {
public Boolean compute(LoopPipe.LoopBundle<Vertex> argument) {
return true;
}
}, closure)
因此,對於第二個參數loop
我們必須建立一個新的PipeFunction
,其中有一種方法叫做compute
。從該方法我們返回true
。我們處理第二個PipeFunction
參數控制頂點發出:
new GremlinPipeline(g.getVertex(1)).out().loop(1,
new PipeFunction<LoopPipe.LoopBundle<Vertex>,Boolean>() {
public Boolean compute(LoopPipe.LoopBundle<Vertex> argument) {
return true;
}
},
new PipeFunction<LoopPipe.LoopBundle<Vertex>,Boolean>() {
public Boolean compute(LoopPipe.LoopBundle<Vertex> argument) {
return argument.getObject().getProperty("someProperty").equals("emitIfThis");
}
})
還有矗立的轉換。由於這是一個很長的帖子,讓我們把原來的常規接近上述兩者的差異是顯而易見的:
g.v(1).out.loop(1){true}{it.object.someProperty=="emitIfThis"}
我們從上面的代碼一行來到近一個十幾對什麼是否則很簡單的遍歷。 Gremlin Java在TinkerPop3中得到了自己的貢獻,給出了lambda表達式,並對語言本身進行了重大改進,但這些先前版本生成的Java代碼實際上不值得在Groovy使事情變得非常整齊時生成或維護。
你所描述的是'方法鏈'。如果您想要API鏈接,請參閱規範(https://github.com/orubel/grails-api-toolkit-docs/wiki/API-Chaining)或其上的springone演示文稿(http://www.slideshare.net/bobdobbes/api-abstraction-api-chaining) – Orubel 2015-04-23 22:29:08