Olá Habr! Publicamos recentemente o livro “
Learning Java EE. Programação Moderna para Grandes Empresas ”, do campeão alemão de Java Sebastian Dashner.
O Sr. Dashner escreve e fala ativamente sobre tópicos relacionados ao Java EE moderno; portanto, seu blog não ignorou os princípios gerais de design da plataforma Jakarta EE, agora desenvolvida pela Eclipse. A tradução deste artigo em particular (junho) está trazendo a sua atenção hoje.
A plataforma EE de Jacarta está gradualmente assumindo o controle, e novas especificações para o desenvolvimento empresarial estão surgindo junto com ela. Para concordar com os vários padrões e tecnologias que estão prestes a surgir, toda a comunidade Java EE será beneficiada apenas se os princípios gerais de design para as especificações de Jakarta EE forem desenvolvidos.
Acredito que a tecnologia Java EE tenha sido tão bem-sucedida com apenas alguns princípios. A seguir, apresentarei meu ponto de vista sobre quais princípios de design desenvolvidos no Java EE me parecem os mais importantes, dignos de mais estudos e potencialmente podem servir como recomendações para o design no Jakarta EE.
Decidi escrever este artigo, inspirado nas propostas de Dmitry Kornilov sobre a direção em que o desenvolvimento técnico do Jakarta EE deveria seguir.
A primeira coisa é lógica de negóciosO modelo de programação adotado no Java EE permite que o desenvolvedor se concentre exatamente no que é necessário - ou seja, na lógica de negócios. Você não precisa mais herdar classes da API; o desenvolvedor pode expressar a lógica de sua área de assunto na linguagem Java usual e predominantemente declarativamente (usando anotações) controlar o comportamento do servidor de aplicativos. Assim, a estrutura se integra perfeitamente ao seu código e, em essência, também é fácil removê-la. Ao projetar, não confie na reutilização, mas na remoção fácil.
No entanto, as implementações devem aliviar ao máximo o desenvolvedor do trabalho mais difícil - ou seja, permitir que ele escape de requisitos técnicos que não estão relacionados à lógica de negócios. Exemplos são multithreading, transações, inversão de controle ou processamento de solicitação HTTP. No lado da aplicação, chato é bom :)
Parece-me importante que a estrutura não apenas não interfira na implementação da lógica de negócios, mas também incentive os programadores a trazer rapidamente recursos desenvolvidos à produção. Não há necessidade de polir a estrutura para brilhar - é melhor trazer o código da lógica de negócios ao ideal. Compare o moderno Java EE ou Spring com as versões antiquadas do J2EE - acho que você entenderá imediatamente o que quero dizer.
O Jakarta EE deve se desenvolver da mesma maneira e, consequentemente, se concentrar nas especificações que permitirão que os desenvolvedores implementem rapidamente a lógica de negócios.
Convenções de configuraçãoO Java EE minimiza a configuração necessária para definir um aplicativo corporativo típico. Na maioria das situações práticas, os acordos funcionam imediatamente, não é necessária nenhuma configuração. Portanto, você não precisa mais de arquivos XML para configurar um aplicativo Java EE simples. Outro exemplo é que o JAX-RS fornece códigos de resposta HTTP padrão que correspondem aos valores de retorno dos métodos JAX-RS.
O Java EE tem flexibilidade para modificar o comportamento e implementar scripts mais complexos; no entanto, não há acordo sobre isso.
O Jakarta EE deve continuar a transformar o simples em fácil e o complexo em possível.
Especificações de interoperabilidadeJakarta EE deve continuar e expandir a interoperabilidade das especificações. O Java EE está em conformidade com as especificações existentes e a funcionalidade presente nelas, que já se tornou parte do padrão.
Os desenvolvedores podem confiar em especificações diferentes para interagir bem entre si, sem nenhuma configuração necessária. Padrões exigidos: se o ambiente de tempo de execução suportar a especificação A e a especificação B, A + B deve interagir entre si. Exemplos: a validação de componente, JAXB ou JSON-B pode ser usada nas classes de recursos JAX-RS e nenhuma configuração adicional é necessária.
Injeção de Dependência e CDIObviamente, é indesejável para o Jakarta EE reinventar o que já existe - por exemplo, injeção de dependência relacionada ao CDI. É desejável que as especificações usem e enfatizem os pontos fortes do JSR 330 ou, se necessário, CDI.
Um exemplo
UriInfo
é o uso do
UriInfo
do JAX-RS em métodos de recursos. A anotação
@Inject
ainda não suporta a implementação desse tipo de método. É mais conveniente para o programador trabalhar, mais ele depende do mecanismo universal.
Outra medida específica é a seguinte: os provedores de CDI devem ser fornecidos nas especificações e, se necessário, qualificadores seguros para os tipos que precisam ser criados. Portanto, no momento, a instância do cliente JAX-RS pode ser obtida apenas programaticamente, por meio da API
ClientBuilder
. Fabricantes e qualificadores simplificam o trabalho de um programador, fornecendo definições declarativas.
Abordagens declarativasPor tudo isso, a Java EE API depende muito de uma abordagem declarativa, enquanto usa inversão de controle. Portanto, os desenvolvedores não chamam a funcionalidade diretamente; o contêiner é responsável por chamar o funcional, enquanto contamos com definições de código. Exemplos (das especificações mais atuais) são JAX-RS, JSON-B ou CDI.
O Jakarta EE não apenas fornece APIs de software mais abrangentes, como também facilita o uso de definições declarativas e inversões de controle.
Estratégias de implantaçãoUma característica distintiva (e na minha opinião uma grande vantagem) do Java EE é o modelo de implantação proposto aqui, no qual os problemas de lógica de negócios se dissociam da implementação. O desenvolvedor programa exclusivamente para a API, que não faz parte do artefato de implementação e é implementado pelo contêiner do aplicativo.
Esses artefatos compactos de implantação simplificam e aceleram a entrega do programa, incluindo montagem, publicação e implantação como tal. Eles também são compatíveis com os níveis do sistema de arquivos do contêiner usado, por exemplo, no Docker. Durante o processo de montagem, você só precisa reconstruir ou reenviar os elementos alterados.
Idealmente, os artefatos de implementação devem conter apenas lógica de negócios e nada mais; implementações de tempo de execução e bibliotecas de terceiros potencialmente adicionadas são entregues em um nível inferior, por exemplo, nas bibliotecas do servidor de aplicativos adicionadas no estágio anterior da montagem do contêiner.
No Jakarta EE, os artefatos implementados também devem ser considerados entidades de primeira classe. Talvez haja uma oportunidade de aumentar ainda mais o ambiente de tempo de execução com base nas especificações exigidas pelo aplicativo. No entanto, o Jakarta EE espera prestar a máxima atenção à lógica comercial e à produtividade do desenvolvedor, e o refinamento do tempo de execução já é secundário.
TestabilidadeAplicando os princípios acima, especialmente dando preferência à programação declarativa e injeção de dependência, estamos melhorando a testabilidade do código comercial. Assim, os desenvolvedores podem instanciar objetos diretamente nos scripts de teste, porque agora você não precisa herdar classes de API ou chamar funcionalidades inconvenientes que você precisaria simular anteriormente.
No entanto, no Jakarta EE, é necessário refinar seriamente a padronização dos testes de integração no nível do código, para que não dependa do fabricante. Anteriormente, era exatamente com isso que você tinha que lidar ao trabalhar com o Arquillian. Em projetos reais, esse padrão seria útil, o que permite declarar apenas cenários de implantação de teste e chamar a funcionalidade de um ou mais componentes. Escrevi anteriormente que não considero extremamente importante o teste de integração no nível do código, por exemplo, ao executar um aplicativo em contêineres internos. No entanto, se você padronizar os testes de integração no nível do código, isso claramente terá um efeito positivo.
ConclusãoEu acho que não é coincidência que as APIs Java EE sejam tão amplamente usadas em projetos reais: essas APIs são bem pensadas e projetadas de acordo com princípios claros, graças aos quais foi possível unificar não apenas uma única especificação, mas uma plataforma inteira. Eles permitem que você use várias especificações ao mesmo tempo, sustentadas no mesmo espírito. Aqui, conseguimos nos livrar de obstáculos artificiais que apenas complicam o trabalho do programador - portanto, acredito, todo o desenvolvimento da empresa se tornou muito mais agradável.