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. Trait se velmi 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í, ale 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. Traity poskytují jednoduchý způsob jak vytvořit třídy, které znovupoužívají chování jiné softwarové komponenty.
Traity jsou něco mezi rozhraním a mixinem: rozhraní je tvořeno pouze názvy metod, zatímco trait obsahuje kompletní definice metod, na druhé straně mixin obsahuje (kromě definic metod) také stav, za pomoci proměnných, což traity většinou nemívají.
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í: i.e. atributy, metody. Trait je používán třídou sloučením kolekcí extra metod poskytovaných s určitým mechanismem řešícím konflikty názvů.
Tedy objekt definován jako trait je 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 ve třídě použita. Musí tedy sám vyřešit „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í, kde konflikty jmen jsou automaticky řešeny pravidly proměnných.
Zatímco mixiny mohou být použity pouze za pomocí dědičných operací, traity poskytují mnohem širší výběr operací. Například: [3][4]
- Symetrický součet: operace, která spojí dva rozdělené traity pro vytvoření traitu nového.
- Přepsání (nebo asymetrický součet): operace, která vytvoří nový trait přidáním dalších metod, případně přepsání 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í).
Trait se liší od rozhraní tím, že poskytuje implementaci metod, nikoli pouze signaturu metod.
Podporované jazyky
Traity pocházejí z programovacího jazyka Self[5] a jsou podporovány následujícími programovacími jazyky:
- Fortress: Kde zároveň zastupují 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 – Fungují jako role (Traity a Mixiny)
- Squeak Smalltalk
- D: použitím __traits language extension[6] a std.traits modulu[7] 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 interface a typů. D také umožňuje explicitní čištění od členských metod a proměnných, včetně forwardingu do vícero členských tříd.[8]
- Pharo
- PHP 5.4[9]
- Ruby: Pro implementaci traitů je možno použít moduly.[10]
- Rust
- Lasso[11]
- Scala[12] The busy Java developer's guide to Scala: Of traits and behaviors[13]
- Python: použitím balíčku Traits[14]
- Groovy: Od verze 2.3[15]
Traity pro Smalltalk programovací jazyk byly původně vytvořeny Software Composition Group, University of Bern.[16] 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 a freezable traitů pro umožnění stavů uvnitř traitů, což nebylo umožněno v prvních definicích.[17]
Koncept byl aplikován jako knihovny do hlavních programovacích jazyků, jako C++, PHP a Javascript.[18]
Traity mají následující vlastnosti
- Poskytují sadu metod, které implementují chování.
- Vyžadují sadu metod, které parametrizují poskytované chování.
Mohou být složeny
- 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.[19] 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 jsou do určité míry podobné traitům. Racket podporuje traity jako knihovnu a používá makra, struktury a first-class třídy k implementaci.
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í 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ě.
Traity fungují odlišně v PHP. Od verze 5.4.0,[9] PHP umožňuje uživatelům určit šablonu, která poskytuje možnost dědit z více než jedné (trait-)třídy, jako pseudovícenásobná dědičnost. Traity v PHP nejsou tolik dynamické jako v C++ v používání datových typů.
Příklady
PHP
Od verze 5.4.0 PHP umožňuje traity. Tento příklad používá jednu šablonovou třídu (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)
- 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)
- 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
- http://web.cecs.pdx.edu/~black/publications/TR_CSE_02-012.pdf
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