2014-11-21 18 views
5

Ho controller che esegue alcuni comandi in base al nome del comando, presi dall'URL. Il punto principale è non usare le clausole if e switch. Come so ci sono solo due modi come farlo - 1) comando schema 2) riflessione.Command pattern vs reflection

//Command pattern 
class Controller{ 
    private HashMap<String,Command> commands; 
    public void executeCommand(String commandName){ 
    commands.get(commandName).execute(); 
    } 
    ... 
} 

//reflection 
class Controller{ 
    public void readCommand(){ 
    .... 
    } 
    public void executeCommand(String commandName){ 
    this.getClass().getMethod(commandName+"Command").invoke(this); 
    } 
    ... 
} 

Così i questios:

  1. che uno è meglio?
  2. È normale in un'applicazione consentire agli sviluppatori di utilizzare uno dei metodi che desiderano.
  3. Ci sono altri modi?
+0

Cosa succede se l'utente immette 'execute'? Ciò causerà 'executeCommand' per provare a chiamarsi in modo ricorsivo? Usando il reflection in questo modo, dove si utilizza una stringa immessa dall'utente per determinare quale metodo utilizzare, appare molto ** pericoloso. Potrebbe anche mettere un segno sul tuo programma dicendo "Ehi, cybercriminali! QUESTO MODO !!!" – ajb

+1

@ajb Grazie per il tuo commento. Lo so, ecco perché usiamo url mapper via xml (url -> component, command). Ho scritto "preso dall'URL" per passare l'idea. –

risposta

2
  1. primo modo è meglio, utilizzare riflessi solo quando non hanno altre opzioni.
  2. in un'unica applicazione ci dovrebbe essere un approccio per risolvere un tipo di problema.
  3. Penso che il primo approccio sia soddisfacente. (Molto meglio quindi se/else blocchi)
0

Penso che ci siano 2 modi diversi per il tuo primo approccio. Ogni comando potrebbe essere una sottoclasse del comando di classe astratta. O ogni comando potrebbe essere un'istanza del comando di classe. Questo dipende da quanto dovrebbe essere flessibile, e sono i parametri e i valori di ritorno per i comandi? Con sottoclassi che sarebbe simile a questa (solo per avere l'idea):

abstract public class Command { 
    abstract public void execute(); 
} 

public class LsCommand extends Command 
{ 
    @Override 
    public void execute() { 
     try { 
      Runtime.getRuntime().exec("ls"); 
     } catch (IOException e) {} 
    } 
} 

public class ChdirCommand extends Command 
{ 
    @Override 
    public void execute() { 
     try { 
      Runtime.getRuntime().exec("chdir"); 
     } catch (IOException e) {} 
    } 
} 

Ecco le mie risposte:

  1. Il tuo primo modo è meglio. Preferisci sempre i modelli di progettazione oltre la riflessione .
  2. dispiace non capisco domanda 2. Ma non ha un punto di domanda comunque, quindi mi basta saltare :)
  3. si potrebbe desiderare di esaminare la Strategy design pattern, dove ogni comando potrebbe anche essere fatto di diverse parti dei comandi secondari. Un'altra idea sarebbe il . In tal caso, l'utente inserirà ciascun comando in una classe e quindi utilizzerà ClassLoader su caricando la classe in base al nome.
+0

Grazie per la risposta. Penso che tu abbia frainteso la domanda un po '. Lo schema di comando riguarda la selezione dinamica del metodo necessario per stringa. Ad esempio, stringa "aaa" - method1(), "bbb" - method2() senza utilizzare if e switch. –

1

Quale è il migliore?

Ovviamente il primo è migliore. Anche se hai citato che stai usando Command pattern, non è completo il pattern "Command". Il modello di comando avrà Command (abstract), Concrete Command, Receiver, Invoker e Client.

Date un'occhiata a questa domanda:

Using Command Design pattern

Oltre a Comando Patten, vorrei evidenziare i pro ei contro di riflessione.

Pro:

  1. Handling iniezione di dipendenza
  2. Sviluppare plug and play quadri

Contro:

  1. Le chiamate di riflessione sono più lente
  2. È possibile violare la sicurezza ed esplodere l'applicazione con cattive intenzioni (ad es. impostazione variabili private di una classe, che è invisibile ad altra classe)

Dai un'occhiata alla correlata questione SE per quanto riguarda la riflessione:

What is reflection and why is it useful?

E 'normale in una sola applicazione per consentire agli sviluppatori usa uno dei metodi che vogliono.

È normale per gli sviluppatori scegliere il metodo migliore per risolvere un particolare problema.

Ci sono altri modi?

Dipende dal tipo di problema che si intende risolvere. I modelli di progettazione forniscono soluzioni a problemi ricorrenti.

Tutte le soluzioni non possono essere adattate nei modelli di progettazione esistenti. Potresti aver sviluppato nuovi modelli per risolvere il tuo problema.