Eclipse-platform
Regels voor het gebruik van de API van het Eclipse-platform
Versie 0.15 - Laatst gewijzigd op 30 mei 2001 om 12:00 uur
In dit document vindt u een beschrijving van de regels voor het gebruik van de Eclipse-platform-API (en andere componenten) voor clients.
Wat is een API
Het Eclipse-platform definieert API-elementen voor gebruikers, ISV's (Independent Software Vendors, onafhankelijke
softwareleveranciers) die plugins ontwikkelen. Deze kunnen op hun beurt weer API-elementen voor
hun gebruikers definiëren, enzovoort. API-elementen vormen het 'gezicht' van de interface. Zij
bevatten de specificaties met betrekking tot hun functie en de manier waarop ze moeten worden
gebruikt. API-elementen worden ondersteund: het Eclipse-platformteam zal implementatiefouten
oplossen wanneer de werking van het programma afwijkt van het gespecificeerde
gedrag. Aangezien ingrijpende API-wijzigingen vaak gepaard gaan met hoge kosten,
streeft het Eclipse-platformteam ook naar een optimale evolutie van API-elementen
in opeenvolgende grote releases.
Het verschil tussen API-elementen en niet-API-elementen
API-elementen zijn per definitie gedocumenteerd en gekoppeld aan een specificatie.
Niet-API-elementen daarentegen hebben betrekking op interne implementatiedetails en
worden gewoonlijk aangeleverd zonder bijbehorende documentatie of specificaties. Als u
ergens geen documentatie voor kunt vinden, is dat meestal een duidelijk teken dat het
geen API-element is.
Om het onderscheid nog duidelijker te maken: de codebasis voor het platform
wordt onderverdeeld in API- en niet-API-pakketten. Hierbij worden alle API-elementen
gedeclareerd in aangewezen API-pakketten.
-
API-pakket: een Java-pakket dat ten minste één API-klasse of API-interface
bevat. De namen van API-pakketten worden aangekondigd in de documentatie
voor de desbetreffende component; waar mogelijk hebben alle andere pakketten die alleen
implementatiedetails bevatten een pakketnaam met "internal" erin. De namen van
API-pakketten mogen legitiem worden gebruikt in clientcode. Voor het Eclipse-platform
zijn dat:
-
org.eclipse.foo.*: bijvoorbeeld org.eclipse.swt.widgets org.eclipse.ui of org.eclipse.core.runtime.
-
org.eclipse.foo.internal.*: niet-API; interne implementatiepakketten.
-
org.eclipse.foo.examples.*: niet-API; dit zijn voorbeelden.
-
org.eclipse.foo.tests.*: niet-API; dit zijn testsuites.
-
API-klasse of API-interface: een public (openbare) klasse of interface in
een API-pakket of een lid van een public of protected (beveiligde) klasse of interface
dat is gedeclareerd in of overgenomen van een andere API-klasse of -interface.
De namen van API-klassen en -interfaces mogen legitiem worden gebruikt in clientcode.
-
API-methode of API-constructor: een public (openbare) of protected (beveiligde)
methode of constructor die is gedeclareerd in of overgenomen van een API-klasse of
API-interface. De namen van API-methoden mogen legitiem worden gebruikt in clientcode.
-
API-veld: een public (openbaar) of protected (beveiligd) veld dat is
gedeclareerd in of overgenomen van een API-klasse of API-interface. De namen van
API-velden mogen legitiem worden gebruikt in clientcode.
Alle overige elementen worden beschouwd als interne implementatiedetails en mogen niet
door cliënten worden gebruikt. Legitieme clientcode mag nooit (verwijzingen naar) namen van
niet-API-elementen bevatten (zelfs niet bij Java-reflectie). In sommige gevallen kunnen de
naamtoegangsregels van de Java-taal worden gebruikt om niet-toegestane verwijzingen te voorkomen.
In veel gevallen is dit echter niet mogelijk. U kunt dit probleem omzeilen door u te houden
aan de volgende eenvoudige regel:
-
Gebruik uitsluitend officieel gedocumenteerde API's. Verwijs alleen naar pakketten die in de gepubliceerde API-Javadoc voor de component zijn gedefinieerd.
Verwijs nooit naar een pakket dat behoort tot een andere component met "internal"
in de naam: dit zijn nooit API-elementen. Verwijs ook nooit naar een pakket waarvoor
geen gepubliceerde API-Javadoc beschikbaar is: dit zijn ook geen API-elementen.
Algemene regels
De specificatie van API-elementen wordt gegenereerd op basis van Javadoc-commentaar in
de Java-broncode van het desbetreffende element. Voor sommige typen elementen heeft de specificatie
de vorm van een contract (of overeenkomst). Bij methoden bijvoorbeeld is er sprake van een
contract tussen twee partijen, namelijk het aanroepprogramma van de methode en de implementor van de
methode. De basisregel is:
-
Respecteer alle contracten. De contracten worden beschreven in de gepubliceerde
Javadoc voor de API-elementen die u gebruikt.
Als in een API-contract (een vorm van) het werkwoord 'moeten' wordt gebruikt, betekent dit dat de desbetreffende partij
verplicht is om ervoor te zorgen dat altijd aan deze voorwaarde wordt voldaan. Als deze verplichting
niet wordt nagekomen, wordt dit beschouwd als programmeerfout met onbekende (en wellicht onvoorspelbare) gevolgen.
-
Neem "moeten" in acht. Let vooral op voorwaarden waarin (een vorm van) het werkwoord 'moeten' is gebruikt.
Overige algemene regels:
-
Ga niet uit van incidenteel gedrag. Dit type gedrag doet zich soms voor tijdens een experiment of in de praktijk, maar wordt nergens beschreven in een API-specificatie.
-
Behandel null niet als object. Null duidt eerder op een ontbrekend object.
Ga ervan uit dat alles niet-null is, tenzij in de API-specificatie iets anders is vermeld.
-
Gebruik geen oneerlijke Java-reflectie. U schiet er niets mee op door de controle van het Java-compileerprogramma te proberen omzeilen door Java-reflectie te gebruiken. Er zijn geen aanvullende API-contracten voor het gebruik
van reflectie: reflectie verhoogt alleen maar de kans op niet-gespecificeerd gedrag en interne implementatiedetails.
-
Gebruik uw eigen pakketten. Declareer geen code in een pakket van een andere component. Declareer altijd uw eigen code in uw eigen pakketten.
Openbare API-methoden aanroepen
Voor de meeste clients wordt de Eclipse-API beschikbaar gesteld in de vorm van openbare (public)
methoden voor API-interfaces of klassen, die op het gewenste moment door de client kunnen worden aangeroepen.
-
Controleer de beginvoorwaarden. Zorg ervoor dat aan alle beginvoorwaarden is voldaan voordat u de API-methode aanroept. Anders gaat de aanroepende code er misschien
direct bij retournering van de aanroep van de methode van uit dat aan de eindvoorwaarden is voldaan.
-
Null-parameters. Geef geen null-parameter door aan een API-methode
tenzij expliciet in de documentatie is vermeld dat dit is toegestaan. Dit is
waarschijnlijk de meest voorkomende programmeerfout.
-
Beperkte aanroepprogramma's. Roep geen API-methode aan die volgens de documentatie
alleen beschikbaar is voor bepaalde initiatiefnemers, tenzij u daartoe behoort. In sommige
gevallen moeten methoden deel uitmaken van de openbare API voor een bepaalde klasse
initiatiefnemers (meestal intern). Als u een van deze methoden op het verkeerde moment
aanroept, kan dit onbekende (en wellicht nadelige) gevolgen hebben.
-
Methoden voor foutopsporing. Roep geen API-methode aan die alleen is bedoeld
voor foutopsporing. De meeste toString()-methoden behoren tot deze categorie.
-
Parameterdefinitie. Geef geen array, collectie of ander variabel object door
als parameter voor een API-methode als u dit object vervolgens wilt wijzigen. Dit is vragen om problemen.
Instances van platform-API-klassen maken
Niet elke gebruiker kan van alle concrete API-klassen een instance maken.
API-klassen vallen onder een contract waarin staat aangegeven onder welke voorwaarden er
instances van mogen worden gemaakt. In het contract kunnen ook bepalingen zijn opgenomen over
resterende initialisatietaken (zoals het configureren van een bepaalde eigenschap voordat
de instance volledig actief is) en bijbehorende levenscyclustaken
(zoals het aanroepen van dispose() om besturingssysteemresources vrij te maken
die door de instance bezet worden gehouden). Als een klasse speciaal is ontworpen om er een instance van te maken,
wordt dit expliciet vermeld in het Javadoc-commentaar van de desbetreffende klasse (bijvoorbeeld met de woorden
"Hier mag een instance van worden gemaakt.").
-
Beperkte instantiators. Maak geen instance van een API-klasse die volgens de documentatie
alleen beschikbaar is voor bepaalde initiatiefnemers, tenzij u daartoe behoort.
In sommige gevallen moeten klassen deel uitmaken van de openbare API voor een
bepaalde partij (meestal intern). Als u op onjuiste wijze een instance van een van deze
klassen maakt, kan dit onbekende (en wellicht nadelige) gevolgen hebben.
Subklassen van platform-API-klassen maken
Slechts een subset van de API-klassen is zo ontworpen dat u er subklassen van kunt maken. API-klassen
vallen onder een contract waarin staat aangegeven onder welke voorwaarden er subklassen van
mogen worden gedeclareerd. Dit contract bevat ook een aantal bepalingen omtrent initialisatie-
en levenscyclustaken. Als een klasse speciaal is ontworpen om er een subklasse van te maken,
wordt dit expliciet vermeld in het Javadoc-commentaar van de desbetreffende klasse (bijvoorbeeld met de woorden
"Hier mag een subklasse van worden gemaakt.").
-
Beperkte subclassers. Maak geen subklasse van een API-klasse die hiervoor
niet is ontworpen. Behandel deze klassen alsof ze gedeclareerd zijn als final
(definitief). Deze klassen worden soms ook wel 'zachte' final-klassen genoemd.
Beveiligde API-methoden aanroepen
Het aanroepen van overgenomen beveiligde (protected) en openbare (public) methoden vanuit een subklasse is
over het algemeen toegestaan. Het is echter wat omslachtiger om deze methoden op de juiste wijze
aan te roepen dan openbare methoden van buiten de hiërarchie.
API-methoden vervangen
Slechts een subset van de openbare en beveiligde API-methoden is zo ontworpen dat u deze
kunt vervangen. Elke API-methode valt onder een subklassencontract waarin staat aangegeven onder welke
voorwaarden u de methode met een subklasse ervan kunt vervangen. Standaard is het vervangen niet toegestaan.
U dient het subklassencontract voor de werkelijke implementatie van de vervangen methode
goed te controleren. De voorwaarden van subklassencontracten worden niet automatisch overgenomen wanneer de desbetreffende methode wordt vervangen.
-
Vervang geen openbare of beveiligde API-methoden tenzij dit expliciet is
toegestaan. Tenzij anders wordt aangegeven, behandelt u alle methoden alsof ze
gedeclareerd zijn als final (definitief). Deze worden soms ook wel 'zachte' final-methoden genoemd.
Toegestane soorten vervangingen zijn:
- "implement": de gedeclareerde abstracte methode van de subklasse moet worden geïmplementeerd door een concrete subklasse.
- "extend": de gedeclareerde methode van de subklasse moet de methode van de superklasse (exact eenmaal) aanroepen.
- "re-implement": de gedeclareerde methode van de subklasse mag de methode van de superklasse niet aanroepen.
- "override": de gedeclareerde methode van de subklasse mag de methode van de superklasse altijd aanroepen.
-
Controleer de eindvoorwaarden. Zorg ervoor dat door de implementatie bij retournering aan alle eindvoorwaarden is voldaan die zijn opgegeven voor de API-methode.
-
Wees proactief in het controleren van de beginvoorwaarden. Ga er niet klakkeloos van uit dat bij activering van de methode aan alle opgegeven beginvoorwaarden is voldaan. Hoewel het voor de
methode-implementatie niet verplicht is om opgegeven beginvoorwaarden te controleren,
is het meestal wel nuttig een controle uit te voeren (mits haalbaar en relatief betaalbaar)
om te zien of de regels worden nageleefd in aanroepende code.
-
Null-resultaat. Retourneer null niet als resultaat van een API-methode tenzij in de documentatie expliciet is aangegeven dat een null-resultaat is toegestaan (voor de specificerende interface of superklasse).
-
Retourneer kopieën. Retourneer geen onvervangbare array, collectie of ander variabel object als resultaat van een API-methode. Retourneer altijd een kopie
om te voorkomen dat er problemen optreden wanneer het object door aanroepende code wordt gewijzigd.
Interfaces van de platform-API implementeren
Slechts een subset van de API-interfaces is zo ontworpen dat deze door clients kunnen worden
geïmplementeerd. API-interfaces vallen onder een contract waarin staat aangegeven onder welke voorwaarden
deze mogen worden geïmplementeerd. Als een interface speciaal is ontworpen om door clients te worden
geïmplementeerd, wordt dit expliciet vermeld in het Javadoc-commentaar van de desbetreffende klasse (bijvoorbeeld met de
woorden "Deze interface mag worden geïmplementeerd."). Een client mag alleen een subinterface van een API-interface declareren als zij gemachtigd zijn om deze te
implementeren.
-
Beperkte implementors. Implementeer geen API-interface die volgens de documentatie
is voorbehouden aan bepaalde partijen, tenzij u tot een van die partijen behoort.
Interfaces worden vaak gebruikt om interne implementatiedetails te verbergen.
Openbare API-methoden implementeren
Zie "API-methoden vervangen".
Toegang krijgen tot velden in API-klassen en API-interfaces
Clients hebben leestoegang tot API-velden, waarvan er veel final zijn. Sommige
structuur-achtige objecten bevatten niet-definitieve, vrij toegankelijke velden. Tenzij
anders is aangegeven, hebben alle clients lees- en schrijftoegang tot deze velden.
-
Null-velden. Stel een API-veld niet in op null, tenzij dit expliciet is toegestaan.
Objecten van een bekend API-type omzetten
Een object van een bekend API-type mag alleen worden omgezet naar een ander API-type
(of voorwaardelijk worden omgezet met instanceof) als dit expliciet is toegestaan in de API.
-
Cast en instanceof. Gebruik geen instanceof- en castexpressies om meer toe te voegen
aan hetgeen bekend is over een object buiten datgene wat door de API wordt ondersteund.
Bij onjuist gebruik worden incidentele implementatiedetails onthuld die niet altijd door de API
worden ondersteund.
En een object omzetten naar een niet-API-klasse of -interface is per definitie niet toegestaan.
Overtreding van de regels
Of het nu expres of per ongeluk gebeurt, aan het overtreden van de regels zijn bepaalde
consequenties verbonden. Het zou ideaal zijn als er een API-politie was om overtreders
op heterdaad te betrappen. Dit is echter niet het geval.
API-conformiteit is grotendeels gebaseerd op een soort erecode, waarbij elke client
geacht wordt de regels te kennen en zich daar ook aan te houden.
De contracten voor de API-elementen bevatten beperkingen ten aanzien van alle gedragspatronen die
worden ondersteund en onderhouden. De API-contracten bevatten ook richtlijnen voor de ontwikkeling
en uitbreiding van het Eclipse-platform. Alle zaken die buiten deze contracten vallen, worden
niet ondersteund en kunnen te allen tijde zonder voorafgaande kennisgeving worden gewijzigd
(zelfs tijdens een release, en kunnen per besturingssysteemplatform verschillen). Als de code van
de client niet aan bovengenoemde regels voldoet, is de code mogelijk niet bruikbaar in alle versies
en op alle patchniveaus van het platform. Mogelijk kan de code ook niet worden uitgevoerd op een ander
besturingssysteem, met een verschillende combinatie van co-residente plugins, vanuit een
ander workbenchperspectief, enzovoort. Het is niet de bedoeling om hier uitgebreid in te gaan op
de nadelige gevolgen van bepaalde overtredingen. Als u zich bewust niet aan de regels wilt
houden, doet u dat op uw eigen verantwoording. U bent gewaarschuwd.
Plugincode van clienten die zich wél aan bovengenoemde regel houden, zou probleemloos moeten functioneren in verschillende versies en op verschillende patchniveaus van
het platform, in verschillende onderliggende besturingssystemen en in combinatie met
andere plugins. Als iedereen zich netjes aan de regels houdt, vormt Eclipse een
stabiel en veelzijdig platform voor de ontwikkeling van baanbrekende nieuwe producten.