【问题标题】:Java: Design with Singletons and genericsJava:使用单例和泛型进行设计
【发布时间】:2009-03-02 20:16:06
【问题描述】:

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

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

然后使用一些实用程序findAll( Collection&lt;T&gt; coll, Predicate&lt;T&gt; pred) 方法将谓词应用于 Cats 集合,并仅获取黑色的,等等。

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

【问题讨论】:

    标签: java singleton generics predicate


    【解决方案1】:

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

    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
    }
    

    如果谓词有参数,可以使用静态工厂方法。

    编辑:正如 cmets 中所指出的,根据使用模式,它可能会导致更清晰的代码来收集单独的类中的谓词常量(和/或工厂方法),或者仅适用于 Cat 的那些,或全部。这主要取决于他们的数量,多少额外的组织是有帮助的。

    【讨论】:

    • 我可能会在 Cat 本身中放入一个“Cats”类。
    【解决方案2】:

    这样的事情应该可以工作:

    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);
        }
    }
    

    【讨论】:

    • getBlackCatPredicate 谓词或 BlackCatPredicate 的返回类型?哪个更好看?
    • 糟糕...我会返回一个谓词
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-20
        • 1970-01-01
        • 2011-12-20
        • 2014-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多