Java:使用单例和泛型进行设计

Java:使用单例和泛型进行设计,java,singleton,generics,predicate,Java,Singleton,Generics,Predicate,我正在使用一个名为谓词的接口,用于筛选集合。例如,我可以定义 public class BlackCatPredicate implements Predicate<Cat> { public boolean evaluate( Cat c ) { return c.isBlack(); } } 公共类BlackCatPredicate实现谓词{ 公共布尔运算(c类){ 返回c.isBlack(); } } 然后使用一些实用工具findAll(Collect

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

public class BlackCatPredicate implements Predicate<Cat> {
  public boolean evaluate( Cat c ) {
       return c.isBlack();
  }
}
公共类BlackCatPredicate实现谓词{
公共布尔运算(c类){
返回c.isBlack();
}
}
然后使用一些实用工具
findAll(Collection coll,Predicate pred)
方法将谓词应用于Cats集合,并仅获取黑色的集合,等等


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

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


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

类似的操作应该可以:

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);
    }
}
类谓词
{
私有静态类BlackCatPredicate实现谓词
{
公共布尔运算(最终c类)
{
返回c.isBlack();
}
}
私有静态final BlackCatPredicate=new BlackCatPredicate();
公共静态谓词getBlackCatPredicate()
{
返回(blackCatPredicate);
}
}

我会使用一个匿名类常量,并将其与它所操作的类放在一起:

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{
公共静态最终谓词BLACK_Predicate=new Predicate(){
公共布尔运算(c类){
返回c.isBlack();
}
};
//猫课的其余部分都在这里
}
如果谓词具有参数,则可以使用静态工厂方法


Edit:正如注释中指出的,根据使用模式的不同,它可能会产生更清晰的代码,以便在单独的类中收集谓词常量(和/或工厂方法),或者只收集Cat的谓词常量,或者收集所有谓词常量。这主要取决于它们的数量,以及有多少额外的组织是有用的。

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

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


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

我可能会将类“Cats”放在Cat中,而不是放在Cat本身中。getBlackCatPredicate或BlackCatPredicate上的返回类型?哪一个看起来更好?哦。。。我将返回一个谓词。