2010-06-28 10 views
5

Qualsiasi linguaggio di programmazione che non abbia un meccanismo di riflessione adatto, trovo seriamente debilitante per problemi che cambiano rapidamente.Come si può essere ASCIUTTI con un linguaggio di programmazione che non ha Reflection?

Sembra con alcune lingue la sua incredibile difficile o non è possibile fare:

  • convenzione sulla configurazione
  • automatico Databinding
  • AOP/programmazione Meta

senza riflessione .

Alcuni linguaggi di esempio che non hanno una sorta di riflessione programmatica sono: C, C++, Haskell, OCaml. Sono sicuro che ce ne sono molti di più.

Per mostrare che è possibile eseguire un esempio di DRY (Non ripeterlo) che viene violato dalla maggior parte di queste lingue è quando si devono scrivere Test unitari. È quasi sempre necessario registrare i test case in queste lingue al di fuori di dove si definisce il test.

In che modo i programmatori di questi linguaggi mitigano questo problema?

MODIFICA: lingue comuni che hanno una riflessione per coloro che non conoscono sono: C#, Java, Python, Ruby e il mio preferito F # e Scala.

MODIFICA: I due approcci più comuni sembrano essere code instrumentation e la generazione del codice. Tuttavia non ho mai visto la strumentazione per C.

Invece di votare per chiudere, qualcuno potrebbe commentare perché dovrebbe essere chiuso e io cancellerò il post.

+9

no. Mi ripeto tutto il tempo in C. – AShelly

+0

@AShelly perché continueresti a sbattere la testa o a mozzare il dito contro il muro :) Puoi cambiare la tua lingua in qualcos'altro? –

+0

Sono curioso di sapere quali lingue possono fare tutte quelle cose così bene? – FrustratedWithFormsDesigner

risposta

1

Un bel esempio per il test dell'unità C++ è cxxtest: http://cxxtest.tigris.org/. Usa la convenzione e uno script python per generare la tua suite di test C++ post-processando il tuo C++ con python.

Un buon modo per pensare a aggirare le restrizioni nelle lingue è la nozione di "cuciture" di Michael Feathers. Una cucitura è un luogo in cui è possibile modificare il programma senza modificare il codice. Ad esempio, in C il pre-processore e il linker forniscono cuciture. Nel polimorfismo C++ è un altro posto. Nei linguaggi più dinamici, ad esempio dove è possibile modificare le definizioni dei metodi o riflettere, si ottiene ancora più flessibilità. Senza le cuciture le cose possono essere più complicate ea volte semplicemente non vuoi provare a martellare un chiodo con la tua scarpa, ma piuttosto andare con il flusso dello strumento a portata di mano.

+0

@paulrubel Ho la sensazione che il pre-elaborazione sia ciò che fanno questi linguaggi. Alcune persone pensano che la riflessione sia l'odore del codice. Penso che la pre-elaborazione sia molto peggio. +1 per il collegamento –

+0

La cosa che salva la giornata qui è che i risultati dello script python vengono rigenerati ogni volta che sono necessari, non è come una procedura guidata in cui si mantiene il codice generato e occorre modificarlo. –

+0

@paulrubel Devo controllare le "cuciture". Vorrei poterti dare un altro +1 per la tua modifica eccellente. –

2

Penso che sia una questione di laurea. La riflessione è solo un metodo molto potente per evitare la ripetizione.

Ogni volta che si generalizza una funzione da un caso specifico in cui si utilizza il principio ASCIUGATURA, più generale lo si rende più ASCIUTTO lo è. Solo perché alcune lingue non ti portano dove ti trovi con la riflessione non significa che non ci siano modi ASCIUTTI di programmazione con loro. Possono non essere ASCIUTTI, ma ciò non significa che non hanno i loro vantaggi unici che nella somma totale possono superare i vantaggi dell'uso di un linguaggio che ha una riflessione. (Ad esempio, le conseguenze della velocità derivanti dall'uso intensivo della riflessione potrebbero essere una considerazione.)

Inoltre, un metodo per ottenere qualcosa come i benefici di DRY della riflessione con un linguaggio che non lo supporta è utilizzando un buon strumento di generazione del codice. In tal caso, si modifica il codice per casi diversi una volta, nel modello di generazione del codice e il modello lo invia a diverse istanze nel codice. (Non sto dicendo che usare o meno la generazione del codice sia una buona cosa, ma con un buon generatore "attivo" è certamente un modo per ottenere qualcosa come il beneficio DRY della riflessione in un linguaggio che non ha riflessioni. i vantaggi della generazione del codice vanno oltre questo semplice vantaggio. Sto pensando a qualcosa come CodeSmith, anche se ce ne sono molti altri: http://www.codesmithtools.com/)

3

Non è così.
Ma è possibile mantenere le ripetizioni vicine l'una all'altra così quando si cambia qualcosa, si vede anche qualcos'altro.

Per esempio, ho scritto un JSON-Parser che emette gli oggetti, una chiamata tipica assomiglia a questo:

struct SomeStruct 
{ 
     int a; 
     int b; 
     double c; 

     typedef int serializable; 
     template<class SerializerT> void serialize(SerializerT& s) 
     { 
       s("a",a)("b",b)("c",c); 
     } 
};

Certo, quando si aggiunge un campo, si deve aggiungere un altro campo nella funzione, ma forse non vuoi serializzare quel campo (qualcosa che dovresti gestire anche in linguaggi con riflessi), e se elimini un campo senza rimuoverlo dalla funzione, il compilatore si lamenterà.

+0

Sfortunatamente ciò non risolve il problema del Test unità. +1 per la risposta –

2
  1. Astrattamente, fare di più in fase di runtime, senza i benefici di cose come tipo in fase di compilazione controllo (si deve scrivere in sostanza il proprio tipo-controllo di routine) e codice bello. Ad esempio, usa una tabella invece di una classe. (Ma se l'hai fatto, perché non usare invece un linguaggio tipizzato dinamicamente?) Questo è spesso male. Non lo consiglio.

  2. In C++, le tecniche di programmazione generiche consentono di includere a livello di programmazione i membri di una classe (è ciò che si desidera fare?) Tramite l'ereditarietà.

+2

Aye. L'opzione 1 sta essenzialmente applicando il vecchio "Qualsiasi cosa può essere risolta con un altro livello di riferimento indiretto". massima. – caf