2009-04-17 39 views
0

隨着新Groovy的...最佳groovy關閉習語取代java內部類?

我試圖取代了事件偵聽器,過濾器等java的成語

在常規工作我的代碼如下:

def find() { 
    ODB odb = ODBFactory.open(files.nodupes); // data nucleus object database 
    Objects<Prospect> src = odb.getObjects(new QProspect()); 

    src.each { println it }; 

    odb.close(); 

} 

class QProspect extends SimpleNativeQuery { 
    public boolean match(Prospect p) { 
     if (p.url) { 
      return p.url.endsWith(".biz"); 
     } 
     return false; 
    } 
} 

現在,這遠離我在java中的習慣,Query接口的實現恰好在odb.getObjects()方法中完成。如果我在那裏編寫的「java」我可能會做一些像下面,但它不工作:

Objects<Prospect> src = odb.getObjects({ 
     boolean match(p) { 
      if (p.url) { 
      return p.url.endsWith(".biz"); 
     } 
      return false; 
     } 
    } as SimpleNativeQuery); 

或者更好,我想它是這樣的:

Objects<Prospect> src = odb.getObjects( 
     { it.url.endsWith(".biz") } as SimpleNativeQuery 
); 

然而,groovy是否會將「匹配」方法與外部腳本環境相關聯並使我失敗。

我發現groovy ...無論如何,所以我會堅持學習更多關於它。謝謝。


我應該問的是我們如何做groovy中的「匿名」類。這裏是java的成語:

void defReadAFile() { 
    File[] files = new File(".").listFiles(new FileFilter() { 
     public boolean accept(File file) { 
      return file.getPath().endsWith(".biz"); 
     } 
    }); 
} 

可以groovy簡潔,沒有額外的類聲明?

回答

1

我認爲如果你已經將問題抽象出來以便它不依賴於Neodatis數據庫接口 - 這會讓我陷入循環,因爲我從來沒有用過它,這會幫助你得到答案。我在下面寫的關於它的基礎是非常粗略的分析。

對於這個問題,我從來沒有使用Groovy,雖然我喜歡我所見過的。但看到沒有其他人已經回答了,你堅持我:-)

我認爲這個問題(或至少部分)可能是你期望過多的Neodatis的SimpleNativeQuery類。它看起來並不像它甚至在將對象添加到返回的集合之前嘗試過濾這些對象。我想相反,你想使用org.neodatis.odb.impl.core.query.criteria.CriteriaQuery。 (注意包裝路徑中的「impl」這讓我有點緊張,因爲我不確定這個類是否被調用者使用,但是我沒有看到Neodatis中的其他類允許指定查詢條件。)

但是,我並不是直接使用CriteriaQuery,而是想將它包裝在Groovy類中,以便可以在閉包中使用它。所以,我認爲Groovy版本的代碼與閉包可能看起來像這樣:

// Create a class that wraps CriteriaQuery and allows you 
// to pass closures. This is wordy too, but at least it's 
// reusable. 

import org.neodatis.odb.impl.core.query.criteria; 

class GroovyCriteriaQuery extends CriteriaQuery { 
    private final c; 

    QProspect(theClosure) { 
     // I prefer to check for null here, instead of in match() 
     if (theClosure == null) { 
      throw new InvalidArgumentException("theClosure can't be null!"); 
     } 
     c = theClosure; 
    } 

    public boolean match(AbstractObjectInfo aoi){ 
     //!! I'm assuming here that 'aoi' can be used as the actual 
     //!! object instance (or at least as proxy for it.) 
     //!! (You may have to extract the actual object from aoi before calling c.) 
     return c(aoi); 
    } 
} 

// Now use the query class in some random code. 

Objects<Prospect> src = odb.getObjects( 
     new GroovyCriteriaQuery(
      { it.url.endsWith(".biz") } 
    ) 
) 

我希望這有助於!

+0

你是正確的,問題是微弱的。你提供的東西實際上是有用的,我將使用它,但是我應該問的是我們如何在groovy中做「匿名」類。這裏的java成語: void defReadAFile(){ File [] files = new File(「。」)。listFiles(new FileFilter(){ public boolean accept(File file){ return file.getPath()。 endsWith(「。biz」); } }); } 可以groovy簡潔,沒有額外的類聲明? – Florin 2009-04-17 13:34:22

1

我相信你真正的問題是「在調用不使用閉包的Java API時,我可以使用閉包而不是匿名類」。答案是肯定的「是」。這:

Objects<Prospect> src = odb.getObjects( 
     { it.url.endsWith(".biz") } as SimpleNativeQuery 
); 

應該工作。你寫道:「然而,將」匹配「方法與外部腳本上下文相關聯並使我失敗的原因是什麼?」。它究竟如何失敗?在我看來,如果你有一個簡單的技術問題來獲得既是「常規方式」又正是你想要工作的解決方案。

0

是的,謝謝你們,謝謝。

我還發現爲什麼SimpleNativeQuery不起作用(根據Dan Breslau)。

我試了下面,它奇妙地工作。所以這個成語確實按預期工作。

new File("c:\\temp").listFiles({ it.path.endsWith(".html") } as FileFilter); 

由於neodatis接口,下一個不起作用。界面確實不是強制執行match()方法!僅提及了它的文件中但它是不存在的類文件:

public class SimpleNativeQuery extends AbstactQuery{ 

} 

Objects<Prospect> src = odb.getObjects( 
    { it.url.endsWith(".biz") } as SimpleNativeQuery 
); 

在上述中,作爲SimpleNativeQuery不具有匹配()方法,它使得不可能的常規編譯器以確定哪些SimpleNativeQuery中的方法應該將閉包附加到;它然後默認爲外部groovy腳本。

這是我的第三天groovy,我很喜歡它。

這兩本書都是偉大的: - Groovy的食譜(斯科特·戴維斯) - 編程的Groovy(Venkat廉)