Platforma Eclipse
Pravidla rozhraní API závazku
Verze 0.15 - Poslední revize 12:00, 30. květen 2001
V tomto textu uvádíme pravidla závazku pro klienty rozhraní API platformy Eclipse (a jiných komponent).
Co znamená API
Platforma Eclipse definuje prvky API pro účely svých klientů, tj. nezávislých dodavatelů modulů plug-in. Tyto moduly plug-in mohou naopak definovat prvky rozhraní API pro své klienty atd. Prvky API představují vnější tvář: nesou specifikaci o účelu a způsobu svého použití. Pro prvky API je poskytována podpora: pracovní skupina platformy Eclipse opravuje chyby implementace na místech výskytu odchylek od specifikovaného chování. Protože obvykle v souvislosti s výraznými změnami rozhraní API vznikají vysoké náklady, pokusí se pracovní skupina platformy Eclipse rovněž o zapracování oprav prvků API do hlavních verzí.
Jak rozeznat prvky API od prvků mimo API
Na rozdíl od prvků mimo API, které jsou vnitřní implementací a obvykle k nim není poskytnuta dokumentace či specifikace, prvky API jsou zásadně dokumentovány a opatřeny specifikacemi. Nemůžete-li nalézt dokumentaci určitého prvku, jde o spolehlivý příznak skutečnosti, že nejde o prvek rozhraní API.
V zájmu výraznějšího odlišení je kódovací báze platformy rozdělena na balíčky rozhraní API a balíčky mimo API a všechny prvky rozhraní API jsou deklarovány ve vyhrazených balíčcích API.
-
Balíček rozhraní API - Balíček Java, který obsahuje nejméně jednu třídu nebo rozhraní API. Názvy balíčků jsou uvedeny v dokumentaci dané komponenty; pokud je to vhodné, názvy všech ostatních balíčků, které obsahují pouze podrobnosti implementace, obsahují termín "internal". Názvy balíčků API se mohou správně zobrazovat v kódu klienta. Pro platformu Eclipse jde o tyto položky:
-
org.eclipse.foo.* - Například org.eclipse.swt.widgets,
org.eclipse.ui nebo org.eclipse.core.runtime.
-
org.eclipse.foo.internal.* - Nejde o API; balíčky vnitřní implementace.
-
org.eclipse.foo.examples.* - Nejde o API; jsou to příklady.
-
org.eclipse.foo.tests.* - Nejde o API; jsou to testovací sady.
-
Třída nebo rozhraní API - Veřejná třída nebo rozhraní v balíčku API nebo veřejný či chráněný člen třídy nebo rozhraní deklarovaný nebo zděděný jinou třídou nebo rozhraním API.
Názvy tříd a rozhraní API se mohou správně zobrazovat v kódování klienta.
-
Metoda nebo konstruktor API - Veřejná nebo chráněná
metoda nebo konstruktor deklarovaná nebo zděděná jinou třídou nebo rozhraním API. Názvy metod API se mohou správně zobrazovat v kódu klienta.
-
Pole rozhraní API - Veřejné nebo chráněné pole deklarované nebo zděděné třídou nebo rozhraním API. Názvy polí API se mohou správně zobrazovat v kódu klienta.
Vše ostatní je považováno za podrobnost vnitřní implementace a mimo dosah všech klientů. Správný kód klienta nesmí odkazovat na názvy prvků mimo API (ani používat obraz Java). V určitých případech se pravidla přístupnosti názvů jazyka Java používají ke znemožnění nepovolených odkazů.
Je však řada případů, ve kterých to není možné. Dodržováním následujícího jednoduchého pravidla se problému zcela vyhnete:
-
Držte se pouze oficiálně dokumentovaných rozhraní API. Odkazujte pouze na balíčky, které jsou dokumentovány v publikované dokumentaci API Javadoc dané komponenty.
Zásadně neodkazujte na balíček, který patří do jiné komponenty, jež má v názvu termín "internal" --- nejde o API. Zásadně neodkazujte na balíček, pro který nebyla publikována dokumentace API Javadoc --- nejde o API.
Obecná pravidla
Specifikace prvků API je vygenerována z komentářů dokumentace Javadoc ve zdrojovém kódu Java prvku. Pro určité typy prvků má specifikace formu kontraktu. Například v případě metod tento kontrakt uzavírají dvě strany, objekt volající metodu a objekt, který metodu implementuje. Základní pravidlo:
-
Dodržujte všechny kontrakty. Kontrakty jsou popsány v publikované dokumentaci Javadoc pro prvky API, které používáte.
Termín "je třeba" použitý v kontraktu API znamená, že daná strana má za povinnost zajistit splnění podmínky za všech okolností; jakékoli selhání v této věci je považováno za chybu programování s nespecifikovanými (a možná i nepředvídatelnými) následky.
-
Klauzule obsahující termín "je třeba" musíte dodržovat. Pozornost věnujte zejména podmínkám, které používají termín "je třeba".
Ostatní smysluplná pravidla:
-
Nespoléhejte se na náhodné chování. Náhodné chování je chování, které bylo pozorováno při experimentu nebo v praxi, které však není zaručeno žádnou ze specifikací API.
-
Nepovažujte nulu za objekt. Nula je spíše nepřítomností objektu.
Nestanoví-li specifikace API jinak, předpokládejte, že vše je nenulové.
-
Nepokoušejte se obcházet pravidla odrazy Java. Použitím odrazu Java k potlačení kompilátoru Java nic nezískáte. K použití odrazu nejsou k dispozici žádné přídavné kontrakty API; odraz pouze zvyšuje pravděpodobnost spoléhání na nespecifikované chování a detail vnitřní implementace.
-
Používejte své vlastní balíčky. Nedeklarujte v balíčku kód patřící do jiné komponenty. Vždy deklarujte svůj vlastní kód ve svých vlastních balíčcích.
Volání veřejných metod API
Pro většinu klientů má celek rozhraní API Eclipse formu veřejných metod rozhraní či tříd API, které může klient volat dle potřeby.
-
Zajistěte předběžné podmínky. Před voláním metody zajistěte splnění předběžných podmínek této metody API. Naopak volající objekt může bezpečně předpokládat, že následné podmínky metody jsou splněny bezprostředně po návratu z volání.
-
Nulové parametry. Nepředávejte nulu jako parametr metodě API, pokud dokumentace výslovně nepovoluje nulu. Jde možná o nejčastější chybu programování.
-
Omezení volajících. Nevolejte metodu API, která je dokumentována pouze pro určité volající, pokud nejste jedním z nich. V určitých situacích metody musí být součástí veřejného API pro určitou třídu volajících (obvykle interních); volání těchto metod v nesprávný moment má nespecifikované (a možná i nepředpověditelné) následky.
-
Metody ladění. Nevolejte metodu API označenou "pouze pro účely ladění". Do této kategorie spadá například většina metod toString().
-
Zachycení parametru. Vyvarujte se předání pole, kolekce či jiného měnitelného objektu v podobě parametru metodě API a následné změně předávaného objektu. Tento postup si přímo říká o potíže.
Vytváření instalací tříd API platformy
Některé třídy API neumožňují vytváření svých instancí komukoli.
Třídy API mají kontrakt o vytváření instancí, který uvádí podmínky vytvoření instance. Tento kontrakt může upravovat rovněž kompetence zbytkové inicializace (např. konfigurace určitých vlastností před úplnou aktivací instance) a kompetence přiřazeného životního cyklu (např. volání dispose() za účelem uvolnění zdrojů operačního systému, které byly použity instancí). Třídy určené k vytváření instancí klienty jsou výslovně označeny v komentáři Javadoc třídy (slovy "Klienti mohou vytvářet instance").
-
Omezení konkretizátorů. Nekonkretizujte třídu API, která je podle dokumentace k dispozici pouze určitým stranám, pokud k nim nepatříte.
V určitých situacích třídy musí být součástí veřejného API pro určitou stranu (obvykle interních); nesprávné vytváření instancí těchto tříd má nespecifikované (a možná i nepředpověditelné) následky.
Vytvoření podtřídy tříd API platformy
Pouze podmnožina tříd API umožňuje vytváření podtříd. Třídy API mají kontrakt o podtřídě, který uvádí podmínky deklarace podtříd. Tento kontrakt rovněž upravuje kompetence inicializace a životního cyklu. Třídy určené k vytváření podtříd klienty jsou výslovně označeny v komentáři Javadoc třídy (slovy "Klienti mohou vytvářet podtřídy").
-
Omezení podtříd. Nevytvářejte podtřídu třídy API, která není určena pro podtřídu. S těmito třídami zacházejte, jakoby byly deklarovány jako konečné. (Tyto třídy se někdy nazývají "měkkými konečnými" třídami).
Volání chráněných metod API
V obecném případě je povoleno volání zděděných chráněných a veřejných metod z podtřídy; nicméně je v takovýchto případech často zapotřebí postupovat s větší obezřetností, než při volání veřejných metod z místa mimo hierarchii.
Potlačení metod API
Potlačovat lze pouze podmnožinu veřejných a chráněných metod API. Každá z metod API má kontrakt o podtřídě, jež určuje podmínky, za kterých lze podtřídu potlačit. Ve výchozím nastavení není potlačení povoleno.
Je zapotřebí kontrolovat smlouvu o podtřídě potlačované implementace třídy; podmínky smlouvy podtřídy nejsou při potlačení metody automaticky předávány.
-
Nepotlačujte veřejnou ani chráněnou metodu API, pokud to není výslovně povoleno. Není-li uveden jiný pokyn, zacházejte se všemi metodami, jakoby byly deklarovány jako konečné. (Tyto metody bývají nazývány "měkkými konečnými" metodami).
Je-li povoleno určité potlačení:
- "implement" - Abstraktní metoda deklarovaná v podtřídě musí být implementována konkrétní podtřídou.
- "extend" - Metoda deklarovaná v podtřídě musí spouštět metodu v supertřídě (pouze jednou).
- "re-implement" - Metoda deklarovaná v podtřídě nesmí spouštět metodu v supertřídě.
- "override" - Metoda deklarovaná v podtřídě může spouštět metodu v supertřídě dle potřeby.
-
Zajistěte následné podmínky. Ujistěte se o splnění následných podmínek zadaných pro metodu API implementací při návratu.
-
Aktivně kontrolujte předběžné podmínky. Nepředpokládejte, že jsou předběžné podmínky zadané pro metodu API na začátku splněny. Implementace metody sice má právo neověřovat zadané předběžné podmínky, avšak kontrola předběžných podmínek (dle potřeb a náročnosti operace) za účelem odstranění stop po nesprávně se chovajících volajících může být velmi užitečná.
-
Nulový výsledek. Není-li to výslovně dokumentováno (v definici rozhraní nebo supertřídy), nevracejte jako výsledek metody API nulu.
-
Vracejte kopie. Vyvarujte se předávání nenahraditelného pole, kolekce nebo jiného měnitelného objektu jako výsledku metody API. Vždy vracejte kopii, vyhnete se tak problémům způsobeným volajícími objekty, které mohou objekt upravit.
Implementace rozhraní API platformy
Pouze podmnožina rozhraní API je určena k implementaci klienty. Rozhraní API mají kontrakt, jenž určuje podmínky jejich implementace. Rozhraní určená k implementaci klienty jsou výslovně označena v komentáři Javadoc třídy (slovy "Klienti mohou implementovat"). Klient může deklarovat podřízené rozhraní pro rozhraní API pouze v případě, že může toto rozhraní implementovat.
-
Omezení implementátorů. Neimplementujte rozhraní API, které je podle dokumentace k dispozici pouze určitým stranám, pokud mezi ně nepatříte. V řadě situací se rozhraní používají ke skrytí detailů vnitřní implementace.
Implementace veřejných metod API
Viz "Potlačení metod API".
Přístup do polí tříd a rozhraní API
Klienti mohou číst pole API. Většina těchto polí je konečná. Určité objekty typu struct mohou obsahovat nefinální veřejná pole. Není-li uvedeno jinak, mohou klienti tato pole číst a zapisovat do nich.
-
Nulová pole. Není-li to výslovně povoleno, nenastavujte pole API jako nulové.
Přetypování objektů známého typu API
Objekt známého typu může být převeden pouze na jiný známý typ API (příp. může být přetypován podmíněně s použitím instanceof), pokud je to v API výslovně povoleno.
-
Cast a instanceof. Nepoužívejte výrazy instanceof a cast k doplnění informací o objektu mimo rámec podpory API.
Při nesprávném použití může dojít ke vzniku náhodných podrobností implementace, za něj API neručí.
Rovněž není vhodné měnit typ objektu na třídu či rozhraní mimo API.
Nedodržení pravidel
Vědomé i neúmyslné překročení pravidel má své následky. Pro všechny zúčastněné by bylo snadnější, kdyby byly k dispozici postupy API, které by vám umožnili porušovat stanovená pravidla. Situace je však odlišná.
Z větší části pracuje API na základě důvěry a jednotliví klienti nesou odpovědnost za znalost a dodržování pravidel.
Kontrakty prvků API omezují podporované a udržované chování. Platforma Eclipse se vyvíjí a dospívá. Tímto procesem ji provádějí kontrakty API. Mimo tyto kontrakty není nic podporováno a vše se mění bez předchozího upozornění (dokonce i mezi verzemi a různými operačními systémy). Kód klienta překračující výše uvedená pravidla může selhávat na různých verzích a úrovních oprav platformy, při provozu v různých operačních systémech, při provozu s různými kombinacemi současně použitých modulů plug-in nebo při provozu v různých perspektivách pracovní plochy atd. Ve skutečnosti se nikdo nezabývá úvahami o způsobech, kterými mohou jednotlivá přestoupení pravidel nepříznivě ovlivňovat činnost systému. Pokud uvedená pravidla budete ignorovat, nestěžujte si, že jste nebyli varováni. Neočekávejte více než soucitné "Vždyť jsme vám to říkali".
Naopak kód klientského modulu plug-in dodržující výše uvedená pravidla by měl pracovat v různých verzích a úrovních oprav platformy, v různých operačních systémech a měl by bez potíží pracovat vedle ostatních modulů plug-in. Budete-li postupovat podle pravidel, poskytne vám platforma Eclipse stabilní a podporovaný základ vytváření skvělých nových produktů.