Duck typing

Da Wikipedia, l'enciclopedia libera.
Jump to navigation Jump to search

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 solo agli 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 wikitesto]

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 wikitesto]

Implementazioni[modifica | modifica wikitesto]

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 wikitesto]

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 wikitesto]

<?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