È accettabile creare un codice mediocre ora in preparazione per nuove funzionalità linguistiche? [chiuso]

-1

Sarò specifico: Java 8 è promesso di portare tra le altre espressioni lambda nonché riferimenti al metodo e al costruttore. Come sviluppatore Java sono molto contento di questo.

Nella mia programmazione quotidiana vedo sempre più opportunità in cui l'utilizzo di queste funzionalità semplificherebbe enormemente il codice che altrimenti sarebbe molto prolisso e noioso. Invece di riferimenti al metodo e al costruttore, ho iniziato a usare sempre più riflessioni e ho pianificato di migrare quei percorsi di codice in Java 8 il prima possibile. Uso commenti speciali (come i ben noti commenti di TODO: JAVA8) che possono essere utilizzati dall'IDE o facilmente aperti per trovare i luoghi pertinenti. Inoltre, eseguo test approfonditi su tutti i casi per assicurarmi che funzionino.

Ma devo ancora chiedermi se sia bello farlo in quel modo. È accettabile produrre un codice un po 'più fragile ora che alla fine diventerà di nuovo robusto? GA per Java 8 è settembre 2013, quindi non è troppo lontano nel futuro (a condizione che la data di rilascio non scorra).

Un esempio generico dovrebbe essere qualcosa del genere: voglio creare alcuni oggetti contenitore e riempirli con dati da un database. Se dovessi usare l'approccio standard di Java, potrebbe apparire come questo:

class ContainerService {
  private Database database;
  private final Map, ContainerInitializer> INITIALIZERS = new HashMap();

  {
    INITIALIZERS.put(Foo.class, new FooInitializer());
  }

  public Container getContainer(Class cls) {
    return INITIALIZERS.get(cls).create();
  }

  interface ContainerInitializer {
    Container create();
  }

  class FooInitializer implements ContainerInitializer {
    Container create() {
      return new Container(database.getFoo());
    }
  }
}

Il codice riflettente è

class ContainerService {
  private Database database;
  private final Map, String> INITIALIZERS = new HashMap();

  {
    INITIALIZERS.put(Foo.class, "getFoo");
  }

  public Container getContainer(Class cls) {
    Method m = Database.class.getMethod(INITIALIZERS.get(cls));
    return new Container(m.invoke(database));
  }
}

Nota come tutte le interfacce e le classi intermedie cadono.

La variante Java 8 è qualcosa che segue le seguenti linee:

class ContainerService {
  private Database database;
  private final Map, ContainerInitializer> INITIALIZERS = new HashMap();

  {
    INITIALIZERS.put(Foo.class, database::getFoo);
  }

  public Container getContainer(Class cls) {
    return new Container(INITIALIZER.get(cls).create());
  }

  private interface ContainerInitializer {
    Container create();
  }
}

Questo è leggermente più lungo di nuovo ma ha la sicurezza del tipo. Inoltre è banale ottenere dal codice preparato il codice finale usando i riferimenti al metodo.

Ovviamente l'esempio è un po 'semplice. Immagina di avere molti tipi che il contenitore potrebbe contenere. Nel primo metodo, ci sarebbe una classe extra per ognuno di essi. Negli altri due metodi, devono essere aggiunti solo i dati. Mantiene tutto molto più semplice.

    
posta musiKk 18.02.2013 - 15:06
fonte

4 risposte

37

Non cadere nel canto delle sirene.

La loro canzone parla di nuove funzionalità e miglioramenti delle prestazioni, ma tutto ciò che ottieni ascoltando questo è un flusso infinito di dolore, ritardi, procrastinazione e problemi di implementazione.

Scrivi ciò che esiste . Il resto è solo speculazione.

    
risposta data 18.02.2013 - 15:15
fonte
3

Sono d'accordo con la risposta di @ ZJR, ma se vuoi andare avanti puoi probabilmente racchiuderlo in una classe MethodReference di qualche tipo. Con un po 'di fortuna potresti essere in grado di guadagnare sicurezza di tipo manipolando solo un posto quando Java 8 arriva.

