Duck-typing
Duck-typing je způsob dynamického typování, kdy posuzujeme objekt nikoli z hlediska jím deklarovaných předků nebo implementovaných rozhraní, ale jen na základě jeho metod. Původ systému je přisuzován větě Jamese Whitcomba Rileyho:
- "Pokud vidím ptáka, který chodí jako kachna, plave jako kachna a kváká jako kachna, tak o tomto ptáku tvrdím, že je to kachna."
Obsah |
Upřesnění definice [editovat]
Pravdou je, že současná implementace duck-typingu tak, jak byla popsána v prvním odstavci se od této idey poněkud liší. Při duck-typingu nezkoumáme, zda objekt "kváká jako kachna", ale zajímá nás jen, zda implementuje metodu kvákni();. Po úpravě tedy tvrdíme, že:
- "Pokud vidím něco, co umí chodit, plavat a kvákat, pak věřím tomu, že vidím kachnu."
Objekt rozpoznaný pomocí duck-typingu se tedy chová stejně, jako objekt implementující rozhraní
public interface IDuck
{
/**
* Walk like a duck.
*/
public void walk();
/**
* Swim like a duck.
*/
public void swim();
/**
* Quack like a duck.
*/
public void quack();
}
s tím rozdílem, že při duck-typingu nemusíme rozhraní implementovat - stačí nám implementace zmíněných metod.
Problémy duck-typingu [editovat]
Jsou způsobené právě zmíněnou vlastností, kdy zkoumáme jen rozhraní (název a datové typy metod) bez ohledu na kontrakt, předky nebo implementovaná rozhraní. Mezi kachny se tak může dostat nejen myslivec, který se rozhodl přihlásit k rozhraní IDuck (pravděpodobně z důvodu vyšší úspěšnosti lovu), ale i dítě, které má v kapse vábničku na kachny, které se kachen bojí.
Z tohoto důvodu k duck-typingu přistupujeme zejména v případech, kdy máme k dispozici známou množinu objektů a nehrozí dezinterpretace. Pokud bychom pomocí duck-typingu například hledali Hodiny jako objekty implementující metodu
public void natáhni();
mohli bychom se dočkat nepříjemných překvapení, pokud by mezi dostupnými třídami existovala třída Facka.
Duckapter [editovat]
Duckapter je knihovna vytvořená Vladimírem Oraným, která přináší duck-typing do programovacího jazyka Java, kde jinak nelze použít duck-typing jinak než pomocí reflexe.
Knihovna vychází z již zmíněné podobnosti s implementací rozhraní. Pokud bychom chtěli zkoumat, zda instance kachna třídy Kachna je dle duck-typingu kachnou (i když se nehlásí k implementaci rozhraní IDuck), pak bychom volali:
boolean isDuck = Duck.test(kachna, IDuck.class);
a pro použití například:
if (Duck.test(kachna, IDuck.class) {
IDuck theDuck = Duck.type(kachna, IDuck.class);
System.out.println(theDuck.quack());
}
Groovy [editovat]
Mnohem jednodušeji než "čistá" Java přistupuje k duck-typingu jazyk Groovy
class Duck
{
def walk() { println "I'm a Duck, I can walk..." }
def swim() { println "I'm a Duck, I can swim..." }
def quack() { println "I'm a Duck, I can quack" }
}
class Person
{
def walk() { println "I'm a Person, I can walk..." }
def swim() { println "I'm a Person, I can swim..." }
def talk() { println "I'm a Person, I can talk..." }
}
def d = new Duck()
def p = new Person()
d.walk() // Ok, duck has walk() method
d.swim() // Ok, duck has swim() method
d.quack() // Ok, duck has quack() method
p.walk() // Ok, person has walk() method
p.swim() // Ok, person has swim() method
p.quack() // Runtime error, no quack() method
Literatura [editovat]
- Tate, A. B. Seven Languages in Seven Weeks, 1.st ed.; Pragmatic Programmers, LLC.: USA, 2010.
- Oraný, V. Automatické vyhodnocování studentských úloh. diplomová práce, VŠE v Praze, 4. května 2010.