Trait
V programování je trait způsob návrhu použitý v objektově orientovaném programování. Trait reprezentuje kolekci metod, které mohou být použity pro rozšíření funkcionalit tříd. Velmi se podobá třídě vytvořené pouze z konkrétních metod, použitých pro rozšíření jiné třídy obdobným způsobem, jako je vícenásobné dědění. Trait však klade důraz na řešení konfliktů názvů za použití podpory samotného programovacího jazyka při následném propojování.
Traity poskytují „jednoduchý konceptuální model pro strukturu objektově orientovaného programování“[1][2] podobný mixinům. Také umožňují jednoduše vytvořit třídy, které opětovně používají chování jiné softwarové komponenty.
Charakteristika
Rozlišení mezi traitem, rozhraním a mixinem
Traity se podobají jak rozhraní, tak mixinu. Zatímco rozhraní je tvořeno pouze názvy metod, trait obsahuje kompletní definice metod. Od rozhraní se liší také tím, že poskytuje implementaci metod, nikoli pouze jejich signaturu. Rozhraní je používáno třídou, která implementuje jeho metody. Mixin je používán třídou promícháním sebe samého a všech jeho vlastností (atributy a metody). Trait je používán třídou sloučením kolekcí extra metod poskytovaných s určitým mechanismem, který řeší konflikty názvů. Mixin obsahuje kromě definic metod také stav za pomoci proměnných, což u traitu obvykle nenalezneme.
Objekt definovaný jako trait je tedy vytvořen jako sloučenina metod, které mohou být použity jinými třídami, bez nutnosti použití vícenásobného dědění. V případě kolize jmen, kdy jeden nebo více traitů mají být použity třídou obsahující metodu stejného jména, musí programátor explicitně tento konflikt vyřešit definováním, která z metod bude v této třídě použita. Musí tedy sám vyřešit tzv. „diamantový problém“ vícenásobného dědění. Toto je rozdílné od jiných skládacích metod v objektově orientovaném programování, u nichž jsou konflikty jmen automaticky řešeny pomocí pravidel proměnných.
Zatímco mixiny mohou být použity pouze na základě dědičných operací, traity poskytují mnohem širší výběr operací:[3][4]
- Symetrický součet: operace, která spojí dva rozdělené traity pro vytvoření traitu nového.
- Přepsání (asymetrický součet): operace, která vytvoří nový trait přidáním dalších metod, případně přepsáním již existujících metod existujícího traitu.
- Alias: operace, která vytvoří nový trait přidáním nového jména pro existující metodu.
- Vyloučení: operace, která vytvoří nový trait odstraněním metody z existujícího traitu. V kombinaci s operací alias získáme operaci mělké přejmenování.
Vlastnosti traitů
- poskytují sadu metod, které implementují chování
- vyžadují sadu metod, které parametrizují poskytované chování
- trait kompozice je symetrická a konfliktní metody jsou vyloučeny z kompozice
- mohou být vnořeny, nicméně vnoření nemá žádnou sémantiku pro třídy
Vnořené traity jsou ekvivalentní flattened traitům.[5] Abstraktní třídy jako mixiny ve vícenásobné dědičnosti programovacího jazyka Curl povolují implementaci metody a tudíž představují traity jiného jména. Modul mixiny v Ruby je do určité míry podobný traitům. Racket podporuje traity jako knihovnu a pro implementaci používá makra, struktury a first-class třídy.
Podporované jazyky
Traity pocházejí z programovacího jazyka Self[6] a jsou podporovány následujícími programovacími jazyky:
- Fortress: zastupují zároveň roli typů.
- Perl 5: implementováno díky Moose modulu, nazývají se „rolemi“.
- Perl 6: nazývají se rolemi a jsou součástí jazyka.
- JavaScript Delegation:[ujasnit] fungují jako role (Traity a Mixiny)
- Squeak Smalltalk
- D: použitím __traits language extension[7] a std.traits modulu[8] pomocných šablon pro kompilaci časových traitů. Dostupné v D 2 od verze 2.003, s pozdější přidanou funkcionalitou. Dohromady s dalšími vlastnostmi jazyka (templety a mixiny) umožňují flexibilní automatické generování metod založených na struktuře rozhraní a typů. Jazyk D také umožňuje explicitní čištění od členských metod a proměnných, včetně přesměrování do vícero členských tříd.[9]
- Pharo
- PHP 5.4[10]
- Ruby: pro implementaci traitů je možno použít moduly.[11]
- Rust
- Lasso[12]
- Scala[13][14]
- Python: použitím balíčku Traits[15]
- Groovy: součástí od verze 2.3[16]
Traity pro programovací jazyk Smalltalk byly původně vytvořeny skupinou Software Composition Group na Bernské univerzitě.[17] AmbientTalk kombinuje vlastnosti ze Self traitů - objektově orientovaná vícenásobná dědičnost a Smalltalk Squeak traity, vyžadující explicitní složení traitů programátorem. AmbientTalk staví na výzkumu v oblasti stateful[ujasnit] a freezable[ujasnit] traitů pro umožnění stavů uvnitř traitů, což v prvních definicích nebylo umožněno.[18]
Koncept byl aplikován jako knihovny do hlavních programovacích jazyků: C++, PHP a Javascript.[19]
Implementace
V počítačovém programování trait třída je třída šablona použitá k asociaci stavu a/nebo chování ke compile-time entitě, typicky datový typ nebo konstanta, bez modifikace existující entity. V C++ a PHP je běžně dosahováno definováním primární šablony třídy a vytvořením explicitních nebo částečných specializací pro relevantní typy.
Je použitá v Standard Template Library a v Standardní knihovna jazyka C pro podporu generických container třídách. Technika je značně používaná v Boost TypeTraits knihovně.
V PHP fungují traity v různých verzích odlišně. Od verze 5.4.0[10] je umožňěno uživatelům určit šablonu, která poskytuje možnost dědit z více než jedné (trait-)třídy jako pseudo-vícenásobná dědičnost. Traity v PHP nejsou tolik dynamické jako v C++ při používání datových typů.
Příklady
PHP
V následujícím příkladu je použita jedna šablonová třída (trait) pro rozšíření jiné třídy:
// The template
trait TSingleton
{
private static $_instance = null;
public static function getInstance()
{
if (null === self::$_instance)
{
self::$_instance = new self();
}
return self::$_instance;
}
}
class FrontController
{
use TSingleton;
}
// Může být použito v již rozšířených třídách
class WebSite extends SomeClass
{
use TSingleton;
}
To dává uživateli možnost simulovat aspekty z vícenásobné dědičnosti:
trait TBounding
{
public $x, $y, $width, $height;
}
trait TMoveable
{
public function moveTo($x, $y)
{
// ...
}
}
trait TResizeable
{
public function resize($newWidth, $newHeight)
{
// ...
}
}
class Rectangle
{
use TBounding, TMoveable, TResizeable;
public function fillColor($color)
{
// ...
}
}
Odkazy
Reference
- ↑ Nathanael Schärli, Stéphane Ducasse, Oscar Nierstrasz, Andrew P. Black. Traits: Composable Units of Behaviour. Proceedings of the European Conference on Object-Oriented Programming (ECOOP). Lecture Notes in Computer Science, Volume 2743, Springer-Verlag, 2003, pp. 248-274
- ↑ Stéphane Ducasse, Oscar Nierstrasz, Nathanael Schärli, Roel Wuyts, Andrew P. Black: Traits: A mechanism for fine-grained reuse. ACM Trans. Program. Lang. Syst. 28(2): 331-388 (2006)
- ↑ FISHER, Kathleen; REPPY, John. Statically typed traits [online]. University of Chicago, 2003 [cit. 2015-05-14]. Dostupné v archivu pořízeném dne 2014-04-28. (anglicky)
- ↑ FISHER, Kathleen; REPPY, John. A typed calculus of traits [online]. University of Chicago, 2003. Dostupné online. (anglicky)
- ↑ http://web.cecs.pdx.edu/~black/publications/TR_CSE_02-012.pdf
- ↑ G. Curry, L. Baer, D. Lipkie, and B. Lee. Traits: An approach to multiple-inheritance subclassing. In SIGOA conference on Office Information Systems, pages 1–9, Philadelphia, Pennsylvania, USA, 1982. ACM Press
- ↑ Traits [online]. Dostupné online. (anglicky)
- ↑ std.traits [online]. Dostupné online. (anglicky)
- ↑ Classes [online]. Dostupné online. (anglicky)
- ↑ a b MARR, Stefan. Request for Comments: Horizontal Reuse for PHP [online]. The PHP Group [cit. 2011-01-31]. Dostupné online. (anglicky)
- ↑ David. Ruby Naseby [online]. Dostupné online. (anglicky)
- ↑ Traits — LassoGuide 9.2 documentation [online]. Dostupné online. (anglicky)
- ↑ A Tour of Scala: Traits [online]. Dostupné online. (anglicky)
- ↑ The busy Java developer's guide to Scala: Of traits and behaviors [online]. Dostupné online. (anglicky)
- ↑ Enthought Traits [online]. [cit. 2015-05-14]. Dostupné v archivu pořízeném dne 2015-05-04. (anglicky) (NOTE: Enthought Traits are not the same kind of Traits as described in this article)
- ↑ Codehaus Groovy Community. Groovy - Home [online]. [cit. 2015-05-14]. Dostupné v archivu pořízeném dne 2014-03-02. (anglicky)
- ↑ Software Composition Group. SCG: SCG Bibliography [online]. Dostupné online. (anglicky)
- ↑ Adding State and Visibility Control to Traits Using Lexical Nesting. Genoa Proceedings of the 23rd European Conference on ECOOP 2009 --- Object-Oriented Programming table of contents. Editor: Sophia Drossopoulou Department of Computing, Imperial College London, London, UK SW7 2AZ. Pages 220 - 243. Publisher Springer-Verlag Berlin, Heidelberg ©2009 ISBN 978-3-642-03012-3 doi>10.1007/978-3-642-03013-0_11. Appears in LNCS: Lecture Notes In Computer Science.
- ↑ Robust Trait Composition for Javascript. Tom Van Cutsem, Mark S. Miller
Související články
Externí odkazy
- Generic Programming Techniques from Boost
- iterator_traits<Iterator> from SGI
- Traits: a new and useful template technique, Nathan C. Myers, C++ Report, June 1995 issue
- Traits - PHP Documentation
- Traits
- traits.js - Traits for JavaScript
- CocktailJS - ANNOTATIONS. TRAITS. TALENTS., April 2013
- The many talents of JavaScript for generalizing Role Oriented Programming approaches like Traits and Mixins, April 11, 2014