Arquivo de março, 2014

E ai galera do Java, tranquilo?

Hoje vamos tratar de algo que é super simples, mas de extrema importância no mundo java…. Os tão famosos javadoc.

O que são javadoc?

Javadoc é aquela documentação que utilizamos em cima de classes, métodos e atributos e servem para identificar sua funcionalidade. Para ficar mais claro, vamos ver um exemplo de código:

package javaapplication1;

public class Calcular {
    private Double valor1;
    private Double valor2;

    public Double somar(Double valor1, Double valor2){
        Double calculo = 0.0;
        calculo = valor1 + valor2;
        return calculo;

    }
    public Double subtrair(Double valor1, Double valor2){
        Double calculo = 0.0;
        calculo = valor1 - valor2;
        return calculo;

    }
    public Double multiplicar(Double valor1, Double valor2){
        Double calculo = 0.0;
        calculo = valor1 * valor2;
        return calculo;

    }
    public Double dividir(Double valor1, Double valor2){
        Double calculo = 0.0;
        if (valor2 != 0){
            calculo = valor1 / valor2;
        }
        else {
            System.out.println("ERRO! Divisão por 0!");
        }


        return calculo;
    }

    public Double calcularComplexo(Double valor1, Double valor2){
      Double calculo = 0.0;  
        // faz calculos que apenas de pensar dai a nossa cabeça
        return calculo;
    }

    public Double getValor1() {
        return valor1;
    }

    public void setValor1(Double valor1) {
        this.valor1 = valor1;
    }

    public Double getValor2() {
        return valor2;
    }

    public void setValor2(Double valor2) {
        this.valor2 = valor2;
    }    
}

Ok, o exemplo de código é bem simples e parece não precisar de nenhum tipo de explicação, certo? Temos ai o nossas variáveis de classe, seus gets e sets e alguns métodos, todos simples fazendo a soma, subtração, divisão, multiplicação e ….. calcularComplexo? O que esse método faz? Quais são esses números? O que ele retorna? Se você for o programador do método irá saber o que ele faz, mas se você for o utilizador do método e não tiver acesso ao código fonte? Ou pior, tem acesso ao código, mas não consegue entender o que ele faz? Para ter uma ideia do que cada método faz terá que ir testando eles como abaixo.

package javaapplication1;

public class JavaApplication1 {

    public static void main(String[] args) {
     Calcular calc = new Calcular();

        System.out.println("Divisão: " + calc.dividir(5.0, 12.0));
        System.out.println("Multiplicação: " + calc.multiplicar(23.0, 2.0));
        System.out.println("Subtração: " + calc.subtrair(2.0, 3.0));
        System.out.println("adição: " + calc.somar(7.0, 6.0));
        System.out.println("Calculo complexos: " + calc.calcularComplexo(1.0, 6.0));

    }

}

Vamos ser sinceros, é inaceitável ter que criar um novo projeto para entender os métodos.

Bom, esse código é uma brincadeira, mas é uma realidade do mercado do desenvolvimento onde muitos programadores não documentam o código devido a pressão dos prazos ou por pura preguiça. Hoje o mercado de desenvolvimento possui diversas ferramentas para avaliar a qualidade de código e entre as análises está a cobertura de documentação no código o que significa que documentar o código (inserir javadocs) é uma boa prática de desenvolvimento.

Agora vamos ver o código documentado com os javadoc.

package javaapplication1;

/**
 *Classe especialista na realização de calculos de matemática.
 * @author aricesar
 */
public class Calcular {


    private Double valor1;
    private Double valor2;

    /**
     * Método que executa a soma de dois valores sejam eles positivos ou negativos.
     * 
     * @param valor1 - > valor Double
     * @param valor2 - > valor Double
     * @return valor calculado (tipo Double)
     */
    public Double somar(Double valor1, Double valor2){
        Double calculo = 0.0;
        calculo = valor1 + valor2;
        return calculo;
    }


