Domanda

Sto ricercando e sperimentando di più con Groovy e sto cercando di avvolgere la mia mente intorno i pro e i contro di attuazione cose in Groovy che io non posso/non fare in Java.La programmazione dinamica è ancora solo un concetto per me da quando sono stato profondamente intrise statico e fortemente tipizzato lingue.

Groovy mi dà la possibilità di anatra-tipo, ma non riesco a vedere il valore.Come è l'anatra-a digitare più produttivo rispetto a tipizzazione statica?Che tipo di cose che posso fare nel mio codice pratica mi aiuti a cogliere i benefici di esso?

Pongo questa domanda con Groovy in mente, ma ho capito che non è necessariamente una bella domanda, così ho benvenuti risposte da tutte le code camp.

È stato utile?

Soluzione

A quel punto, che è meglio:EMACS o vi?Questo è uno dei esecuzione di guerre di religione.

Penso in questo modo:qualsiasi programma che è corretto, sarà corretto se la lingua è staticamente tipizzato.Cosa tipizzazione statica non è consentire al compilatore di disporre di informazioni sufficienti per rilevare le incongruenze di tipo in fase di compilazione, invece del tempo di esecuzione.Questo può essere un fastidio se il vostro fare incrementale tipo di programmazione, anche se (mantenere) se stai pensando chiaramente circa il vostro programma non importa molto;d'altra parte, se si sta creando davvero un grande programma, come un sistema operativo o un commutatore telefonico, con decine o centinaia o migliaia di persone che lavorano su di esso, o con esigenze di elevata affidabilità, quindi avere egli compilatore essere in grado di rilevare una vasta classe di problemi per voi senza la necessità di un caso di test di esercitare il giusto percorso di codice.

Non è come se la tipizzazione dinamica è una nuova e diversa cosa:C, per esempio, è effettivamente digitato in modo dinamico, dal momento che ho sempre gettato un foo* per un bar*.Significa solo che è mia responsabilità come programmatore C mai usare il codice appropriato su un bar* quando l'indirizzo è davvero punta a un foo*.Ma come risultato di problemi con programmi di grandi dimensioni, C è cresciuto di strumenti come il panno(1), rafforzato il suo tipo di sistema con typedef e, infine, sviluppato fortemente tipizzato variante in C++.(E, naturalmente, C++ a sua volta sviluppato modi per aggirare la tipizzazione forte, con tutte le varietà di calchi e generici/modelli / e con RTTI.

Un altra cosa, anche se --- non confondere la "agile programming" con "i linguaggi dinamici". Agile programming è di circa il modo di lavorare insieme in un progetto:il progetto può adattarsi alle mutevoli esigenze per soddisfare le esigenze dei clienti, pur mantenendo un ambiente umano per i programmatori?Esso può essere fatto con linguaggi tipizzati in modo dinamico, e spesso è, perché essi possono essere più produttivi (ad esempio, Ruby, Smalltalk), ma può essere fatto, è stato fatto con successo, in C e anche assembler.Infatti, Rally Di Sviluppo utilizza anche metodi agili (SCRUM), per fare marketing e di documentazione.

Altri suggerimenti

Un sacco di commenti per il duck typing in realtà non suffragare le affermazioni."Non aver paura" a proposito di un tipo non è sostenibile per la manutenzione o la realizzazione di un'applicazione estensibile.Ho avuto davvero una buona occasione per vedere Grails in azione sopra il mio ultimo contratto e la sua molto divertente per guardare davvero.Tutti sono felici di circa il utili nel riuscire a "creare-app" e - purtroppo non tutte le catture a voi sul back-end.

Groovy sembra la stessa strada per me.Certo che si può scrivere molto succinta codice e sicuramente c'è qualche bel zucchero in quanto lavoriamo con proprietà, raccolte, ecc...Ma il costo di non sapere che cosa il heck è passati solo peggio e peggio.A un certo punto il grattarsi la testa, chiedendosi perché il progetto è diventato l ' 80%), la prova e il 20% del lavoro.La lezione qui è che i "piccoli" non rendono "più leggibile" codice.Mi spiace, la sua logica semplice: più si deve sapere intuitivamente, più complesso il processo di comprensione che il codice diventa.E ' per questo che la GUI è stato eseguito fuori diventando eccessivamente iconico negli anni - molto bella, ma CON sta succedendo non è sempre evidente.

