Duck typing

Da Wikipedia, l'enciclopedia libera.

Nei linguaggi di programmazione object oriented, il duck typing si riferisce ad uno stile di tipizzazione dinamica dove la semantica di un oggetto è determinata dall'insieme corrente dei suoi metodi e delle sue proprietà anziché dal fatto di estendere una particolare classe o implementare una specifica interfaccia. Il nome del concetto si riferisce al duck test attribuito a James Whitcomb Riley (vedi storia sotto) che può essere formulato come segue:

"Quando io vedo un uccello che cammina come un'anatra,nuota come un'anatra e starnazza come un'anatra, io chiamo quell'uccello "anatra" "

Nel duck typing si è interessati a solo gli aspetti di un oggetto che sono usati invece che al tipo dell'oggetto stesso. Per esempio in un linguaggio non-duck-tipizzato si può creare una funzione che prende un oggetto di tipo Anatra(duck) e chiama i metodi starnazza(quack) e cammina(walk) di quell'oggetto. In un linguaggio duck-tipizzato la funzione equivalente avrebbe preso un oggetto di qualunque tipo e chiamato i metodi walk e quack di quell'oggetto. Se quindi l'oggetto non ha i metodi che chiamiamo la funzione segnala un errore di run-time. È quest'azione di ogni oggetto avente i corretti metodi quack e walk che vengono accettati dalla funzione che evoca la citazione e quindi il nome di questa forma di tipizzazione.

Il duck typing è avvantaggiato abitualmente dal non dover testare per il tipo di argomento in metodi e corpi di funzione, basandosi sulla documentazione, codice pulito e prove per assicurare un uso corretto. Gli utenti che provengono da linguaggi tipizzati staticamente sono abitualmente tentati di aggiungere questo controllo statico dei tipi (prima del run-time), reprimendo i benefici e la flessibilità del duck typing e vincolando il dinamismo del linguaggio.

Esempi del concetto[modifica | modifica sorgente]

Considera il seguente pseudocodice per un linguaggio duck tipizzato :

function calcola(a, b, c) => return (a+b)*c

esempio1 = calcola (1, 2, 3)
esempio2 = calcola ([1, 2, 3], [4, 5, 6], 2)
esempio3 = calcola ('mele ', 'e arance, ', 3)

print to_string esempio1
print to_string esempio2
print to_string esempio3

In questo esempio ogni volta che viene chiamata la funziona calcola potrebbero essere usati oggetti non correlati fra loro (numeri,liste e stringhe). Fino a che l'oggetto supporta i metodi "+" e "*" l'operazione avrà successo. Se tradotto in ruby o python, per esempio, il risultato del codice sarà:

9
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
mele e arance, mele e arance, mele e arance,

Inoltre il duck typing permette il polimorfismo senza ereditarietà. L'unico requisito che la funzione calcola deve avere nelle sue variabili è avere i metodi "+" e "*". Il duck test può essere visto nell'esempio seguente (in python). Dal punto di vista della funzione in_the_forest, l'oggetto è di tipo duck:

class Duck(object):
    def quack(self): 
        print "Quaaaaaack!"
    def feathers(self): 
        print "The duck has white and gray feathers."
 
class Person(object):
    def quack(self):
        print "The person imitates a duck."
    def feathers(self): 
        print "The person takes a feather from the ground and shows it."
 
def in_the_forest(duck):
    duck.quack()
    duck.feathers()
 
def game():
    donald = Duck()
    john = Person()
    in_the_forest(donald)
    in_the_forest(john) 
 
game()

Il risultato sarà:

Quaaaaaak
The duck has white and gray feathers.
The person imitates a duck.
The person takes a feather from the ground and shows it.

Duck Typing in linguaggi tipizzati staticamente[modifica | modifica sorgente]

Implementazioni[modifica | modifica sorgente]

Si può avere un comportamento simile a quello di un linguaggio duck-tipizzato anche con linguaggi tipizzati.
I seguenti esempi ricalcano il comportamento del precedente scritto in Python.

Javascript[modifica | modifica sorgente]

var Duck = function(){
    this.quack = function(){alert('Quaaaaaack!');};
    this.feathers = function(){alert('The duck has white and gray feathers.');};
    return this;
};
 
var Person = function(){
    this.quack = function(){alert('The person imitates a duck.');};
    this.feathers = function(){alert('The person takes a feather from the ground and shows it.');};
    this.name = function(){alert('John Smith');};
    return this;
};
 
var in_the_forest = function(duck){
    duck.quack();
    duck.feathers();
};
 
var game = function(){
    var donald = new Duck;
    var john = new Person;
    in_the_forest(donald);
    in_the_forest(john);
};
 
game();


PHP[modifica | modifica sorgente]

<?php
class Duck{
        function quack(){ echo "Quack\n";}
        function fly(){ echo "Flap, Flap\n";}
}
class Person{
        function __construct($name){$this->name=$name;}
        function quack(){echo "{$this->name} walks in the forest and imitates ducks to draw them\n";}
        function fly(){ echo "{$this->name} takes an airplane\n";}
}
 
function QuackAndFly($obj){$obj->quack(); $obj->fly();}
 
QuackAndFly(new Duck());
QuackAndFly(new Person("Jules Verne"));
?>


informatica Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica