Při čtení některých blogů se člověk dozví, že (s troškou nadsázky 🙂 anotace jsou něco, co by se nemělo používat příliš často, protože to porušuje vrstvení aplikace. Chtěl bych k této diskusi přispět také svou troškou do mlýna.
Když se bavíme o anotacích neměli bychom zapomenout zmínit jednu zvláštní anotaci, protože v Javě existovala i v dobách kdy Java anotace jako takové neznala. Ano myslím tím synchronized ve formě:
public synchronized void pracuj() { }
Možná si řeknete „tohle přece nejsou anotace“, ale dle Wikipedie jsou (i když se nejedná o anotaci dle JSR-175).
Nyní si tedy můžete říci ono „anotace porušuje vrstvy“ tím, že říká jak je daná metoda implementována navenek. Ona říká, že tato metoda je synchronizována.
A přesto to nikomu nedělá potíže. Proč? To si povíme dále.
Anotace mohou být rozděleny (i když asi zjednodušeně) na dva typy:
- programovací
- integrační
Programovací anotace jsou takové, které ovlivňují jak je daná aplikace (nebo její část) napsaná. Tj. místo iterativního programování je použito deklarativní. Pokud nechceme tyto anotace zveřejňovat (jedná se přeci o implementaci), můžeme je skrýt stejným způsobem jako skrýváme vnitřní metody pomocí rozhraní (i když tyto metody musí být z nějakého důvodu veřejné). Pokud tedy v době instalace chcete měnit tyto anotace, měníte vlastně samotný program a tudíž musíte vše znovu přeložit a otestovat.
Na druhou stranu integrační anotace definují, jakým způsobem je aplikace navázána na okolí (kde je JTA, kde je databáze, kde vezmu Mail Session, jak ověřovat uživatele, …). Do této skupiny patří i integrace knihoven a nástrojů třetích stran. Tato konfigurace by měla být v externích souborech (jako to umožňuje např. JPA), aby byla instalace jednodušší a obvykle bývá pro každou instalaci trošku odlišná. Někdy je ovšem vhodné definovat integrační konfiguraci jako anotace, abychom nastavili rozumné výchozí hodnoty a zjednodušili tak konfigurační soubory (např. mapování na tabulky a sloupce v databázi).
Hranice, kde je vhodné definovat integrační výchozí hodnoty jako anotace a kde je definovat v konfiguračních souborech, aby se snadno měnili je velmi tenká a bude spíše záviset na intuici, zkušenosti a typu projektu.
Stejně tak tenká je i hranice mezi integrační a programovací anotací – pro někoho je název sloupce a jeho typ integrační a pro někoho jen programovací.
To je moc pekne, ale napriklad Hibernate, se mi nepodarilo donutit k tomu, aby pouzival jak annotace tak xml formu. Abych mohl mit „defaultni“ nastaveni a pak konkretni (ktere by bylo v XML). Je tam moznost bud a nebo a pak si myslim, ze lepsi volbou je XML.
Já bych nebyl tak zdrženlivý ohledně anotací před Javou 5 — za anotace by se dala považovat i klíčová slova final, volatile, klidně i public/protected/private, a navíc ještě každý marker interface (třeba Serializable).
Chci říct: jsem rád, že v Javě existuje obecný způsob zápisu metadat, který se drží principu lokality — i když má svoje nedostatky.
Petre, moc to nechapu, muzes dat v sanc jiny typ programove anotace nez „synchornized“? Ja podle tvoji definice pouzivam zrejme jenom anotace integracni. Anotace jsou skutecne peklo pokud vyjadruji metadata, ktera by bylo snazsi a prehlednejsi zapsat v XML viz brutalni pouziti v ORM nastrojich (ted myslim slozite konstrukty jako vlastni property type apod.).
pokud vim tak se to michat muze, alespon pri pouziti se springem
http://forum.springframework.org/showthread.php?t=28126
Když budu mít design-by-contract framework, jenž se bude zapisovat pomocí anotací, pak jsou to anotace programové. Tomu rozumím, chápu význam.
Když mám anotace jako v Tapestry IoC, tak tomu rozumím a je to dobré.
Ale Hibernate a anotace, to je nečitelné a zvěrstvo. Zlaté XML …
dagi: „synchronized“ je jen ukázka toho, že anotace jsou zde již dlouho. Ukázkou programátorské anotace je např. u Seamu „@Name()“ nebo „@Scope()“ případně „@Transactional“ – potřebuju transakci, abych mohl fungovat.
jira: souhlasím, že Hibernate (resp. JPA) anotace můžou být celkem ošklivé. Pokud ale člověk nechá všechno výchozí tak to není tak hrozné 🙂
Jedna věc je jak to vypadá a druhá, zda to dává smysl … a smysl to nedává, protože model nemá co řešit nějakou persistenci. To je např. problém, který mám se Seamem, samá anotace, řeší se tím kde co, co zdánlivě nesouvisí s danou vrstvou, ve které se objekt pohybuje.
Pohybuju se ve světě aplikací, které vyvíjíme třeba i 5, 10 let a tam si takovoudle sebevraždu nemůžem dovolit. View už jsme měnili 2x, persistentní část 2x, kdybych pokaždé menil model bylo by to neúnosné.
ad JPA/Hibernate anotacie: podla mna je hlavnym meradlom pouzitelnost. ak v tom modeli nebude tych anotacii tak vela, ze to zacne byt neprehladne, tak je to podla mna fajn vec. a co sa tyka toho, ze to so samotnym modelom vobec nesuvisi: no a co? vsak tie anotacie vam nic z kodu samotnej triedy neovplyvnia, su uplne nezavisle a 100% neinvazivne. podla mna su anotacie uplne skvela vec (hlavne ked si spomeniem na tie sialene deployment deskriptory v j2ee 1.4), ale suhlasim, ze Seam to s nimi tak trochu prehana…
Asi budu za rebela, ale myslim, ze synchronized neni anotace. Klicove slovo synchronized v hlavicce metody je jen nahradou za synchronized(this) { … } v tele metody. A toto synchronized anotace byt nemuze, protoze v Jave lze anotovat jen anotaci, konstruktor, atribut, lokalni promennou, metodu, balik, parametr a typ (viz ElementType).
Ve Wikipedii jsem zminku o tom, ze by synchronized bylo anotaci nenasel. Uvedeno je jen transient.
Dnes se všichni snaží mít aplikace ve stylu POJO, což je určitě správný přístup. Ale právě anotace dost často objekty resp. třídy degradují, že už se o žádné POJO nejedná, tedy pak je narušena nezávislost, hůře se to testuje, zhoršena flexibilita atd.
A POJO with annotations is not Plain
Annotations in POJO – a boon or a curse?
When is a POJO not a POJO? …. when it’s an APOJO.
Ahoj,
nevím, jestli jsou anotace peklo, ale myslím si, že kdokoliv nový, kdo se nyní začne učit Javu, tak pro něj Java bez anotací nebude Javou.
Ohledně dělení anotací na integrační a programové bych se možná ještě přimlouval za bezpečnostní anotace (security anotace jak jsou třeba v JSR-250). Ale je pravda, že jsou možná integrační (dle definice výše), protože by mohly být specifikovány i mimo kód. Na druhou stranu můžou být i programové, protože přímo ovlivňují jak je daná aplikace napsaná, tj. můžeme implementaci ověřování autorizace zahrnout přímo do kódu, protože právě ze sémantiky dané metody víme, které role ji mohou využít. Abych se přiznal, tak jsem z toho dělení trošku jelen 🙂
Btw. nebyla by špatná myšlenka udělat trošku v anotacích pořádek, tj. mít pohromadě u každého frameworku i nějaký pěkný (Java?)Doc, který by ukázal, které anotace a jak lze použít. A pokud se bavíme o anotacích jako deklarativním způsobu programování tak mít tuto dokumentaci odděleně od obyčejného JavaDocu obsahujícího výkonný kód frameworku. Ale to bych si asi přál už hodně 😉
to Petr: je otazka jestli tebou uvadene priklady nejsou anotace integracni. Ja myslim, ze jsou, protoze integruji tvuj kod se Seamem, to je muj pohled. Programova anotace to bude, kdyz ve svem kode pouzijes vlastni anotaci, kterou budes vyhodnocovat v jine casti kodu.
to Zdenda> souhlasim, ze to anotace v pravem slova smyslu neni, ale klidne by mohla byt.
@Synchronized
public void doSomething() {
…
}
ja v tom nevidim nejmensi problem.
to Dagi> no to by potom klidne mohla byt anotaci i:
@public
void method() { .. }
zas bych to neprehanel 🙂
Jsou anotace videt v JavaDoc …