Domanda

Sto usando un'interfaccia chiamata Predicate che viene usata per setacciare le Collezioni. Ad esempio, posso definire

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

e quindi utilizzare un metodo di utilità findAll( Collection<T> coll, Predicate<T> pred) per applicare il predicato a una raccolta di gatti e ottenere solo quelli neri, ecc.

La mia domanda è questa: sto trovando gatti neri in tutto il mio codice, quindi non è necessario continuare a creare un'istanza di BlackCatPredicate più e più volte. Dovrebbe avere solo un'istanza. (Un singleton?) Ma poi, nel corso della stesura di molti predicati, non voglio implementare ognuno come singleton. Quindi, qual è il design giusto qui?

È stato utile?

Soluzione

Userei una costante di classe anonima e la metterei con la classe su cui opera:

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
}

Se il predicato ha parametri, è possibile utilizzare un metodo factory statico.

Modifica: Come è stato sottolineato nei commenti, a seconda dei modelli di utilizzo, potrebbe risultare in un codice più chiaro per raccogliere le costanti predicate (e / o metodi di fabbrica) in una classe separata, sia solo quelli per Cat, o tutti loro. Dipende principalmente dal loro numero, dalla quantità di organizzazione aggiuntiva utile.

Altri suggerimenti

Qualcosa del genere dovrebbe funzionare:

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

È possibile creare una factory generica che accetta qualsiasi predicato come tipo arg e quindi genera una singola istanza per un determinato tipo di predicato.

Un altro approccio più generale sarebbe quello di iniziare a utilizzare una libreria di iniezione delle dipendenze e di eseguire tutta la creazione dell'oggetto attraverso di essa. In genere puoi cambiare un tipo in singleton, se appropriato, con poche modifiche.

Non mi preoccuperei affatto di creare BlackCatPredicate istanze extra.

Se non ti piace scrivere new BlackCatPredicate() ovunque, puoi sicuramente aggiungere un metodo statico di fabbrica in modo da poter scrivere invece BlackCatPredicate.getInstance(). Un'altra opzione sarebbe quella di creare una classe separata in modo da poter scrivere CatPredicates.getBlackCatPredicateInstance().

Tuttavia, questo è solo per astrarre la creazione del predicato dal codice client, non ha nulla a che fare con la creazione effettiva dell'oggetto. Trattare oggetti di breve durata è una delle cose che la JVM fa meglio, quindi creare un mucchio di <=> istanze extra e scartarle immediatamente non influirà minimamente sulle tue prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top