Question

J'utilise une interface appelée Predicate, utilisée pour parcourir les collections. Par exemple, je peux définir

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

puis utilisez une méthode utilitaire findAll( Collection<T> coll, Predicate<T> pred) pour appliquer le prédicat à une collection de chats et obtenir uniquement les noirs, etc.

Ma question est la suivante: je trouve des chats noirs dans tout mon code, il n’est donc pas nécessaire de continuer à instancier BlackCatPredicate encore et encore. Il ne devrait y avoir qu'un cas. (Un singleton?) Mais, au fil de l'écriture de nombreux prédicats, je ne veux pas avoir à implémenter chacun d'eux en tant que singleton. Alors, quel est le bon design ici?

Était-ce utile?

La solution

J'utiliserais une constante de classe anonyme et la mettrais avec la classe sur laquelle elle opère:

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
}

Si le prédicat a des paramètres, vous pouvez utiliser une méthode de fabrique statique.

Modifier: Comme indiqué dans les commentaires, il peut en résulter un code plus clair permettant de collecter les constantes de prédicat (et / ou les méthodes d'usine) dans une classe distincte, seulement ceux pour Cat, ou tous. Cela dépend principalement de leur nombre, de la quantité d'organisation supplémentaire utile.

Autres conseils

Quelque chose comme ça devrait marcher:

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

Vous pouvez créer une fabrique générique qui considère n'importe quel prédicat comme un argument de type, puis génère une instance unique pour un type de prédicat donné.

Une autre approche plus générale consisterait à commencer à utiliser une bibliothèque d’injection de dépendances et à effectuer toute la création de votre objet. En règle générale, vous pouvez changer le type en singleton, le cas échéant, avec peu de changement.

Je ne m'inquiéterais pas de la création d'instances BlackCatPredicate supplémentaires.

Si vous n'aimez pas écrire new BlackCatPredicate() partout, vous pouvez certainement ajouter une méthode de fabrique statique pour pouvoir écrire BlackCatPredicate.getInstance() à la place. Une autre option serait de créer une classe séparée pour pouvoir écrire CatPredicates.getBlackCatPredicateInstance().

Cependant, ceci n’est destiné qu’à résumer la création du prédicat à partir du code client, cela n’a rien à voir avec la création d’un objet. La JVM s’efforce de mieux gérer les objets éphémères. Par conséquent, la création de nombreuses instances <=> supplémentaires et leur suppression immédiate n’affecteront en rien votre performance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top