Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top