Piattaforma Eclipse
Regole di attivazione dell'API
Versione 0.15 - Ultima revisione 30 maggio 2001 ore 12.00
Di seguito sono riportate le regole di attivazione per i client dell'API di piattaforma Eclipse e degli altri componenti.
Definizione di API
La piattaforma Eclipse definisce gli elementi API che verranno utilizzati dai propri client e cioè gli ISV che creano i plugin. I plugin, a loro volta, definiscono gli elementi API per i propri client. Gli elementi API costituiscono l'aspetto pubblico: essi riportano una specifica relativa alla propria probabile funzione ed al proprio utilizzo. Gli elementi API sono supportati: il team della piattaforma Eclipse corregge gli errori di implementazione qualora si verifichi una diversità rispetto alle caratteristiche specificate. Dal momento che le modifiche di rilievo dell'API richiedono costi notevoli, il team della piattaforma Eclipse tenterà di evolvere gli elementi API in modo progressivo, attraverso rilasci successivi.
Differenze tra gli elementi API e quelli non API
Per natura, gli elementi API sono documentati e hanno una specifica, diversamente dagli elementi non API che costituiscono dettagli di implementazione interna, solitamente privi di specifiche o documentazione pubblicate. Pertanto, la mancanza della documentazione relativa all'elemento indica che si tratta di un elemento non API.
Una differenza più netta è data dalla base del codice della piattaforma, che è distinta in pacchetti API e non API; pertanto tutti gli elementi API vengono dichiarati in specifici pacchetti API.
-
Pacchetto API - un pacchetto Java che contiene almeno una classe API o un'interfaccia API. I nomi dei pacchetti API sono pubblicati nella documentazione del relativo componente; laddove è possibile, tutti gli altri pacchetti, che contengono solo dettagli di implementazione, riportano nel nome del pacchetto il termine "internal". I nomi dei pacchetti API potrebbero essere visualizzati nel codice del client. Per la piattaforma Eclipse:
-
org.eclipse.foo.* - ad esempio, org.eclipse.swt.widgets,
org.eclipse.ui,
oppure org.eclipse.core.runtime
-
org.eclipse.foo.internal.* - non API; pacchetti di implementazione interna
-
org.eclipse.foo.examples.* - non API; si tratta di esempi
-
org.eclipse.foo.tests.* - non API; si tratta di istanze di verifica
-
Classe o interfaccia API - una classe o un'interfaccia pubblicain un pacchetto API oppure un membro di una classe o un'interfaccia pubblica o protetta dichiarato in o ereditato da un'altra classe o interfaccia API.
I nomi delle classi o delle interfacce API possono essere visualizzati nel codice del client.
-
Costruttore o metodo API - un costruttore o un metodo pubblico o protetto dichiarato in o ereditato da una classe o un'interfaccia API. I nomi dei metodi API possono essere visualizzati nel codice del client.
-
Campi API - un campo pubblico o protetto dichiarato in o ereditato da una classe o interfaccia API. I nomi dei campi API possono essere visualizzati nel codice del client.
I rimanenti elementi sono considerati dettagli di implementazione interna e non sono utilizzabili da alcun client. Un corretto codice del client non può riportare i nomi di elementi non API, tranne nel caso in cui si utilizzano riproduzioni Java. In alcuni casi, infatti, vengono utilizzate le regole di accessibilità del nome del linguaggio Java, per impedire i riferimenti invalidi.
Tuttavia, ciò non sempre è possibile. Osservando questa semplice regola si evita ogni problema:
-
Fare riferimento alle API ufficialmente documentate. Considerare come elemento API solo i pacchetti che sono documentati nei Javadoc API pubblicati relativi al componente.
Non considerare mai un pacchetto di un altro componente che riporta "internal" nel proprio nome: non si tratta di API. Né tanto meno va considerato elemento API un pacchetto del quale non non vi sono Javadoc API pubblicate: neanche queste sono API.
Regole generali
La specifica degli elementi API viene generata dai commenti Javadoc nel codice origineJava dell'elemento. Per alcuni tipi di elementi, la specifica si trova nel modello di un contratto. Ad esempio, nel caso dei metodi, il contratto è tra due parti, il chiamante del metodo e l'implementatore del metodo. La regola fondamentale è:
-
Rispettare tutti i contratti. I contratti sono descritti nel Javadoc pubblicato per gli elementi API utilizzati.
Il termine "dovere", utilizzato in un contratto API, indica l'obbligatorietà per le parti di assicurare il verificarsi della condizione; il mancato rispetto di questo obbligo verrà considerato come un errore di programmazione con conseguenze non specificate e quindi imprevedibili.
-
Rispettare sempre il termine "dovere". Fare particolare attenzione alle condizioni in cui viene utilizzato il termine "dovere".
Altre regole di senso comune:
-
Non valutare le caratteristiche occasionali. Tali caratteristiche vengono riscontrate durante la verifica o nella pratica, ma non sono garantite da nessuna specifica API.
-
Non considerare null un oggetto. Null è piuttosto la mancanza di un oggetto.
Tutti gli elementi vanno considerati un non null a meno che la specifica API affermi il contrario.
-
Fare attenzione all'utilizzo della riproduzione Java. Servirsi di questa riproduzione per evitare il controllo del compilatore Java non produce alcun vantaggio. Non esistono infatti ulteriori contratti API da utilizzare con la riproduzione; la funzione della riproduzione consente semplicemente di rendere più affidabili le caratteristiche non specificate e sui dettagli di implementazione interna.
-
Utilizzare i propri pacchetti. Non dichiarare il codice in un pacchetto che appartiene a un altro componente. Dichiarare sempre il proprio codice nei propri pacchetti.
Chiamata dei metodi API pubblici
Per molti client, l'intera API Eclipse assume l'aspetto di metodi pubblici su interfacce o classi API, che il client può chiamare quando necessario.
-
Assicurare le precondizioni. Prima di procedere alla chiamata di un metodo API, assicurarsi che tutte le precondizioni del metodo siano rispettate. Diversamente, il chiamante potrebbe ritenere che le postcondizioni del metodo si siano verificate immediatamente dopo la chiamata.
-
Parametri null. Non inoltrare null come parametro a un metodo API se non è documentato che il parametro supporta null. Questo è probabilmente l'errore di programmazione più frequente.
-
Chiamanti riservati. Non chiamare un metodo API, se è documentata una sua disponibilità solo per alcuni chiamanti, a meno che l'utente non rientri fra questi. Vi sono casi in cui è necessario che i metodi siano parte dell'API pubblica a vantaggio di una determinata classe di chiamanti (spesso interni); la chiamata di uno di questi metodi nel momento sbagliato produce conseguenze non specificate e quindi imprevedibili.
-
Metodi di debug. Non chiamare un metodo con un etichetta che indica che il metodo è destinato solo al debug. Ad esempio, la maggior parte dei metodi toString() fa parte di questa categoria.
-
Acquisizione dei parametri. Non passare come parametro una matrice, un insieme o un altro oggetto mutevole a un metodo API, per poi modificarlo. Ciò potrebbe causare dei problemi.
Istanza di classi API della piattaforma
Non tutti possono creare un'istanza per qualsiasi classe API.
Le classi API dispongono di un contratto per la creazione dell'istanza che indica i termini da rispettare per questa operazione. Il
contratto può riguardare, ad esempio, le responsabilità di inizializzazione
(configurazione di una determinata proprietà precedente alla piena attivazione
dell'istanza) e le responsabilità del relativo ciclo di vita, come ad esempio
la chiamata del metodo dispose() per rilasciare le risorse del sistema
operativo dipendenti dall'istanza. Le classi la cui istanza deve essere creata dai client sono indicate in modo esplicito nel commento della classe Javadoc, con espressioni del tipo "Creazione di istanza consentita ai client".
-
Utilità di creazione delle istanze riservate. Non creare istanze di a una classe API, la cui documentazione indica una disponibilità limitata ad alcune parti, a meno che l'utente non rientri fra queste parti.
Vi sono casi in cui è necessario che le classi siano parte dell'API pubblica a vantaggio di determinate parti (spesso interne); l'errata istanza di una di queste classi produce conseguenze non specificate e quindi imprevedibili.
Creazioni di sottoclassi per classi API di piattaforma
È possibile creare sottoclassi solo per un sottoinsieme di classi API. Queste dispongono di un contratto di sottoclasse che indica i termini da rispettare per questa operazione. Questo contratto riguarda anche le responsabilità di inizializzazione e le responsabilità relative al ciclo di vita. Le classi che possono essere divise in sottoclassi dai client sono indicate in modo esplicito nel commento della classe Javadoc, con espressioni del tipo "Creazione di sottoclassi consentita ai client".
-
Utilità di creazione delle sottoclassi riservate. Non creare sottoclassi relative a classi API che non sono destinate a questo scopo. È consigliabile considerare tali classi come classi finali (spesso vengono definite classi "quasi finali").
Chiamata dei metodi API protetti
La chiamata dei metodi ereditati protetti o pubblici da una sottoclasse è solitamente possibile; tuttavia questa operazione richiede maggiore cautela rispetto alla chiamata dei metodi pubblici dall'esterno della gerarchia.
Sostituzione di metodi API
È possibile sostituire solo un sottoinsieme di metodi API pubblici e protetti. Ogni metodo API dispone di un contratto di sottoclasse che indica i termini da rispettare per questa operazione. Per impostazione predefinita, la sostituzione non è consentita.
È importante controllare il contratto di sottoclasse relativo all'implementazione del metodo che deve essere sostituito; i termini di questi contratti non vengono automaticamente trasferiti durante la sostituzione del metodo.
-
Non sostituire un metodo API pubblico o protetto se non è esplicitamente consentito. Se non indicato diversamente, è consigliabile considerare tutti i metodi come metodi finali (spesso vengono definiti metodi "quasi finali").
Se il tipo di sostituzione consentita è:
- "implementa" - il metodo astratto dichiarato nella sottoclasse deve essere implementato da una sottoclasse concreta
- "estendi" - il metodo dichiarato nella sottoclasse deve richiamare il metodo di superclasse (una sola volta)
- "re-implementa" - il metodo dichiarato nella sottoclasse non deve richiamare il metodo di superclasse
- "sostituisci" - il metodo dichiarato nella sottoclasse può richiamare il metodo di superclasse che rileva corretto
-
Assicurare le postcondizioni. Assicurarsi che tutte le postcondizioni specificate per il metodo API siano rispettate al termine dell'implementazione.
-
Controllare preliminarmente le precondizioni. Non è possibile presumere che le precondizioni specificate per il metodo API si siano verificate all'inizio dell'implementazione. Sebbene l'implementazione del metodo potrebbe evitare il controllo delle precondizioni, è consigliabile effettuare tale controllo, quando possibile e ragionevolmente vantaggioso.
-
Risultato null. Non restituire null come un risultato di un metodo API, a meno che non sia esplicitamente documentato, nell'interfaccia o nella superclasse, che il risultato supporti null.
-
Restituire le copie. Non restituire una matrice non sostituibile, un insieme o un altro oggetto modificabile come risultato di un metodo API. Restituire sempre una copia, in modo da evitare problemi dai chiamanti che potrebbero modificare l'oggetto.
Implementazione delle interfacce API di piattaforma
È possibile implementare dai client solo un sottoinsieme di classi API. Queste dispongono di un contratto che indica i termini da rispettare per questa operazione. Le interfacce che possono essere implementate dai client sono indicate in modo esplicito nel commento della classe Javadoc, con espressioni del tipo "Implementazione consentita ai client". Un client può dichiarare una sottointerfaccia di un'interfaccia API solo nel caso in cui gli sia consentita l'implementazione.
-
Implementazione riservata. Non implementare un'interfaccia API, la cui documentazione indica una disponibilità limitata ad alcune parti, a meno che l'utente non rientri fra queste parti. Vi sono molti casi in cui le interfacce vengono utilizzate per nascondere dettagli di implementazione interna nella vista.
Implementazione di metodi API pubblici
Consultare la sezione "Sostituzione di metodi API"
Accesso ai campi nelle interfacce e nelle classi API
I client possono leggere campi API, molti dei quali sono finali. Alcune oggetti di tipo struct potrebbero avere campi pubblici non finali, che i client possono leggere e scrivere, salvo diversa indicazione.
-
Campi null. Non impostare un campo API su null, a meno che questa impostazione non sia esplicitamente ammessa.
Esecuzione del cast degli oggetti di un tipo di API conosciuto
È possibile eseguire il cast di un oggetto di un tipo di API conosciuto solo a un diverso tipo di API (oppure utilizzare instanceof) se consentito esplicitamente nell'API.
-
Cast e instanceof. Non utilizzare le espressioni instanceof e cast per incrementare le informazioni note di un oggetto oltre il livello supportato dall'API.
Un utilizzo improprio impedisce all'API di garantire i dettagli di implementazione incidentale.
Ovviamente, non è mai opportuna l'esecuzione del cast di un oggetto in una classe o interfaccia non API.
Mancato rispetto delle regole
Il mancato rispetto delle regole, anche involontario, comporta delle conseguenze. Potrebbe essere utile un sistema di controllo che avverta nei casi di violazione di una regola. Tuttavia questo sistema non è stato ancora sviluppato.
La maggior parte degli utenti conosce ed applica le regole di funzionamento.
I contratti degli elementi API definiscono i comportamenti consentiti. L'evoluzione dei contratti API guiderà la parallela evoluzione della piattaforma Eclipse. Al di fuori di tali contratti, tutto deve considerarsi non supportato e soggetto a modifiche, senza preavviso e in qualsiasi momento (anche attraverso rilasci intermedi o tra diversi sistemi operativi). Un codice client che non rispetti le regole riportate potrebbe non funzionare in altre versioni o livelli della piattaforma; durante l'esecuzione su diversi sistemi operativi; durante l'esecuzione con un insieme di plugin coesistenti; durante l'esecuzione con una diversa prospettiva del workbench e così via. In realtà, non esiste un particolare interesse all'individuazione di tutte le conseguenze negative del mancato rispetto di queste regole. Se l'utente non rispetta queste regole va incontro a inevitabili conseguenze.
Al contrario, coloro che osservano quanto sopra riportato potranno utilizzare il codice di plugin del client attraverso le diverse versioni e livelli della piattaforma, con diversi sistemi operativi e possono tranquillamente operare insieme ad altri plugin. Il rispetto delle regole consente alla piattaforma Eclipse di costituire una stabile e valida base per la creazione di nuovi efficienti prodotti.