Persone che in quel progetto sembra avere problemi a "inchiodare" le lezioni apprese, ma quando si hanno metodi di restituzione di un singolo elemento di tipo T, un array di T, un ErrorResult o null ...diventa piuttosto evidente.

Una cosa che lavorano con Groovy ha fatto per me comunque impressionante ore fatturabili woot!

Non c'è niente di sbagliato con tipizzazione statica se si utilizza Haskell, che ha un'incredibile statico tipo di sistema.Tuttavia, se si sta utilizzando linguaggi come Java e C++ che sono terribilmente invalidante tipo di sistemi, il duck typing è sicuramente un miglioramento.

Immaginate di provare a utilizzare qualcosa di semplice come "mappa"in Java (e no, non intendo la struttura di dati).Anche i generici sono piuttosto mal supportato.

Il Duck typing storpi più moderni IDE verifica statica, che possono notare gli errori durante la digitazione.Alcuni considerano questo un vantaggio.Voglio IDE/Compilatore per dirmi che ho fatto una stupida programmatore trucco il più presto possibile.

La mia ultima preferito argomento contro il duck typing proviene da una Grails progetto DTO:

class SimpleResults {
    def results
    def total
    def categories
}

dove results si rivela essere qualcosa di simile Map<String, List<ComplexType>>, che può essere scoperto solo seguendo un percorso di chiamate di metodo in classi diverse fino a trovare dove è stato creato.Per il terminale curioso, total è la somma delle dimensioni di List<ComplexType>s e categories è la dimensione del Map

Potrebbe essere stato chiaro per lo sviluppatore originale, ma la scarsa manutenzione ragazzo (MI) ha perso un sacco di capelli di monitoraggio di questo uno giù.

È un po 'difficile vedere il valore di duck typing, fino a quando hai usato per un po'.Una volta che ci si abitua ad esso, vi renderete conto quanto di un carico fuori la vostra mente è di non avere a che fare con interfacce o di doversi preoccupare esattamente che tipo qualcosa.

IMHO, il vantaggio di duck typing diventa ingrandita quando si aderisce ad alcune convenzioni, come la denominazione delle variabili e i metodi in modo coerente.Prendendo l'esempio da Ken G, Mi pare di leggere meglio:

class SimpleResults {
    def mapOfListResults
    def total
    def categories
}

Diciamo che definire un contratto su qualche operazione denominata 'calculateRating(A,B) dove A e B aderire a un altro contratto.In pseudocodice, si leggerà:

Long calculateRating(A someObj, B, otherObj) {

   //some fake algorithm here:
   if(someObj.doStuff('foo') > otherObj.doStuff('bar')) return someObj.calcRating());
   else return otherObj.calcRating();

}

Se si desidera implementare questo in Java, entrambi A e B deve implementare un qualche tipo di interfaccia che legge qualcosa di simile a questo:

public interface MyService {
    public int doStuff(String input);
}

Inoltre, se si vuole generalizzare è contratto per il calcolo del rating (diciamo che hanno un altro algoritmo per la valutazione di calcolo), si hanno anche per creare un'interfaccia:

public long calculateRating(MyService A, MyServiceB);

Con il duck typing, è possibile eliminare il vostro interfacce e fare affidamento solo che in fase di runtime, entrambi A e B risponde correttamente al tuo doStuff() le chiamate.Non c'è bisogno di una specifica definizione del contratto.Questo può funzionare per voi, ma può anche funzionare contro di voi.

