2009-03-02 33 views
4

我正在使用一個名爲Predicate的接口,它用於篩選Collections。例如,我可以定義Java:使用單例和泛型進行設計

public class BlackCatPredicate implements Predicate<Cat> { 
    public boolean evaluate(Cat c) { 
     return c.isBlack(); 
    } 
} 

,然後使用一些工具findAll(Collection<T> coll, Predicate<T> pred)方法謂詞適用於貓的集合,並得到只是黑色的,等

我的問題是這樣的:我在我的代碼中找到黑貓,所以沒有必要一遍又一遍地實例化BlackCatPredicate。它應該只有一個實例。 (單身?)但是,在編寫許多謂詞的過程中,我不想將每個謂詞都實現爲單例。那麼 - 這裏的設計是什麼?

回答

12

我會用匿名類常量,並把它與類它所操作:

public class Cat{ 
    public static final Predicate<Cat> BLACK_PREDICATE = new Predicate<Cat>(){ 
      public boolean evaluate(Cat c) { 
       return c.isBlack(); 
      } 
     }; 

    // Rest of the Cat class goes here 
} 

如果斷言有參數,你可以使用靜態工廠方法。正如在註釋中指出的那樣,根據使用模式的不同,它可能導致更清晰的代碼來收集單獨類中的謂詞常量(和/或工廠方法),或者只有那些用於Cat ,或者全部。這主要取決於他們的人數,多少額外的組織是有幫助的。

1

您可以創建一個通用工廠,它將任何謂詞作爲類型arg - 然後爲給定的謂詞類型生成單個實例。

另一種更一般的方法是開始使用依賴注入庫 - 並通過它來完成所有的對象創建。通常情況下,您可以將類型切換爲單例,如果適用,幾乎沒有變化。

3

像這樣的東西應該工作:

class Predicates 
{ 
    private static class BlackCatPredicate implements Predicate<Cat> 
    { 
     public boolean evaluate(final Cat c) 
     { 
      return c.isBlack(); 
     } 
    } 

    private static final BlackCatPredicate = new BlackCatPredicate(); 


    public static Predicate<Cat> getBlackCatPredicate() 
    { 
     return (blackCatPredicate); 
    } 
} 
+0

getBlackCatPredicate謂詞或BlackCatPredicate的返回類型?哪個更好看? – extraneon 2009-03-02 20:40:10

+0

糟糕...我會返回一個謂詞。 – TofuBeer 2009-03-02 20:44:35

0

我根本不用擔心會創建額外的BlackCatPredicate實例。

如果您不喜歡在整個地方編寫new BlackCatPredicate(),您當然可以添加靜態工廠方法,以便您可以改爲編寫BlackCatPredicate.getInstance()。另一種選擇是創建一個單獨的課程,以便您可以編寫CatPredicates.getBlackCatPredicateInstance()

但是,這僅僅是從客戶端代碼中抽象出謂詞的創建,它與實際的對象創建無關。處理短暫對象是JVM最擅長的事情之一,因此創建一堆額外的實例並立即丟棄它們不會影響您的性能。