Plataforma Eclipse
Regras de Engajamento da API
Versão 0.15 - Última revisão 12:00 em 30 de maio de 2001
Aqui estão as regras de engajamento para clientes da Plataforma Eclipse API (e outros componentes).
O que significa ser API
A plataforma Eclipse define os elementos API para serem utilizados pelos seus clientes, nomeados plug-ins de escrita ISVs.
Esses plug-ins podem em contrapartida definir os elementos API para seus clientes, e assim por diante.
Os elementos API são a face pública: eles carregam a especificação sobre o que eles devem fazer e sobre como os mesmos devem ser utilizados. Os elementos API possuem suporte: a equipe da plataforma
Eclipse corrigirá erros de implementação onde houver um desvio do comportamento
especificado. Uma vez que freqüentemente há um alto custo associado à ruptura das alterações da API, a equipe da plataforma Eclipse também tentará desenvolver elementos API como cortesia através dos principais releases sucessivos.
Como diferenciar API de não API
Pela sua natureza variada, os elementos API são documentados e têm uma especificação, em contraste com elementos não API, que são detalhes de implementação interna, geralmente sem documentação publicada ou especificações. Assim, se você não puder encontrar a documentação para alguma coisa, isso geralmente é um bom indicador de que não é uma API.
Para tentar desenhar a linha mais completa, a base do código para a plataforma é separada em pacotes API e não API, com todos os elementos sendo declarados em pacotes API designados.
-
pacotes API - um pacote Java que contém pelo menos uma classe API ou interface API. Os nomes dos pacotes API são anunciados na documentação para aquele componente; onde possível, todos os outros pacotes contendo somente detalhes de implementação têm "interno" no nome do pacote. Os nomes dos pacotes API podem legitimamente aparecer no código do cliente. Para a própria plataforma Eclipse, são esses:
-
org.eclipse.foo.* - por exemplo, org.eclipse.swt.widgets,
org.eclipse.ui,
ou org.eclipse.core.runtime
-
org.eclipse.foo.internal.* - não API; pacotes de implementação interna
-
org.eclipse.foo.examples.* - não API; esses são exemplos
-
org.eclipse.foo.tests.* - não API; esses são conjuntos de teste
-
Classe API ou interface - uma classe pública ou interface no pacote API, ou uma classe pública ou protegida ou membro da interface declarado em, herdado de alguma outra classe API ou interface. Os nomes das classes API e interfaces podem legitimamente aparecer no código do cliente.
-
O método API ou construtor - um método público ou protegido
ou construtor declarado em, ou herdado por uma classe API ou interface. Os nomes dos métodos API podem legitimamente aparecer no código do cliente.
-
Campo API - um campo público ou protegido declarado em ou herdado por uma classe API ou interface.
Os nomes dos campos API podem legitimamente aparecer no código do cliente.
Todo o resto é considerado detalhe de implementação interna e proibido para todos os clientes. O código de cliente legítimo nunca se refere a nomes dos elementos não API (nem mesmo utilizando a reflexão Java). Em alguns casos, as regras de acessibilidade do nome da linguagem Java são utilizados para impedir referências ilegais. Entretanto, há muitos casos onde isso simplesmente não é possível. Observar essa regra simples evita o problema completamente:
-
Anexados a APIs oficialmente documentadas. Somente pacotes de referência que são documentados em Javadoc de API publicado para o componente.
Nunca se refere a pacote pertencentes a outro componente que tenha "interno" em seu nome ---esses nunca são API. Nunca se refere a um pacote para o qual não há nenhum Javadoc de API publicado ---esses não são API igualmente.
Regras Gerais
A especificação dos elementos API é gerada a partir dos comentários Javadoc no código de origem dos elementos Java. Para alguns tipos de elementos, a especificação está no formulário do contrato. Por exemplo, no caso dos métodos, o contrato é entre duas artes, o originador da chamada do método e o implementador do método. A regra básica fundamental é:
-
Honrar todos os contratos. Os contratos são descritos no Javadoc publicado para os elementos API que você está utilizando.
O termo "deve", quando utilizado em um contrato API, significa que é incumbência da parte assegurar que a condição será sempre atendida; qualquer falha em fazer isso deve ser considerada um erro de programa com conseqüências não especificadas (e talvez imprevisíveis).
-
Você deve honrar o "deve". Preste especial atenção às condições onde "deve" é utilizado.
Outras regras de senso comum:
-
Não confie em comportamento incidental. Comportamento incidental é comportamento observado em experiência ou na prática, mas o que não é garantido por nenhuma especificação API.
-
Não trate nulo como um objeto. Nulo é mais que a ausência de um objeto. Assuma que tudo é diferente de não nulo, a menos que a especificação API diga o contrário.
-
Não tentar trapacear com a reflexão Java. Utilizar a reflexão para tirar vantagem da verificação do compilador Java não lhe acrescenta nada.
Não existem contratos API adicionais para usos de reflexão; a reflexão simplesmente aumenta a possibilidade de ocorrência de comportamento não especificado e detalhes de implementação interna.
-
Utilize seus próprios pacotes. Não declare código em um pacote pertencente a outro componente.
Sempre declare seu próprio código em seus próprios pacotes.
Chamar por métodos API públicos
Para a maioria dos clientes, a massa do Eclipse API toma a forma dos métodos públicos nas interfaces API ou classes, fornecidas para o cliente chamar quando apropriado.
-
Assegure pré-condições. Certifique-se de que as pré-condições dos métodos API foram satisfeitas antes de chamar o método.
De modo recíproco, o originador da chamada pode seguramente assumir que as pós-condições do método serão alcançadas imediatamente, mediante o retorno do originador de chamada.
-
Parâmetros nulos. Não transfira nulo como um parâmetro para um método API a menos que o parâmetro esteja explicitamente documentado como permitindo nulo. Isso talvez seja o erro de programação mais freqüente.
-
Originadores de chamada restritos. Não chame um método API que esteja documentado como disponível somente para certos originadores de chamada, a menos que você seja um deles. Em algumas situações, os métodos precisam ser parte de um API público para o benefício de certas classes de originadores de chamada (freqüentemente internos); chamar um desses métodos na hora errada tem conseqüências não especificadas (e talvez imprevisíveis).
-
Métodos de Depuração. Não chame um método API rotulado como "para propósitos de depuração somente".
Por exemplo, a maioria dos métodos toString() estão nessa categoria.
-
Captura de Parâmetro. Não transmita uma matriz, coleção ou outro objeto mutável como um parâmetro para um método API para então modificar o objeto transmitido. Isso é procurar por problemas.
Instanciando classes de plataforma API
Nem todas as classes concretas de API podem ser instanciadas por qualquer pessoa. As classes API têm um contrato de instanciação indicando os termos sob os quais as instâncias podem ser criadas. O contrato pode também cobrir coisas tais como responsabilidades por inicialização residual (por exemplo, configurar uma certa propriedade antes de a ocorrência estar totalmente ativa), e responsabilidades associadas ao ciclo de vida
(por exemplo, chamar dispose() para liberar recursos OS pendurados em uma ocorrência). As classes que são designadas para serem instanciadas pelos clientes são explicitamente avisada no comentário da classe Javadoc (com palavras como "Clientes podem instanciar.").
-
Instanciadores Restritos. Não instancie uma classe API que esteja documentada como disponível para determinadas partes, a menos que você sejam uma delas. Em algumas situações, as classes precisam ser parte de um API público para o benefício de determinada parte (freqüentemente interna); instanciar uma dessas classes incorretamente tem conseqüências não especificadas (ou talvez imprevisíveis).
Subclassificar classes de plataforma API
Somente um subconjunto das classes API foram designados para serem subclassificados. As classes API têm um contrato de subclassificação indicando os termos sob os quais as classes filhas podem ser declaradas. Esse contrato também cobre as responsabilidades de inicialização e as responsabilidades do ciclo de vida. As classes que são designadas para serem subclassificadas pelos clientes estão explicitamente avisadas no comentário da classe Javadoc (com palavras como "Clientes podem subclassificar.").
-
Subclassificadores restritos. Não subclassifique uma classe API que não deve ser subclassificada. Trate essas classes como se elas tivessem sido declaradas finais. (Isso algumas vezes é referido como classes "soft final").
Chamando métodos API protegidos
Chamar métodos públicos e protegidos herdados a partir de uma classe filha é geralmente permitido; entretanto, isso freqüentemente exige mais cuidado para chamar corretamente do que os métodos públicos de fora da hierarquia.
Substituindo métodos API
Somente um subconjunto de métodos API públicos e protegidos foram designados para serem substituídos.
Cada método API tem um contrato de classe filha indicando os termos sob os quais uma classe filha pode substituí-los. Por padrão, a substituição não é permitida.
É importante verificar o contrato da classe filha referente a implementação do método atual que está sendo substituído; os termos dos contratos das classes filhas são automaticamente transmitidos para frente quando o método é substituído.
-
Não substitua um método API público ou protegido, a menos que seja explicitamente permitido. A menos que indicado de outra forma, trate todos os métodos como se eles tivessem sido declarados finais.
(Eles são conhecidos algumas vezes como métodos "soft finais"). Se o tipo de substituição permitido for:
- "implementar" - método abstrato declarado na classe filha deve ser implementado por uma classe filha concreta
- "estender" - método declarado na classe filha deve chamar o método na superclasse (exatamente uma vez)
- "re-implementar" - o método declarado na classe filha não deve chamar o método na superclasse.
- substituir" - o método declarado na classe filha é livre para chamar o método na superclasse, se for adequado.
-
Assegurar pós condições. Certifique-se de que quaisquer das pós condições especificadas para o método API são satisfatórias para a implementação mediante retorno.
-
Pré-condições de verificação pró-ativadas. Não presuma que as pré-condições especificadas para o método API foram necessariamente satisfeitas mediante a entrada. Embora a implementação do método esteja dentro de seus direitos de não verificar as pré-condições, geralmente é uma boa idéia verificar as pré-condições (quando possível e razoavelmente barato), a fim de eliminar os originadores de chamada mal comportados e desonestos.
-
Resultado nulo. Não retorne nulo como um resultado a partir do método API a menos que o resultado esteja explicitamente documentado (na interface especificada ou superclasse), como que o nulo é permitido.
-
Retornar cópias. Não retorne uma matriz insubstituível, uma coleção, ou outro objeto mutável como resultado do método API.
Sempre retorne uma cópia para evitar problemas do originadores de chamada que podem modificar o objeto.
Implementando interface na plataforma API
Somente um subconjunto das interfaces foi designado para ser implementado pelos clientes. As interfaces API têm um contrato indicando os termos sob os quais ele pode ser implementado. As interfaces que são designadas para serem implementadas pelos clientes são explicitamente avisadas no comentário de classe Javadoc (com palavras como "Clientes podem implementar."). Um cliente pode declarar uma subinterface da interface API somente se for permitido implementá-la.
-
Implementadores restritos. Não implemente uma interface API que foi documentada como disponível somente para certas partes a menos que você seja uma delas. Em muitas situações, as interfaces são utilizadas para ocultar detalhes de implementação da exibição.
Implementando métodos de API públicos
Consulte "Substituindo métodos API".
Acessando Campos nas Classes e Interfaces da API
Os clientes podem ler campos API, muitos dos quais são finais. Determinadas estruturas tipo objetos podem ter campos públicos não finais, que os clientes podem ler e escrever a menos que indicado de outra forma.
-
Campos nulos Não defina um campo API como nulo a menos que seja explicitamente permitido.
Lançando Objetos de um Tipo de API Conhecido
Um objeto de um tipo conhecido de API pode ser lançado somente para um tipo de API diferente (ou lançado condicionalmente utilizando-se instanciar) se isso for claramente permitido na API.
-
Lançar e instanciar. Não utilize as expressões lançar e instanciar para aumentar o que é conhecido sobre um objeto além do que a API suporta. O uso impróprio expõe detalhes da implementação incidental não garantidos pela API.
E, claro, lançar um objeto para uma classe não API ou interface é sempre inapropriado.
Não Seguir as Regras
Se feito inadvertidamente ou com conhecimento, há conseqüências para a transgressão das
regras. Pode ser mais fácil para todos os envolvidos se houvesse uma política API que iria puni-lo por quebrar as regras. Entretanto, esse não é o caso.
Para a maioria das partes, a conformidade API opera como um sistema de honra, com cada cliente responsável por conhecer as regras e aderir às mesmas.
Os contratos dos elementos API delimitam o comportamento que é suportado e sustentado. À medida que a plataforma Eclipse amadurece e evolui, serão os contratos API que irão determinar como essa evolução acontece.
Fora desses contratos, tudo é sem suporte e sujeito à alterações, sem notificação e a qualquer tempo.(mesmo entre os releases ou entre diferentes plataformas OS). O código do cliente que ultrapassa as regras acima pode falhar em diferentes versões e em níveis de correção da plataforma; ou ao executar diferentes OSes subjacentes; ou quando executar um mix diferente de plug-ins coexistentes; ou quando executar com uma perspectiva de workbench diferente, e assim por diante. De fato, ninguém está particularmente interessado em especular exatamente como cada transgressão em particular pode voltar e prejudicar você. Para aqueles que escolhem ignorar as regras, não diga que não foram avisados.
E não espere muito mais que um simpático
"Eu avisei."
Por outro lado, o código de plug-in do cliente que vive sob as regras deve continuar a trabalhar nas diferentes versões e nos níveis de correção da plataforma, nas diferentes OSes subjacentes, e deve coexistir pacificamente com outros plug-ins. Se cada um obedecer às regras, a plataforma Eclipse fornecerá uma base estável e com suporte onde construir novos e interessantes produtos.