Estou trabalhando em um projeto de estágio, mas tenho que sair antes que eu possa terminar tudo.
Eu tenho 1 classe que não é estável o suficiente para uso em produção. Quero marcar / sinalizar esta classe para que outras pessoas não a usem acidentalmente na produção. Eu já coloquei o aviso em Javadoc, mas isso não parece suficiente. Algum erro ou aviso do compilador seria melhor.
O código está organizado assim:
[Package] | company.foo.bar.myproject
|-- Class1.java
|-- Class2.java
|-- Class3.java <--(not stable)
Se houvesse uma única classe de fábrica que chama essas classes em métodos públicos, eu poderia ter definido o método class3
como private
. No entanto, a API NÃO é exposta dessa maneira. Os usuários usarão diretamente essa classe, por exemplo new Class1();
, mas eu não posso tornar uma classe de nível superior privada. Qual é a melhor prática para lidar com essa situação?
Respostas:
Por que não apenas verificar todas as classes instáveis em uma ramificação diferente no seu sistema de controle de versão?
fonte
Se você tiver comentado corretamente a classe, poderá marcar os bits da funcionalidade incompleta como "obsoletos" e / ou comentar os detalhes do método e colocar a
throw new UnsupportedOperationException();
.Consulte Existe algo como o NotImplementedException do .NET em Java? para detalhes.
fonte
Não conheço esse aviso do compilador.
Na sua situação, eu provavelmente usaria a
@Deprecated
anotação. Ele cruzará as chamadas de método, para que seja óbvio para os outros que algo está acontecendo. Quando eles analisarem o que está acontecendo, eles verão seus comentários sobre "a produção não está pronta" e serão enviados para a AHA.fonte
Eu não acho que há uma maneira padrão de marcação código como
WIP
,Incomplete
ou algo parecido.Você pode criar uma nova exceção chamada
ClassUnstableException
e, em seguida, aumentá-la noClass3
construtor com uma mensagem que explica como eles não devem usá-la. Isso é ruim, porque apenas os avisa em tempo de execução.Você também pode tentar tornar a classe incompilável de alguma forma e, em seguida, adicionar uma nota à seção de código que aciona o compilador, de modo que, se alguém for consertar o código, esperançosamente verá uma explicação de por que não deve usar essa classe. . Isso pode não funcionar se eles usarem uma ferramenta semi-automatizada de "corrigir esse problema" que alguns IDEs possuem. Isso também é ruim porque pode quebrar as compilações.
Você pode criar uma anotação chamada
WIP
(já que a mais próxima que eu consigo pensar é,Deprecated
mas na verdade não significa a mesma coisa) e usá-la para anotar a classe. Provavelmente isso seria um pouco mais trabalhoso, e o que apoiaria a anotação?Por fim, você pode colocá-lo nos comentários, mas isso só funcionará se as pessoas realmente os lerem .
EDITAR:
Isso pode ser relevante: Como causar intencionalmente uma mensagem de aviso do compilador java personalizado?
fonte
Por que está lá em primeiro lugar?
Você verificou código instável na linha principal? Por quê?
O código instável não deve ser verificado no tronco / principal / mestre ou seja qual for o nome do tronco principal. Isso é considerado um desenvolvimento de alto risco e, em vez disso, deveria ter sido isolado em seu próprio ramo em que você trabalhou, em vez de fazer o check-in no main.
Eu o incentivaria fortemente (e o líder da sua equipe) a ler Estratégias avançadas de ramificação do SCM . Em particular, preste atenção ao papel do desenvolvimento e ao que ele diz sobre o que é considerado desenvolvimento de alto risco:
Permitir que as pessoas verifiquem código instável (ou não usado) na linha principal significa que você confundirá esforços futuros de desenvolvimento sobre a tentativa de manter esse código. Cada ramo e clone do representante a partir de agora até o final dos tempos conterá isso até que alguém diga "seu código morto" e o exclua.
Há quem diga "bem, se estiver em um ramo, ele será esquecido" e, embora isso possa ser verdade, ter esquecido o código morto (e instável) na linha principal é muitas vezes pior, pois confunde todo o desenvolvimento futuro até que seja removido - e então é ainda mais esquecido. Um ramo bem nomeado de "/ fooProject / branches / WeisBigIdea" (ou equivalente) é visível e mais fácil de se trabalhar no futuro - especialmente se funcionar.
@Deprecated
A primeira coisa é a
@Deprecated
anotação. Isso vai além do javadoc e cospe avisos do compilador.javac
fornece um-deprecation
sinalizador descrito como:Como observado, isso vai além dos avisos padrão do compilador.
Em muitos IDEs, métodos e valores obsoletos são mostrados com um rasurado:
E produziria saída como:
Dependendo da sua estrutura de construção, você pode receber avisos para interromper a construção. Isso apenas interromperia a compilação se uma de suas classes fosse usada (não se for simplesmente compilada).
@CustomAnnotation
Existem muitas abordagens para isso. Por exemplo, a anotação Lightweight javac @Warning, que fornece um processador de anotações que dispara um aviso no momento da compilação quando algo com essa anotação é usado ( um tutorial do netbeans sobre processadores de anotações personalizados, para que você possa ter uma idéia do que está acontecendo por trás do cenas).
A Oracle ainda descreve um exemplo de uso de anotações personalizadas para uma
@Unfinished
anotação em Aproveitando ao máximo os metadados do Java, parte 2: anotações personalizadas .Com o AnnotationProcessor , você pode executar código arbitrário em tempo de compilação. É realmente você quem decide o que deseja fazer. Aviso, quebre a construção quando algo for usado. Existem inúmeros tutoriais disponíveis na Web sobre como escrever esse tipo de código. Se você deseja gerar um erro quando ele é compilado (isso será irritante e leva à exclusão) ou se é usado (um pouco mais complexo de escrever).
Observe que tudo isso implica alterar as compilações para realmente usar o processador de anotações.
fonte
Você pode introduzir o processamento da anotação em tempo de compilação, mas isso forçaria todos os membros da equipe a ajustar seu processo de compilação.
No entanto, acho todo o processo um pouco confuso. Uma API instável deve ser claramente separada criando uma ramificação em seu sistema de controle de versão. Se ele realmente precisa estar no restante da base de código, foi documentado como instável e, no entanto, usado, o problema não é realmente técnico, mas está dentro da organização e da comunicação. Sim, você pode introduzir verificações técnicas (como o processamento de anotações), mas isso não resolveria o problema - basta movê-lo para outro nível.
Portanto, minha recomendação é: se você não pode separar a base de código colocando-a em diferentes ramos, converse com as pessoas e explique a elas por que elas não devem usar a API.
fonte
Você poderia mover todas as classes incompletas para um subpacote chamado algo óbvio como "NOTCOMPLETE"? É um pouco complicado, mas pode ser visível o suficiente.
(Se eles não estiverem todos no mesmo pacote, você poderá recriar a estrutura do pacote.)
fonte
Não sei se existe realmente uma boa maneira de fazer isso no código. Dê um passo para trás:
Crie duas cópias de todo o projeto, uma com a classe e outra sem. Marque a versão sem a classe como uma base de código estável, pronta para o release de produção e a versão com a classe como desenvolvimento para um release futuro. Documente o que precisa acontecer antes que essa classe possa ser considerada como qualidade de produção.
Idealmente, você deve fazer isso usando ramificações em sua solução de controle de origem de sua escolha. Talvez você precise trapacear um pouco, pois parece que você não está usando uma estratégia de ramificação. Remova com cuidado a nova classe, faça o check-in de uma versão sem ela e faça alguns testes de regressão. Quando estiver satisfeito, é estável, você pode marcar essa revisão, criar um ramo de desenvolvimento a partir da marca e adicionar a classe novamente no ramo de desenvolvimento.
fonte
Eu optaria por tornar a classe abstrata e comentar adequadamente - dessa forma, o código ainda está lá para referência, mas boa sorte para quem tentar instanciar :)
fonte
Que tal criar uma dependência que o compilador não pode resolver? Basta adicionar:
importar este.não.um.done.no.do.não.utilizar;
para o topo. Os usuários não poderão compilar com ele.
Se você quiser testar a classe, simplesmente crie um pacote / classe com esse nome (ou use um mais simples como "experimental.danger") e poderá testar o novo código.
fonte