我正在使用一个名为Predicate的接口,用于筛选集合。例如,我可以定义
public class BlackCatPredicate implements Predicate<Cat> {
public boolean evaluate( Cat c ) {
return c.isBlack();
}
}
然后使用一些实用程序findAll( Collection<T> coll, Predicate<T> pred)
方法将谓词应用于Cats集合,并获得黑色等等。
我的问题是:我在我的代码中找到黑猫,所以没有必要一遍又一遍地实例化BlackCatPredicate。它应该只有一个实例。 (单身?)但是,在编写许多谓词的过程中,我不想将每个谓词都作为单例来实现。那么 - 这里的设计是什么?
答案 0 :(得分: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
}
如果谓词有参数,则可以使用静态工厂方法。
编辑:正如评论中指出的那样,根据使用模式,它可能会导致更清晰的代码在单独的类中收集谓词常量(和/或工厂方法),或者只有那些猫,或所有。这主要取决于他们的数量,有多少额外的组织是有帮助的。
答案 1 :(得分: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);
}
}
答案 2 :(得分:1)
您可以创建一个将任何谓词作为类型arg的泛型工厂 - 然后为给定的谓词类型生成单个实例。
另一种更通用的方法是开始使用依赖注入库 - 并通过它完成所有对象创建。通常,您可以将类型切换为单例,如果适用,只需稍加更改。
答案 3 :(得分:0)
我根本不担心创建额外的BlackCatPredicate
个实例。
如果您不喜欢在整个地方编写new BlackCatPredicate()
,您当然可以添加静态工厂方法,以便您可以编写BlackCatPredicate.getInstance()
。另一种选择是创建一个单独的类,以便您可以编写CatPredicates.getBlackCatPredicateInstance()
。
但是,这仅用于从客户端代码中抽象出谓词的创建,它与实际的对象创建无关。处理短期对象是JVM最擅长的事情之一,因此创建一堆额外的BlackCatPredicate
实例并立即丢弃它们不会影响您的性能。