views:

1166

answers:

4

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?

+1  A: 

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.

+2  A: 

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);
    }
}
TofuBeer
Return type on getBlackCatPredicate Predicate, or BlackCatPredicate? Which looks better?
extraneon
Oops... I would return a Predicate<Cat>.
TofuBeer
+9  A: 

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.

Michael Borgwardt
I'd probably put in a class "Cats" not in Cat itself.
Tom Hawtin - tackline
A: 

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.

Dan Berindei