2012-02-07 9 views
10

Nel mio progetto ho bisogno di creare oggetti per ogni tipo di Java Math Operator come "Aggiungi", "Substraction", "Moltiplicazione", ecc. E questi operatori dovrebbero essere singleton.Java - istanze di implementazione all'interno di un'interfaccia

Quindi ecco cosa ho intenzione di fare. Definisco l'operatore matematico come un'interfaccia e inserisco tali implementazioni al suo interno poiché non voglio definire classi singleton per ciascun operatore.

public interface MathOperator { 


double operate(double a, double b); 

MathOperator ADD = new MathOperator(){ 

    @Override 
    public double operate(double a, double b) { 
     return a + b; 
    } 

}; 

MathOperator SUBSTRACT = new MathOperator(){ 

    @Override 
    public double operate(double a, double b) { 
     return a - b; 
    } 

}; 

} 

Non vedo molto di tale utilizzo quando eseguo questa operazione su Google. Quindi mi chiedo se questa è una buona pratica e se ci sono approcci migliori e più aggraziati?

+0

sono statici di default –

risposta

5

avrei fatto SMT come

1) Definisci interfaccia

interface MathOperator { 
    double operate(double a, double b); 
} 

2) che avere un po 'di implementazione comuni a enum (meno codice)

enum MathOperators implements MathOperator { 
    ADD { 
     @Override 
     public double operate(double a, double b) { 
      return a + b; 
     } 
    }, 

    SUBTRACT { 
     @Override 
     public double operate(double a, double b) { 
      return a - b; 
     } 
    } 
} 

3) O i membri statici pubblici (soluzione più pulita).

class MathOperators { 
    public static MathOperator ADD = new MathOperator() { 
     @Override 
     public double operate(double a, double b) { 
      return a + b; 
     } 
    }; 
    public static MathOperator SUBTRACT = new MathOperator() { 
     @Override 
     public double operate(double a, double b) { 
      return a - b; 
     } 
    }; 
} 
  • possibile creare nuovi MathOperator senza cambiare MathOperators
  • avere bel API per le operazioni più comuni
  • non dovrebbe scrivere singletons
  • hanno bella interfaccia pulita
+2

È necessario implementare 'MathOperators'' MathOperator' altrimenti non si @ Ignora nulla. –

+0

@Peter Grazie per il punto. –

+0

Sì, sembra meglio che prenderò la soluzione 'enum implements interface'. Grazie. – Jay

4

Uso spesso questo modello, soprattutto per implementazioni specifiche di interfacce generiche. Trovo funziona davvero bene per me.

Mi piace il modo in cui mette le implementazioni dove è possibile trovarli. Io lo faccio in modo leggermente diverso - li faccio statico (è una cosa stile, in modo che i impls interfaccia più simile impls classe):

public interface MathOperator { 

    double operate(double a, double b); 

    public static MathOperator ADD = new MathOperator() { 
     @Override 
     public double operate(double a, double b) { 
      return a + b; 
     } 
    }; 

    public static MathOperator SUBSTRACT = new MathOperator() { 
     @Override 
     public double operate(double a, double b) { 
      return a - b; 
     } 
    }; 

} 
+3

sono statici di default –

+0

sì, ma per le classi astratte uso statico, quindi lo stile del codice rimane costante – Bohemian

2

non vedo alcun problema con esso. Prendi ad esempio java.lang.String.CASE_INSENSITIVE_ORDER. È quasi la stessa, tranne che

  1. stringa non è un'interfaccia ma una classe finale
  2. Il Comparator non è dichiarato usando una classe anonima, ma utilizzando una classe interna statica, che è essenzialmente lo stesso
5

Un linguaggio che ho visto usato proprio in queste circostanze è l'uso di enum:

public enum MathOperator { 

    ADD { 
     @Override 
     public double operate(double a, double b) { 
      return a + b; 
     } 
    }, 

    SUBTRACT { 
     @Override 
     public double operate(double a, double b) { 
      return a - b; 
     } 
    }; 

    public abstract double operate(double a, double b); 

} 
+2

le enumerazioni sono OK quando si dispone di un numero finito di possibili impls, ma quando si desidera alcuni comuni a portata di mano, la regola delle costanti dell'interfaccia. Quello che * potresti * fare è avere 'enum MathOperatorImpl implementa MathOperator'! Mi piace ancora meglio !! : D – Bohemian

+0

Grazie a @Bohemian, prenderò la soluzione 'enum implements interface'. – Jay

+0

@Bohemian Ricordo una simile raccomandazione in Java efficace, per usare le interfacce per emulare enumerazioni estendibili. Penso che Jay abbia assolutamente ragione ad usare questa soluzione. – Malcolm

1

Personalmente, non mi piace mettere implementazioni all'interno di interfacce. Vorrei uno:

  • fare MathOperator un enum
  • mantenere l'interfaccia, ma hanno una fabbrica o di una classe statica (diciamo MathOperators) con le implementazioni
0

Perché non definisci ogni implementazione nella sua classe/file? Ciò renderebbe più chiaro e lascerebbe l'interfaccia pulita.