Boost fondamentalmente lo fa prima del C ++ 11. Alcune funzionalità assomigliano molto alla sintassi proposta per C ++ 11 per facilitare la transizione.

    
risposta data 18.02.2013 - 16:08
fonte
2

Condivido l'opinione di ZJR secondo cui dovresti attenersi a ciò che è disponibile oggi e svilupparlo per Java 6 o 7, se è quello che stai usando ora: usa sempre gli strumenti che hai ora per quello che sono, non per quello che sono potrebbe essere in futuro.

Aggiungo che se ti piacciono davvero le funzioni anonime e altri idiomi di linguaggio funzionale, dovresti prendere in considerazione il passaggio a Scala, Clojure o un'altra lingua che già esiste e supporta pienamente tali idiomi, invece di aspettare che Java supporti alcuni di quegli idiomi un po 'di tempo in futuro. Altrimenti, quando hai le tue belle espressioni lambda in Java 8, potresti conoscere la corrispondenza dei pattern e iniziare a mancare (forse lo avrai con Java 10?) E poi sentirai parlare di funzionalità di inferenza di tipo currying o più ricco, e devo aspettare ancora.

Quindi, vorrei attenermi a Java 6 per la programmazione orientata agli oggetti e passare a un linguaggio che supporta realmente la programmazione funzionale se si desidera eseguire una programmazione funzionale adeguata o un mix di programmazione orientata agli oggetti e funzionale. In altre parole, non attenersi a Java se questa lingua non fornisce la combinazione di funzionalità che stai cercando.

E sono anche d'accordo con "Non cedere al canto delle sirene". Penso che Oracle stia introducendo alcuni FP in Java (tra le altre ragioni) per continuare a vendere Java alle persone che sono non sono veramente interessato al FP (altrimenti userebbero un vero linguaggio FP già) ma non voglio essere considerato uncool per non conoscere FP.

A mio parere, è perfettamente OK stare fuori da questo clamore e continuare a usare linguaggi puramente orientati agli oggetti (come Java 6) se ci si sente a proprio agio con loro. E se si scrive codice corretto orientato agli oggetti, non sarà "codice mediocre".

    
risposta data 19.02.2013 - 12:02
fonte
0

Penso che la risposta a questa domanda molto probabilmente dipenda dalla situazione in particolare con cui hai a che fare. In termini di "programmazione quotidiana", questo è costituito dal tuo lavoro? Hobbyist / lavoro personale, forse? Se è il secondo, non penso necessariamente che sia una cattiva idea guardare avanti per quanto riguarda il refactoring e il miglioramento della tua base di codice, se hai tempo - il tentativo di migliorare il tuo lavoro non è mai una cosa negativa. D'altra parte, se si tratta di uno scenario di lavoro, anche se sei un project manager, dovresti comunque eseguire tali pensieri dai tuoi colleghi per ottenere il loro input. Tuttavia, poiché queste funzionalità non esistono ancora, a meno che tu non abbia nient'altro sul tuo piatto, potrebbe essere uno spreco di tempo e risorse molto grande perché nessuna delle funzionalità esiste realmente.

È certamente qualcosa a cui pensare, e ci sono alcuni modi in cui puoi gestirlo. Si menziona la possibilità di utilizzare i commenti di TODO in cui è possibile applicare le funzionalità di Java 8. Potresti anche considerare la ramificazione / forking di un progetto interamente e la scrittura di pseudocodici di ripiego (supponendo che la sintassi lambda in Java 8 non sia ancora finalizzata) in punti in cui potresti volerli migliorare in futuro. Di nuovo, tuttavia, fa emergere le preoccupazioni sopra menzionate del tempo e dello sforzo.

    
risposta data 18.02.2013 - 15:21
fonte

Leggi altre domande sui tag