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

发布于 2024-07-14 05:46:05 字数 452 浏览 9 评论 0原文

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

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

然后使用一些实用程序 findAll( Collectioncoll, Predicatepred) 方法将谓词应用于猫集合,并只获取黑色猫, 我的问题是这样

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

I am using an interface called Predicate which is used for sifting through Collections. For example, I can define

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

and then use some utility findAll( Collection<T> coll, Predicate<T> pred) method to apply the predicate to a collection of Cats, and get just the black ones, etc.

My question is this: I'm finding black cats all over my code, so there is no need to keep instantiating the BlackCatPredicate over and over again. It should just have one instance. (A singleton?) But then, over the course of writing many predicates, I don't want to have to implement each one as a singleton. So -- what is the proper design here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

往日情怀 2024-07-21 05:46:05

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

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
}

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

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

I'd use an anonymous class constant and put it with the class it operates on:

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
}

If the predicate has parameters, you can use a static factory method.

Edit: As was pointed out in the comments, depending on the usage patterns, it may result in clearer code to collect the predicate constants (and/or factory methods) in a separate class, either only those for Cat, or all of them. It depends mainly on their number, how much additional organization is helpful.

许你一世情深 2024-07-21 05:46:05

像这样的东西应该有效:

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

Something like this should work:

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);
    }
}
呆橘 2024-07-21 05:46:05

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

另一种更通用的方法是开始使用依赖注入库 - 并通过它来创建所有对象。 通常,如果合适,您可以将类型切换为单例,只需进行很少的更改。

You could make a generic factory that takes any predicate as a type arg - and then generates a single instance for a given predicate type.

Another more general approach would be to start using a dependency injection library - and do all of your object creation through it. Typically you can switch a type to be a singleton, if appropriate, with little change.

请叫√我孤独 2024-07-21 05:46:05

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

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

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

I wouldn't worry about creating extra BlackCatPredicate instances at all.

If you don't like writing new BlackCatPredicate() all over the place you can certainly add a static factory method so you can write BlackCatPredicate.getInstance() instead. Yet another option would be to create a separate class so you can write CatPredicates.getBlackCatPredicateInstance().

However this is only for abstracting the creation of the predicate from the client code, it has nothing to do with actual object creation. Dealing with short-lived objects is one of the things the JVM does best, so creating a bunch of extra BlackCatPredicate instances and discarding them immediately won't affect your performance in the slightest.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文