Pattern di progettazione della strategia modificata

11

Di recente ho iniziato a esaminare i modelli di progettazione e una cosa che sto codificando si adatta perfettamente al modello di strategia, fatta eccezione per una piccola differenza.

Essenzialmente, alcuni (ma non tutti) i miei algoritmi, hanno bisogno di un parametro aggiuntivo o di due passati a loro.

Quindi avrò bisogno di

  • passa loro un parametro extra quando invoco il loro metodo di calcolo

o

  • memorizzarli come variabili all'interno della classe ConcreteAlgorithm ed essere in grado di aggiornarli prima di chiamare l'algoritmo.

Esiste un modello di progettazione per questa esigenza / Come potrei implementarlo mentre si attacca al Modello di strategia?

Ho preso in considerazione il passaggio dell'oggetto client a tutti gli algoritmi e l'archiviazione delle variabili, quindi l'ho utilizzato solo quando l'algoritmo specifico ne ha bisogno. Tuttavia, penso che sia al tempo stesso poco maneggevole e sconfigge il punto del modello strategico.

Per essere chiari, sto implementando in Java e quindi non ho il lusso dei parametri opzionali (che risolvono bene questo aspetto).

    
posta Megan Walker 13.03.2011 - 13:49
fonte

5 risposte

5

Samuel, è possibile incapsulare il parametro che ciascuna delle strategie assume in una classe comune e quindi estendere quella classe Parameter comune per aggiungere più comportamenti di cui alcune delle tue strategie hanno specificamente bisogno?

per es.

StrategyParameter //Base strategy parameter that most of the strategies need
        ^
        |
        |
SpecialStrategyParameter // will be used for strategies that need more parameter

Quindi, definire la gerarchia della strategia come:

Interface MyStrategy {
   void myStrategyMethod(StrategyParameter parameter);
}

class MyNormalStrategy extends MyStrategy {
   void myStrategyMethod(StrategyParameter parameter) {
       //implement the logic here
   }
}

chiama la strategia sopra indicata come myNormalStrategyInstance.myStrategyMethod(strategyParameter);

class MySpecializedStrategy extends MyStrategy {
   void myStrategyMethod(StrategyParameter parameter) {
       //implement the logic here
   }
}

chiama la strategia sopra facendo passare SpecialStrategyParameter instance invece che: mySpecializedStrategy.myStrategyMethod(specialStrategyParameter);

Si prega di aggiornare se qualcosa non è chiaro. Sarò felice di spiegare / chiarire.

    
risposta data 13.03.2011 - 18:16
fonte
3

Devi chiarire la tua strategia .

Dipende tutto da come usi i tuoi algoritmi. Affinché la classe del cliente utilizzi le diverse implementazioni strategiche in modo intercambiabile, è necessario che tutti abbiano una astrazione comune. Se non seguono la stessa interfaccia, forse ciò di cui hai bisogno sono diverse astrazioni .

Ho usato strategie configurabili prima, dove parametrizzate le classi concrete sulla costruzione:

interface Strategy {
  int calculate();
}

class ConcreteStrategyThatNeedsAParameter implements Strategy {
  private final int param;
  public ConcreteStrategyThatNeedsAParameter(int param) {
    this.param = param;
  }
  public int calculate() { 
    // uses param...
  }
}

Ora, qualcuno deve ancora creare un'istanza di questa classe e passarla al tuo cliente. Ma il tuo cliente deve solo conoscere l'interfaccia Strategy .

Funziona anche se la tua strategia metodo prende i parametri, ma poi il tuo client conosce su quei parametri e li passa ad implementazioni tutte che funziona con.

    
risposta data 01.01.2012 - 05:16
fonte
1

Finché la firma è definita chiaramente sull'interfaccia, continua a essere conforme al modello di strategia.

I pattern scritti sono la forma più semplice in assoluto che mostra ancora il comportamento previsto, quindi puoi abbellirli finché mantengono l'intento originale. Questo naturalmente presuppone che tu voglia seguire lo schema. Non ha senso usare uno schema se non si adatta, o solo perché è lì, ma nel tuo caso penso che tu stia bene.

    
risposta data 13.03.2011 - 14:23
fonte
0

estendendo la risposta sopra fornita da peakit - puoi usare l'astrazione. Sto usando il codice di peakit qui -

Interfaccia MyStrategy {     abstract void myStrategyMethod (parametro StrategyParameter); }

classe MyNormalStrategy estende MyStrategy {    public override void myStrategyMethod (parametro StrategyParameter) {        // implementa la logica qui    } }

classe MySpecializedStrategy estende MyStrategy {    public override void myStrategyMethod (parametro StrategyParameter, ExtraStrategyParameter extraParameter) {        // implementa la logica qui    } }

Se capisco correttamente la tua domanda, volevi passare un parametro extra ad alcuni algoritmi, giusto? Per favore fatemi sapere se questo è quello che stavi cercando?

    
risposta data 13.03.2011 - 18:33
fonte
0

Se si esamina il libro dei modelli di progettazione, non è di per sé sbagliato che esista un po 'di SimpleStrategy che utilizza meno o nessuno dei parametri passati, o che i parametri sono di una misura unica o minima / comune -moltiplicatore. La scelta di progettazione qui è se questo ti fa male in termini di elaborazione extra che finisce per non essere utilizzato.

    
risposta data 31.12.2011 - 17:13
fonte

Leggi altre domande sui tag