2009-07-03 14 views
28

Ho appena sentito parlare della digitazione anatra e ho letto il numero Wikipedia article a riguardo, ma sto facendo fatica a tradurre gli esempi in Java, il che aiuterebbe davvero la mia comprensione.Che cos'è un esempio di digitazione anatra in Java?

Qualcuno sarebbe in grado di dare un chiaro esempio di digitazione anatra in Java e come potrei usarlo?

+1

Sì, ma gli altri potrebbero non hanno letto quell'articolo. –

risposta

38

Java non è adatto alla digitazione anatra. Il modo in cui si può scegliere di farlo è la riflessione:

public void doSomething(Object obj) throws Exception { 

    obj.getClass().getMethod("getName", new Class<?>[] {}).invoke(obj); 
} 

ma vorrei sostenere farlo in un linguaggio dinamico, come Groovy, dove ha più senso:

class Duck { 
    quack() { println "I am a Duck" } 
} 

class Frog { 
    quack() { println "I am a Frog" } 
} 

quackers = [ new Duck(), new Frog() ] 
for (q in quackers) { 
    q.quack() 
} 

Reference

+2

++ Bel esempio di anatra, mi piace il nuovo metodo di creazione dell'oggetto. – Secko

+3

Attraversa un'elegante libreria chiamata "duckapter" se scorri lungo il percorso di riflessione Java: http://code.google.com/p/duckapter/ – penfold

+0

Voglio sapere perché è difficile o impossibile implementare la digitazione anatra in java o qualsiasi linguaggio di tipo statico? Le persone dicono che possiamo usare l'interfaccia. Plz spiega. – kamal

5

check this library:

interface MyInterface { 
    void foo(); 
    int bar(int x, int y); 
    int baz(int x); 
} 

public class Delegate { 
    public int bar() { 
     return 42; 
    } 
} 

DuckPrxy duckProxy = new DuckPrxyImpl(); 
MyInterface prxy = duckProxy.makeProxy(MyInterface.class, new Delegate()); 
prxy.bar(2, 3); // Will return 42. 

Con una battitura un'interfaccia anatra è semplice utilizzando un Dynamic Proxy, si deve corrispondere il nome del metodo e il tipo di ritorno.

+1

Va notato che questo non è strettamente anatra digitando ma usando i proxy dinamici (che è ciò che fa) è il più vicino possibile a Java. – cletus

4

Java non implementa la digitazione anatra.

1

La digitazione in Java è nominale - la compatibilità si basa sui nomi. Se hai bisogno di un esempio su come la tipizzazione delle anatre (o la tipizzazione strutturale) possa apparire in Java, guarda questa pagina: http://whiteoak.sourceforge.net/#Examples che fornisce esempi per il programma scritto in Whiteoak: un linguaggio compatibile con Java che supporta anche la tipizzazione strutturale.

1

In genere, la digitazione anatra viene utilizzata con lingue tipizzate dinamicamente. Verificheresti in fase di esecuzione dell'esistenza di metodi o proprietà necessari per soddisfare le tue esigenze, indipendentemente dalle gerarchie di ereditarietà.

Diverso dall'utilizzo del riflesso, che risulterebbe brutto, il più vicino possibile è quello di utilizzare interfacce minime che corrispondono ai criteri di ciò che sarebbe necessario per la digitazione anatra. Questo blog post fa un buon lavoro descrivendo il concetto. Perde molta della semplicità della digitazione anatra in python o ruby ​​o javascript, ma in realtà è una pratica abbastanza buona in Java se stai cercando un alto livello di riusabilità.

10

Vedere this blog post. Fornisce un resoconto molto dettagliato su come utilizzare i proxy dinamici per implementare la digitazione anatra in Java.

In sintesi:

  • creare un'interfaccia che rappresenta i metodi che si desidera utilizzare tramite anatra digitando
  • creare un proxy dinamico che utilizza questa interfaccia e un oggetto applicazione che richiama metodi dell'interfaccia sul oggetto sottostante per riflessione (assumendo che la partita firme)
+0

È un buon articolo - pensi di poter riassumere la soluzione qui fornita nel caso in cui qualcosa accada? – Shog9

+1

Aggiunta una spiegazione molto semplice. –

+0

La digitazione di anatre usando * proxy dinamici * può essere implementata anche in una quantità minore di codice - vedere [questo elenco] (https://gist.github.com/unix-junkie/b9481245904892f07780). Basta notare che l'ordine in cui le interfacce implementate da un 'Proxy' sono elencate: se non è corretto, riceverai un' java.lang.IllegalArgumentException: object non è un'istanza di dichiarare la classe'. – Bass

3

con Java 8, si dispone di 2 modi:

n º1: se avete solo bisogno di un metodo, utilizzare lambda

static interface Action { public int act(); } 

public int forEachAct(List<Action> actionlist) { 
    int total = 0; 
    for (Action a : actionList) 
     total += a.act(); 
} 

public void example() { 
    List<Action> actionList = new ArrayList<>(); 
    String example = "example"; 
    actionList.add(example::length); 
    forEachAct(actionList); 
} 

nº2: Utilizzare le classi anonime (non molto prestazioni-saggio, ma in alcune parti non critiche si può fare)

static interface Action { 
    public int act(); 
    public String describe(); 
} 

public void example() { 
    List<Action> actionList = new ArrayList<>(); 
    String example = "example"; 

    actionList.add(new Action(){ 
     public int act() { return example.length(); } 
     public String describe() { return "Action: " + example; } 
    }); 
} 
0

Nizza definizione:

Gli oggetti sono polimorfici senza essere correlati da una classe base comune o un'interfaccia.

Reference

0

ho scritto una classe di utilità per creare dinamicamente decoratori per un oggetto. Si potrebbe usare per la digitazione anatra: https://gist.github.com/stijnvanbael/5965616

Esempio:

interface Quacking { 
    void quack(); 
} 

class Duck { 
    public void quack() { System.out.println("Quack!"); } 
} 

class Frog { 
    public void quack() { System.out.println("Ribbip!"); } 
} 

Quacking duck = Extenter.extend(new Duck()).as(Quacking.class); 
Quacking frog = Extenter.extend(new Frog()).as(Quacking.class); 

duck.quack(); 
frog.quack(); 

uscita:

Quack! 
Ribbip! 
Problemi correlati