Artigo no estilo: Curso

Do que se trata o artigo:

Este artigo visa mostrar o processo de refatoração e evolução de código, melhorando o reuso e a legibilidade do mesmo, além de técnicas de melhoria de performance, aplicando ambos sobre a aplicação desenvolvida nos dois primeiros artigos dessa série.

Em que situação o tema é útil:

O artigo mostra ao leitor como a refatoração pode ajudar na melhoria da legibilidade e reusabilidade de código, além de apresentar técnicas para melhorar a performance de aplicações que utilizam JPA para o mapeamento objeto relacional.

Java EE 6: Da configuração aos testes – Parte 3:

O processo de refatoração ganhou ainda mais importância com o advento das metodologias ágeis, pois estas focam bastante nesse processo e na criação de testes automatizados, que é a base para a execução da refatoração com segurança. Outro ponto que tem conquistado cada vez mais destaque é a importância dos requisitos não funcionais, como performance.

Esses dois tópicos serão atacados durante essa última parte do artigo, mostrando como melhorar a reusabilidade do código construído até o momento, e apresentando técnicas de melhoria de performance para aplicações que utilizam mapeamento objeto relacional com JPA.

Na parte anterior do artigo, desenvolvemos os testes automatizados para o back-end da aplicação, falando da sua importância e como o framework Arquillian pode nos auxiliar nessa tarefa, facilitando a criação e gerenciamento dos testes. Além disso, também desenvolvemos o front-end da aplicação, usando tecnologias atuais e bastante produtivas, como JSF 2, CDI e PrimeFaces. Ao final, a aplicação exemplo estava totalmente pronta e funcional.

Nessa terceira e última parte do artigo, iremos abordar outros dois assuntos de extrema importância no processo de desenvolvimento e evolução do software: refatoração e melhorias de performance.

Refatoração é o processo de evoluir e melhorar a estrutura interna do software, visando maior legibilidade/entendimento, reusabilidade e manutenibilidade, sem que a estrutura externa do mesmo seja modificada. E como garantir que nenhuma dessas alterações internas quebre o funcionamento externo do sistema? Através dos testes! Conforme falamos na segunda parte do artigo, uma das vantagens de se ter uma suíte de testes automatizados é justamente a possibilidade de testar todo o sistema com apenas um clique. Refatorar um sistema sem que o mesmo possua um bom conjunto de testes pode ser uma tarefa bastante arriscada.

Outro ponto que vamos falar um pouco é sobre performance. Mais do que nunca, esse é um tema que deve estar sempre em evidência na pauta dos arquitetos e desenvolvedores, e alguns motivos para isso são a maior exigência dos usuários e o grande volume de dados/acessos a serem tratados pelas aplicações. Porém, os pontos a serem atacados para melhorar a performance geralmente variam de aplicação para aplicação, pois dependem de fatores como tecnologias utilizadas e o perfil da aplicação. Nesse artigo serão apresentados alguns pontos genéricos para melhorar a performance de aplicações Java EE, principalmente no que diz respeito ao mapeamento objeto relacional com JPA.

Refatorando código

Quantas vezes olhamos um trecho de código e achamos que ele pode ficar melhor e mais claro? Quantas vezes você já olhou um código que fez há algum tempo e pensa: “que código feio”? O normal nesse caso é você pegar e alterar o código para que ele fique mais limpo e claro. É natural e desejável que com o passar do tempo nós, desenvolvedores, passemos a ter uma visão mais crítica sobre qualidade de código. Essa visão crítica ajuda no processo de melhoria de código, conhecido como refatoração. As metodologias ágeis dão bastante importância para esse conceito, porém, independente da metodologia de desenvolvimento utilizada, a refatoração é um processo que deve ser realizado sempre que possível, pois melhora a qualidade do código, facilitando a manutenção e a adição de novas funcionalidades.

Observando trechos da classe ClienteMB (Listagem 1), desenvolvida no artigo anterior dessa série, podemos perceber que alguns métodos utilitários foram definidos em seu conteúdo. Isso é ruim, pois conforme novos Managed Beans forem sendo adicionados, esses precisarão desses mesmos métodos e, da forma como o código está estruturado, seria necessário replicar o código para cada um deles. Sendo assim, veremos agora como melhorar a distribuição e reusabilidade desse código.

Listagem 1. Código da classe ClienteMB.


  package br.com.javamagazine.jee6.crud.cliente.web.mb;
   
  //imports omitidos...
   
  //alguns métodos também foram omitidos...
   
  @Named
  @SessionScoped
  public class ClienteMB implements Serializable {
    // bundle com as mensagens internacionalizaveis
    private ResourceBundle bundle;
   
    @PostConstruct
    public void init() {
      this.bundle = ResourceBundle.getBundle("messages", getFacesContext()
          .getViewRoot().getLocale());
    }
   
    public void load() {
      if (!getFacesContext().isPostback()) {
        if (idCliente != null) {
          cliente = clienteServices.findById(idCliente);
          if (cliente == null) {
            redirect("list.xhtml");
          }
        }
        else {
          cliente = new Cliente();
        }
      }
    }
   
    public String save() {
      try {
        clienteServices.save(cliente);
        addMessageFromBundleInFlash(FacesMessage.SEVERITY_INFO,
            "label.cliente.salvo");
        limpar();
        return "list?faces-redirect=true";
      }
      catch (ClienteExistenteException e) {
        getFacesContext().addMessage(
            null,
            new FacesMessage(FacesMessage.SEVERITY_ERROR, "", bundle
                .getString("label.cliente-existente")));
      }
      catch (NenhumTelefoneInformadoException e1) {
        getFacesContext().addMessage(
            null,
            new FacesMessage(FacesMessage.SEVERITY_ERROR, "", bundle
                .getString("label.nenhum-telefone-informado")));
      }
      return null;
    }
   
    private void redirect(String pagina) {
      try {
        getFacesContext().getExternalContext().redirect(pagina);
      }
      catch (IOException e) {
        e.printStackTrace();
      }
    }
   
    public void addMessageFromBundleInFlash(Severity severidade, String chave) {
      Flash flash = getFacesContext().getExternalContext().getFlash();
      flash.setKeepMessages(true);
      getFacesContext().addMessage(null,
          new FacesMessage(severidade, null, bundle.getString(chave)));
    }
   
    private FacesContext getFacesContext() {
      return FacesContext.getCurrentInstance();
    }
    
  }  ... 

Quer ler esse conteúdo completo? Tenha acesso completo