Il rovescio della medaglia è che dovete essere molto attenti in modo da garantire che il codice non si rompe quando ci sono altre persone che la cambia (vale a dire, l'altra persona deve essere consapevole di contratto implicito nel nome di metodo e argomenti).

Si noti che questo aggrava appositamente in Java, in cui la sintassi non è così terso come potrebbe essere (rispetto a Scala per fare un esempio).Un contro-esempio di questo è la Ascensore quadro, dove si dice che il SLOC conteggio del quadro è simile a Guide, ma il codice di test ha meno linee, perché non hanno bisogno di implementare il tipo di controlli nei test.

Ecco uno scenario in cui il duck typing salva lavoro.

Ecco una molto banale di classe

class BookFinder {
    def searchEngine

    def findBookByTitle(String title) {
         return searchEngine.find( [ "Title" : title ] ) 
    }
}

Ora per i test di unità:

void bookFinderTest() {
    // with Expando we can 'fake' any object at runtime.
    // alternatively you could write a MockSearchEngine class.
    def mockSearchEngine = new Expando()
    mockSearchEngine.find = {
        return new Book("Heart of Darkness","Joseph Conrad")
    }

    def bf = new BookFinder()
    bf.searchEngine = mockSearchEngine
    def book = bf.findBookByTitle("Heart of Darkness")
    assert(book.author == "Joseph Conrad"
}

Siamo stati in grado di sostituire un Expando per il motore di ricerca, a causa dell'assenza di un controllo di tipo statico.Con un controllo di tipo statico avremmo avuto per garantire che il motore di ricerca è un'interfaccia, o almeno di una classe astratta, e la creazione di un finto attuazione di esso.Che lavoro per la cpu, oppure è possibile utilizzare un sofisticato unico scopo beffardo quadro.Ma il duck typing è generica, e ci ha aiutato.

A causa di duck typing, la nostra unità di test in grado di fornire qualsiasi vecchio oggetto della dipendenza, così come lungo come si implementa i metodi che vengono chiamati.

A sottolineare - si può fare questo in un linguaggio tipizzato staticamente, con un uso attento delle interfacce e delle gerarchie di classi.Ma con il duck typing si può fare con meno di pensare e di meno tasti.

Questo è un vantaggio di duck typing.Ciò non significa che la tipizzazione dinamica è il diritto paradigma usare in tutte le situazioni.Nel mio Groovy progetti, mi piace tornare a Java in circostanze in cui mi sento che avvisi del compilatore sui tipi stanno andando per aiutare me.

Con, TDD + 100% di Copertura Codice + IDE strumenti per sempre eseguire i miei test, non mi sento un bisogno di tipizzazione statica più.Senza un forte tipi, la mia unità di test è diventato così facile (Basta usare le Mappe per la creazione di oggetti fittizi).Specialmente , quando si utilizzano farmaci Generici, si può vedere la differenza:

//Static typing 
Map<String,List<Class1<Class2>>> someMap = [:] as HashMap<String,List<Class1<Class2>>>

vs

//Dynamic typing
def someMap = [:]   

Non è che il duck typing è più produttivo rispetto a tipizzazione statica, per quanto vi è semplicemente diverso.Con tipizzazione statica è sempre preoccuparsi che i vostri dati è il tipo corretto e in Java si presenta attraverso la fusione per tipo giusto.Con il duck typing il tipo non importa fintanto che ha il metodo giusto, quindi è davvero solo elimina molti dei problemi di casting e le conversioni tra tipi.

@Chris Mazzo

Non è che la tipizzazione statica è più produttivo che il duck typing quanto è semplicemente diverso.Con il duck typing è sempre preoccuparsi che i vostri dati è il metodo giusto e in Javascript o Ruby si presenta attraverso un sacco di metodo di test.Con tipizzazione statica non importa quanto a lungo è l'interfaccia corretta, quindi è davvero solo elimina un sacco di fastidio di test e conversioni tra tipi.

Mi dispiace, ma ho dovuto farlo...

Il mio parere:

Dinamicamente tipizzati o di anatra linguaggi tipizzati sono giocattoli.Non è possibile ottenere Intellisense e si perde del tempo di compilazione (o modificare il tempo - quando si utilizza un VERO e proprio IDE, come VS, non spazzatura che la gente pensa sono Ide) validazione del codice.

Soggiorno chiaro di ogni lingua che non è staticamente tipizzato, tutto il resto è solo puro masochismo.

Per me, non sono terribilmente diverso se vedi linguaggi tipizzati in modo dinamico semplicemente come una forma di tipizzazione statica, dove tutto eredita da un sufficientemente classe di base astratta.

I problemi sorgono quando, come molti hanno sottolineato, si avvia sempre di strano in questo.Qualcuno ha sottolineato una funzione che restituisce un singolo oggetto, una raccolta o un valore null.La funzione di restituire un tipo specifico, non di più.L'utilizzo di più funzioni per singolo vs collezione.

Che cosa si riduce a è che chiunque può scrivere male il codice.La tipizzazione statica è un grande dispositivo di sicurezza, ma a volte il casco si mette in mezzo quando si vuole sentire il vento nei capelli.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top