    /**
     * Método que executa a subtração de dois valores sejam eles positivos ou negativos.
     * @param valor1 - > valor Double
     * @param valor2 - > valor Double
     * @return valor calculado (tipo Double)
     */
    public Double subtrair(Double valor1, Double valor2){
        Double calculo = 0.0;
        calculo = valor1 - valor2;
        return calculo;
    }

    /**
     * Método que executa a multiplicação de dois valores sejam eles positivos ou negativos.
     * @param valor1 - > valor Double
     * @param valor2 - > valor Double
     * @return valor calculado (tipo Double)
     */
    public Double multiplicar(Double valor1, Double valor2){
        Double calculo = 0.0;
        calculo = valor1 * valor2;
        return calculo;

    }

    /**
     * Método que executa a divisão de dois valores sejam eles positivos ou negativos. 
     * Impede o erro de divisão por zero.
     * @param valor1 - > valor Double
     * @param valor2 - > valor Double ( não pode ser zero)
     * @return valor calculado (tipo Double)
     */
    public Double dividir(Double valor1, Double valor2){
        Double calculo = 0.0;
        if (valor2 != 0){
            calculo = valor1 / valor2;
        }
        else {
            System.out.println("ERRO! Divisão por 0!");
        }


        return calculo;
    }

    /**
     * Executa calculos complexos subtraindo, dividindo, multiplicando e somando os valores passados por parametro. Pode retornar qualquer valor.
     * 
     * @param valor1 - > valor Double
     * @param valor2 - > valor Double
     * @return valor calculado (tipo Double)
     */
    public Double calcularComplexo(Double valor1, Double valor2){
      Double calculo = 0.0;  
      // faz calculos que apenas de pensar dai a nossa cabeça
        return calculo;
    }

    /**
     * Getter do valor 1
     * @return valor 1
     */
    public Double getValor1() {
        return valor1;
    }

    /**
     * Setter do valor 1
     * @param valor1 
     */
    public void setValor1(Double valor1) {
        this.valor1 = valor1;
    }

    /**
     * Getter do valor 2
     * @return valor 2
     */
    public Double getValor2() {
        return valor2;
    }

    /**
     * Setter do valor 2
     * @param valor2
     */
    public void setValor2(Double valor2) {
        this.valor2 = valor2;
    }

}

Melhorou? Agora quando alguém for utilizar o código da classe Calcular os comentários serão apresentados e o programador saberá o que faz cada um dos métodos.

Quer ver funcionando? Crie um projeto, crie uma classe chamada Calcular e copie esse último código que possui os comentários. Depois crie uma nova classe e copie o código abaixo para dentro dela.

    public static void main(String[] args) {
     Calcular calc = new Calcular();

    }

Depois disso, faça o import necessário para funcionar a classe Calcula e escreva calc. (se precisar use CTRL+ para ativar o autocomplete). Escolha algum dos métodos da classe Calcular e verá o javadoc que criamos para ele.

Uma ultima observação de qualidade de código: Um bom método é auto-explicativo o que significa que o nome do método e seu javadoc devem ser mais do que suficientes para explicar o que ele é e o que faz. Nunca, em hipótese alguma, um programador deve necessitar acessar o código do método para entender para que ele serve, Esse tipo de coisa caracteriza um método mal documentando ou com problema de nomenclatura.

Se quer um bom exemplo de documentação de uma olhada nós códigos nativos do java. Você verá que cada classe e método possuiu seu javadoc.

Bem, é isso, até a próxima.

Anúncios

FEA-JV8-001 – Novidades Java 8: porque tanta expectativas?

Publicado: 04/03/2014 por Guilherme Weizenmann em Básico, java
Tags:,

Olá Pessoal.

Estive olhando as novidades do Java 8 e resolvi reportar um pequeno resumo. Desde o Java 5, uma nova versão do Java nã era tão aguardada. No Java 5 foram aicionados Annotations e Generics. O Java 8 irá estreiar Lambdas e Streams.

Gordan Freeman, at Black Mesa, Lambda Core

Lambdas são um rescurso genérico, derivado de conceitos funcionais, e muito similar a Scala (outra lingagem que roda na JVM). A descrição do recurso é a seguinte:

Expressões Lambda são uma nova e importante funcionalidade no Java SE 8. Elas provêm uma forma clara e concisa de representar 1 método de uma interface usando uma expressão. Expressões Lambda também melhoram as bibliotecas Collection fazendo com que seja fácil iterar sobre, filtrar e extrair dados de uma Collection. Adicionalmtente, novas funcionalidades de concorrência melhoram a performance em ambientes multiprocessados.
Java SE 8: Lambda Quick Start em 04/03/2014 em inglês. Tradução do autor.

A idéia básica é facilitar o desenvolvimento, principalmente de códigos que iteram sobre collections, baseado em interfaces, que também trazem novidades, devido aos Lambdas. A parte da concorrência é implementada por “debaixo dos panos”, pra você não ter que se preocupar com isso.

Olhando através do espelho

As interfaces, até o Java 7, serviam para criar assinaturas de métodos, sem implementação padrão. Mas com o surgimento dos Lambdas, e a necessidade de manutenção de código legado temos o seguinte problema:

Se alterarmos uma interface em um projeto já existente, e adicionarmos um método a ela, obrigaremos todas as classes que implementam essa interface a implementar esse novo método, quebrando assim o código existente.

Visando resolver esse problema, no Java 8 foram introduzidos os “métodos padrões” (Default Methods, também chamados “virtual extension methods” ou “defender methods”). São métodos com implementação padrão em Interfaces. Esses métodos com implementação padrão não precisam ser implementados pelas subclasses, mas podem ser sobrescritos se preciso. Assim é possível alterar um interface sem quebrar compatibilidade. Como as interfaces dos Collection foram modificadas com o adventos dos Lambda, foi preciso a criação dos métodos padrões para evitar a quebra de código ou o mega trabalho para ajustar tudo.

Mas lembre-se, as interfaces não guardam estados e não são, portanto, substitutas das classes abstratas. Classes abstratas e interfaces ainda são diferentes e tem funções diferentes.

Outra coisa importante: múltiplas heranças. Com os métodos padrões surge um problema. Dadas duas interfaces com métodos de mesmas assinatura, com implementação padrão, qual deverá ser escolhido? O problema, no Java, é resolvido em tempo de compilação. A classe deverá implementar (sobrescrever o método em questão, mesmo que seja chamando a implementação default de uma das interfaces implementadas) ou o compilador irá gerar uma mensagem de erro e não compilará a classe.

Seguindo o fluxo do rio

Aleḿ das alterações em interfaces e surgimento dos Lambdas, surgem também os Streams. Mas o que são?

Wrappers sobre coleções que suportam várias operações convenientes e de alta performance expressadas sucintamente com Lambdas.
Java 8 Tutorial: Lambda Expressions, Streams, and More – Java 8 Streams Part 1 em 04/03/2014 em inglês. Tradução do autor.

Streams não guardam dados, mas possuem uma entrada de dados baseada, por exemplo, em um ArrayList. Recuperando o stream dessa lista, pode-se facilmente aplicar operações em cada elemento (forEach), como aplicar filtros (filter), entre outras. O importante de lembrar é que esses métodos foram feitos para se trabalhar com Lambdas.

Pequenos detalhes

Além dessas grandes mudanças, outras pequenas serão adicionadas. Citarei apenas algumas:

  • Nashorn JavaScript Engine: suporte a javascript embarcado e disponível para qualquer aplicação
  • Repeating Annotations: atualmente cada anotação somente pode ser usada uma vez (na classe, método, prorpiedade). O Java 8 terá suporte a repetição de anotaçãoes!
  • Java Time API: nova api para trabalhar com datas e horas, substituindo o velho e proplemático java.util.Date

E se eu encontrar outra que vale a pena postar, eu atualizo o post…..

Going back home

Pra terminar, fazendo um resumo do resumo, Lambdas são a grande novidade, trazendo mudanças em várias outras estruturas do Java. Com isso, será mais rápido desenvolver, sem perder compatibilidade com o que já existe, e mais rápido operar sobre collections.

Até mais e obrigado pelos peixes!