Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Design with Singletons and generics

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?

like image 998
Jake Avatar asked Dec 05 '22 06:12

Jake


2 Answers

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.

like image 164
Michael Borgwardt Avatar answered Dec 19 '22 04:12

Michael Borgwardt


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);
    }
}
like image 42
TofuBeer Avatar answered Dec 19 '22 02:12

TofuBeer