2011-02-15 2 views
2

Je voudrais créer une liste de paires méthode-objet. Chaque méthode est une fonction renvoyant un booléen. Puis:Couches Method-Object en Java

foreach(pair) { 
    if method evaluates to true { 
     do something with the object 
    } 
} 

Une façon de modéliser ce que je peux penser est d'avoir une classe Constraint avec une méthode isValid() et pour chaque contrainte produire une classe anonyme (remplaçant la méthode isValid()). Je pense qu'il pourrait y avoir une meilleure façon. Pouvez-vous en penser?

+1

quelle est la logique dans la méthode? Est-ce la même logique pour tous les éléments? – Bozho

+0

c'est différent à travers l'arbre. –

Répondre

3

En Java, il n'y a pas de pointeurs de méthode, la seule (meilleure) façon de le faire avec une interface commune que vous avez dit:

public interface Constraint { 
    boolean isValid(); 
} 

De cette façon, vous pouvez créer une carte (ou une liste de tuple, comme vous le souhaitez), itérer sur les éléments, appelez la méthode isValid et Constraint effectuer l'opération en fonction de la réponse:

public void doThings(Map<Constraint, Object> map) { 
    for (Entry<Constraint, Object> entry: map.entrySet()) { 
     if (entry.getKey().isValid()) { 
      Object obj = entry.getValue(); 
      // Do whatever you want with the object 
     } 
    } 
} 

Hope it helps.

Cordialement!

0

Cela serait plus facile dans Java si les fonctions étaient des objets de première classe, mais votre approche de retour d'une classe anonyme fonctionnera. Je pense cependant qu'une approche plus propre est le Domain Driven Design specification pattern. L'idée est de définir une interface:

interface Specification { 
    boolean isSatisfiedBy(Criteria criteria) 
} 

interface Criteria { 
    /* what goes on here is up to you */ 
} 

Cela vous permettra de itérer dire une collection de Specification entités comme:

for (Specification s : specifications) { 
    if (!s.isSatisfiedBy(criteria) { continue; } 
    /* do something */ 
} 
+0

Je suggère de changer 'Boolean' en' boolean' en raison de la boxing/unboxing possible lorsque ce code est exécuté dans le cycle et 'isStatisfiedBy' renvoie une primitive. –

+0

OK a été remplacé par 'booléen'. – orangepips

0

programme via une interface que vous implémentez avec votre classe:

package test; 

public interface Constraint { 
    boolean isValid(); 
} 

Utilisez l'interface comme variable et peu importe la classe de la liste tant qu'elle implémente l'interface. Programmez les interfaces ...

package test; 

import java.util.LinkedList; 
import java.util.List; 

public class Main { 
    public static void main(String[] args) { 

    List<Constraint> list = new LinkedList<Constraint>(); 

    list.add(new A()); 
    list.add(new B()); 

    for (Constraint con : list) { 
     if (con.isValid()) { 
     System.out.println("True"); 
     } 
     else { 
     System.out.println("False"); 
     } 
    } 

    } 
} 

class A implements Constraint { 
    @Override 
    public boolean isValid() { 
    return false; // add real code for valid check 
    } 
} 

class B implements Constraint { 
    @Override 
    public boolean isValid() { 
    return true; // add real code for valid check 
    } 
} 
0

Découvrez la bibliothèque Google de Guava. Il contient déjà 2 interfaces susceptibles de vous intéresser.

Le prédicat est une interface très similaire à celle que vous utilisez avec Constraint. Au lieu de isValid(), il a une méthode appelée apply() qui renvoie un booléen pour indiquer si l'objet doit être passé ou non. Ceci est associé à d'autres fonctions de collection de la bibliothèque Guava pour effectuer (ou ne pas effectuer) opérations sur des collections entières. Ce qui est exactement ce que vous semblez faire avec votre pour: chaque boucle.

L'interface de fonction peut également vous intéresser, mais uniquement parce que vous avez affiché des pointeurs de fonction. Je pense que l'interface Predicate avec certaines des autres classes de collection de Guava fera exactement ce dont vous avez besoin dans un minimum de code lisible.

Un exemple de ceci serait:

for(Pair pair : Collections2.filter(pairs, pairPredicate)){ 
    // Do something. All pairs that get to this point have been validated 
} 
+0

Comment le code OP est-il moins lisible? – irreputable

+0

@irreputable - Je ne comprends pas votre question. Qui a dit quelque chose de plus ou moins lisible? J'ai dit que c'était minime et lisible, et une alternative à ce qu'il avait. Il a demandé des alternatives et j'en ai fourni une. – rfeak