4

我正在使用一个名为 Predicate 的接口,用于筛选集合。例如,我可以定义

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

然后使用一些实用findAll( Collection<T> coll, Predicate<T> pred)方法将谓词应用于 Cats 的集合,并只获取黑色的,等等。

我的问题是:我的代码中到处都是黑猫,所以没有必要一遍又一遍地实例化 BlackCatPredicate。它应该只有一个实例。(单例?)但是,在编写许多谓词的过程中,我不想将每个谓词都实现为单例。那么——这里的正确设计是什么?

4

4 回答 4

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,或者全部。这主要取决于他们的数量,多少额外的组织是有帮助的。

于 2009-03-02T20:23:06.367 回答
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);
    }
}
于 2009-03-02T20:21:04.577 回答
1

您可以创建一个将任何谓词作为类型 arg 的通用工厂 - 然后为给定的谓词类型生成单个实例。

另一种更通用的方法是开始使用依赖注入库 - 并通过它创建所有对象。通常,您可以在适当的情况下将类型切换为单例,而无需进行少量更改。

于 2009-03-02T20:18:10.577 回答
0

我根本不用担心创建额外的BlackCatPredicate实例。

如果你不喜欢到处写new BlackCatPredicate(),你当然可以添加一个静态工厂方法,这样你就可以写BlackCatPredicate.getInstance()了。另一种选择是创建一个单独的类,以便您可以编写CatPredicates.getBlackCatPredicateInstance().

然而,这只是为了从客户端代码中抽象出谓词的创建,它与实际的对象创建无关。处理短期对象是 JVM 最擅长的事情之一,因此创建一堆额外的BlackCatPredicate实例并立即丢弃它们不会丝毫影响您的性能。

于 2009-03-02T20:46:16.937 回答