7

J'ai plusieurs classes Java qui implémentent le modèle de stratégie. Chaque classe a des paramètres de nombre variable de différents types:Modèle de stratégie paramétré

interface Strategy { 
    public data execute(data); 
} 

class StrategyA implements Strategy { 
    public data execute(data); 
} 

class StrategyB implements Strategy { 
     public StrategyB(int paramA, int paramB); 
     public data execute(data); 
} 

class StrategyC implements Strategy { 
     public StrategyC(int paramA, String paramB, double paramC); 
     public data execute(data); 
} 

Maintenant je veux que l'utilisateur puisse entrer les paramètres dans une sorte d'interface utilisateur. L'interface utilisateur doit être choisie au moment de l'exécution, c'est-à-dire que les stratégies doivent en être indépendantes. La boîte de dialogue des paramètres ne devrait pas être monolithique et il devrait y avoir la possibilité de la faire se comporter et d'avoir une apparence différente pour chaque stratégie et interface utilisateur (par exemple, console ou Swing).

Comment pourriez-vous résoudre ce problème?

Répondre

4

Une possibilité de le faire est quelque chose de similaire au modèle de conception de Constructeur:

Pour chaque type de stratégie que vous devriez avoir un constructeur correspondant (un ou plusieurs). Le générateur ne fonctionne pas comme un constructeur normal recevant tous les paramètres init comme arguments de méthode; Au lieu de cela, il faut bloquer jusqu'à ce que l'entrée correspondante soit reçue. Certains constructeurs afficheront une boîte de dialogue Swing et attendront, d'autres imprimeront sur la console et attendront les entrées, d'autres pourront lire dans un fichier, etc. Après avoir reçu toutes les entrées, le générateur peut créer l'instance de stratégie et la renvoyer.

De cette façon, vous découplerez la logique de récupération de données de la stratégie elle-même. Un autre avantage est que vous pouvez avoir une interface générique de tous les constructeurs, donc une fois que vous choisissez un constructeur spécifique, vous pouvez le manipuler avec le même morceau de code.

+0

+1 En d'autres termes, les constructeurs eux-mêmes seraient des stratégies. Agréable. –

1

La solution de ce problème dépend principalement de ce qui détermine quelle stratégie est la stratégie actuelle. Pour simplifier, je suppose que l'interface utilisateur est la même pour toutes les stratégies.

Pratiquement, vous allez créer une classe de construction ou une méthode d'usine. Quelque chose le long de cette ligne:

interface StrategyPicker { 
    public Strategy getStrategy(); 
} 

// Most likely used in the JFrame it is added to 
class StrategyPickerUI extends JPanel implements StrategyPicker { 
    // initialize the panel with all the widgets 
    // and implement the getStrategy method. the getStrategy 
    // method should be called after the input is done in this 
    // panel (such as clicking an Ok or Apply button) 
} 

// You can also make one for the console app 
class StrategyPickerSimple implements StrategyPicker { 
    // ... 
} 

Si vous voulez être vraie fantaisie que vous créez une classe simple d'usine pour enlever l'acte de créer dans sa propre classe:

public class StrategyFactory() { 
    public static Strategy createStrategyFromParameters(StrategyParams sp) { 
     // creates the Strategy object... doesn't need to be public static 
     // and if it isn't, it will help making unit tests easier 
    } 

    // This nested class could be split up to StrategyAParams, 
    // StrategyBParams, StrategyCParams 
    public class StrategyParams { 
     data paramA; 
     int paramB_A; 
     int paramB_B; 
     int paramC_A; 
     String paramC_B; 
     float paramC_C; 
    } 
} 

// in StrategyPickerUI class 
    public getStrategy() { 
     StrategyParams sp = new StrategyParams(); 
     sp.paramB_A = myJTextFieldParamB_A.getText(); 
      // and so on... 
     return StrategyFactory.createStrategyFromParameters(sp); 
    } 

Si vous voulez garder l'interface utilisateur non-monolithique, puis diviser les responsabilités à leurs propres objets. J'espère que cela t'aides.

0

Si vos classes de paramètres contiennent un objet simple (Numbers, Boolean, Date, String), vous pouvez essayer de générer votre interface lors de l'exécution.

Il sera plus difficile de générer une interface utilisateur et ensemble de paramètres

objets composés Jetez un oeil à Metawidget c'est un générateur ui puissant.