2015-11-20 10 views
5

Ho una coppia di file di proprietà (chiave/valore) da cui attualmente leggo un valore rispetto a una chiave e visualizzo tale valore come è nell'interfaccia utente.Modello di progettazione Java per mantenere un nome di metodo in un file di proprietà

La complessità è aumentata, ora il valore è più dinamico in base ad alcune formule. La formula include un parametro variabile il cui valore otterrò in fase di esecuzione.

Esiste un modello di progettazione java per progettare questo scenario.

Stavo pensando di inserire un nome di metodo nel file di proprietà su una chiave.

Ora leggerò la chiave e recupererò il nome del metodo. Questo metodo calcolerà il valore per quella particolare chiave.

Per favore fatemi sapere il vostro suggerimento

+2

Il modello di progettazione è "scrivi un analizzatore di espressioni parser/albero" ... o "incorpora un interprete di espressioni esistente". –

+0

È possibile utilizzare la normale serializzazione e questo https://en.wikipedia.org/wiki/Reverse_Polish_notation Ad esempio: http://stackoverflow.com/questions/1320891/java-rpn-reverse-polish-notation-infix-to- postfix – Alexmelyon

+0

Soluzioni come MVEL o spring EL ti aiuteranno. –

risposta

1

Esiste un modello di progettazione del Java per la progettazione di questo scenario.

Non so se c'è uno schema.


Se ho capito la tua domanda giusta posso spiegare quello che faccio di solito.

  • inserire stringhe localizzabili nei miei proprietà valori
    Io di solito uso #number#
  • Sostituire in un secondo momento quando le variabili vengono risolte

piccolo esempio:

messages.properties

name.of.key = sum of #0# + #1# = #2# 

Poi leggere il valore da e sostituire il #num# con valori gli appropriati (NOTA: qui è lo stesso metodo per shortenes, ma utilizzare un replace metodo esterno):

public void printSum(int n1, int n2) { 
    String myString = messageSource("name.of.key", Locale.getDefault(), null, null)); 
    myString.replace("#0#", String.valueOf(n1)); 
    myString.replace("#1#", String.valueOf(n2)); 
    myString.replace("#2#", String.valueOf(n1+n2)); 
    System.out.println(myString); 
} 

USCITA printSum(1,2);

sum of 1 + 2 = 3 
+0

Upvote per aver notato che il design non viene sempre in pattern. –

0

È possibile utilizzare la modello di strategia mettendo il nome del metodo/algoritmo nel file di proprietà:

public interface IFormula{ 
    public int formula(int a, int b); 
} 
public class Sum implements IFormula{ 
    public int formula(int a, int b){ 
     return a+b; 
    } 
} 

Quindi è possibile selezionare il metodo di ottenere il nome da un file di proprietà:

public static Strategy getStrategy(Name name) { 
    switch (name) { 
     case SUM: 
      return new Sum(); 
     ... 
    } 
} 
+0

Tranne i problemi minori di precedenza degli operatori e parentesi. – EJP

+0

Questo è solo un esempio del modello di strategia. La domanda non specifica la formula ... – Valerio

+0

La domanda è intitolata 'Modello di progettazione Java per mantenere una formula in un file di proprietà' e non hai risposto correttamente, tranne che per casi banali e senza specificare i suoi limiti. – EJP

1

Usare Java incorporato JavaScript engine per valutare le espressioni . Per abbinare lo spirito più da vicino, puoi usare JSON per le proprietà.

Se la sicurezza è importante, è necessario fornire lo class filter. Può essere molto semplice e restrittivo in quanto è necessario solo valutare espressioni banali. L'esempio sul filtro di classe può essere trovato here.

+0

Esiterei a raccomandare questa soluzione perché crea una vulnerabilità agli attacchi di iniezione. Con questo cambiamento, lo sviluppatore deve ora occuparsi della sicurezza della chiave, coppie di valori. – scottb

+0

È molto semplice limitare il JavaScript se questo è un problema. Ho modificato la domanda spiegando come farlo. – h22

1

Sembra che lo ANTLR farebbe un ottimo adattamento.

È un generatore di parser. Gli dai la grammatica come input e in cambio ti fornisce un parser.

È possibile utilizzare il parser per trasformare la formula testuale in una rappresentazione ad albero analizzata. Successivamente, è possibile eseguire un visitatore per valutare ciascuno dei nodi. Basta scrivere qualche funzione semplice da implementare il comportamento, come ad esempio:

public Double visitAdd(AntlrNode left, AntlrNode right) { 
    Double left = visit(left); 
    Double right = viist(right); 

    return left + right; 
} 

La grammatica è molto vicino alla notazione BNF familiare. Descrivi solo come sono le tue stringhe di formula. Ad esempio:

formula : left '+' right; 
left: Number; 
right: Number; 
Number: [0-9]+; 
0

Un'altra soluzione è il refactoring della mappa in modo che il tipo di valore sia un'interfaccia funzionale il cui metodo accetta un parametro arbitrario. Per esempio:

@FunctionalInterface 
interface ValueType<R> { 
    R eval(Object param); 
} 

Questa soluzione (o una variante di esso) permetterebbe di associare un lambda con le chiavi piuttosto che un valore fisso. L'esecuzione di un lambda dovrebbe essere molto meglio di un parser di run-time pur continuando a offrire la flessibilità necessaria per far dipendere il valore associato da un argomento run-time.

Questa soluzione deve anche essere meno vulnerabile agli attacchi di iniezione rispetto a una soluzione basata sull'analisi di runtime.

0

Dal momento che sembra voler un nome per il motivo ... il motivo è chiamato: Domain Specific Language.

E di nuovo se si desidera rimanere nei regni di modelli astratti e design è possibile leggere Martin Fowlers discussion on the topic at length.

Inutile dire che sono una tonnellata di strumenti che risolvono il modello di cui sopra (comprese alcune delle risposte qui).

L'altro schema che consiglio vivamente di NON do è utilizzare un linguaggio generico con un programma di valutazione (ad es. Javascript, EL, Groovy, ecc.). Questo in genere ha problemi di sicurezza e di prestazioni (ovviamente ci sono delle eccezioni).

Problemi correlati