Métodos

Este artigo discute vários aspectos da criação de métodos, visando usabilidade, robustez e flexibilidade.

Item 23: Verifique a validade dos parâmetros
Aplicando o princípio de que um erro deve ser detectado o mais cedo possível depois de ocorrer, valores válidos para os parâmetros devem ser verificados logo no início do método, evitando erros posteriores mais difíceis de serem identificados.
Em métodos públicos, documente a restrição e utilize a tag
@throws do Javadoc para indicar a exceção que será lançada se ela for violada, que normalmente será IllegalArgumentException, IndexOutOfBoundsException ou NullPointerException.
Já no caso de métodos que não são exportados, o autor do pacote deve assegurar que só serão enviados valores corretos para o método, portanto a verificação deve ser realizada através do mecanismo de assertions ao invés das checagens normais.
Se a checagem da validade do parâmetro já estiver implícita no processamento do método e for muito custoso realizar a verificação no início, é aceitável que ela não ocorra. No caso da exceção lançada naturalmente pelo método ser diferente da que seria utilizada na validação do parâmetro, deve ser feita sua tradução, como será descrito no item 43.
É importante ressaltar que o melhor é escrever seus métodos de forma que consigam lidar de forma geral com os parâmetros, colocando apenas o mínimo de restrições necessárias para seu funcionamento correto.

Item 24: Crie cópias defensivas quando necessário
Apesar do Java ser uma linguagem segura, não permitindo o acesso direto à memória, é necessário programar de maneira defensiva, assumindo que os clientes de sua classe tentarão destruir sua  estabilidade, o que pode ocorrer propositalmente, se alguém tentar quebrar a segurança, ou por um simples engano de um programador.
No caso de construtores que recebem objetos mutáveis como parâmetro, é essencial criar uma cópia do mesmo e utilizá-la como componente da classe, evitando as conseqüências do objeto original ser alterado. Note que a validação dos parâmetros deve ser feita já na cópia, não criando uma janela de vulnerabilidade entre o tempo que são feitas a validação e a cópia. Além disso, não utilize o método clone para fazer a cópia caso o parâmetro seja de uma classe não final, e sim crie um novo objeto que contenha os mesmos valores. Outra precaução que deve ser tomada é não retornar os objetos internos mutáveis em métodos accessors, e sim uma cópia dos mesmos.
Claro que se for previsto que a classe controle o objeto fornecido por um cliente, não é feita a cópia defensiva, e sim utilizado o original. Mas isso deve estar explícito na documentação e deve haver confiança entre as classes que estão compartilhando o objeto.

Item 25: Planeje a assinatura dos métodos cuidadosamente
Alguns itens que devem ser considerados na criação de métodos:
- Escolha os nomes cuidadosamente. Obedeça às convenções, e deixe os nomes compreensíveis e consistentes com os outros nomes no mesmo pacote (e da API do Java);
- Não inclua métodos desnecessários, pois seu excesso torna a classe mais difícil de aprender, usar, documentar, testar e manter. Para cada ação suportada pelo seu tipo (incluindo interfaces), inclua um método funcional;
- Evite listas de parâmetros longas. Muitos parâmetros confundem o programador, especialmente se alguns forem do mesmo tipo. Soluções para esse caso são dividir o método ou utilizar uma classe auxiliar para armazenar os parâmetros;
- Para os tipos dos parâmetros, prefira interfaces a classes, dando mais flexibilidade ao método;
- Utilize objetos de função apenas quando houver uma razão legítima, como no caso da implementação de um Strategy ou Visitor;

Item 26: Utilize overloading (sobrecarga) de forma adequada
A escolha de qual método overloaded será utilizado é feita em tempo de compilação. Por exemplo, tendo a seguinte array:
Collection[] tests = new Collection[] {new HashSet(), new ArrayList(), new HashMap().values()};
E fazendo um loop em que é chamado um método
classify que está sobrecarregado para receber Set, List ou Collection, para as três instâncias ele irá chamar o de Collection, ainda que em tempo de execução o tipo seja diferente É a idéia oposta dos métodos overriden (herdados), que são aplicados de acordo com o tipo da instância e não da variável que a declara. Portanto, evite overloads confusos, que aumentam a chance de um programador usando a classe tomar uma decisão errada. A regra mais segura é nunca exportar dois métodos overloaded com o mesmo número de parâmetros. Se isso não for possível, que pelo menos os tipos sejam mutuamente exclusivos por cast. E por fim, se for possível receber o mesmo objeto em 2 métodos diferentes, eles devem ter o mesmo comportamento para este parâmetro.

Item 27: Retorne arrays de tamanho zero, não nulls
Não há motivo para retornar null em um método que retorna um tipo de array. É melhor retornar uma array de tamanho zero, evitando erros no método que recebe esse valor caso ele esqueça de testar e tratar o null.

Item 28: Escreva comentários de documentação (javadoc) para todos os elementos expostos da API
O javadoc provê um meio efetivo de documentar sua API e mantê-la sempre atualizada, devendo ser usado amplamente.
Todas as classes, interfaces, construtores, métodos ou declaração de campos exportados devem ser precedidos por um comentário.
A documentação de um método deve descrever sucintamente o contrato entre o método e seu cliente. Ela deve dizer o que o método faz ao invés de como faz. Deve enumerar as pré-condições (através da
@throws, @param ou descrição), pós-condições e efeitos colaterais. Também deve estar indicada a segurança em relação a threads. Devem ser incluídas as tags @param para cada parâmetro, @return se o tipo de retorno não for void e @throws para as exceções que podem ser lançadas (checked ou unchecked), seguidas pela descrição do parâmetro ou retorno ou da condição em que a exceção é lançada.
É permitido usar HTML para uma melhor formatação do texto no javadoc.
A primeira sentença de cada comentário de javadoc é a descrição resumida do elemento. Tenha cuidado para que ela não contenha um ponto (por exemplo em uma abreviação), pois isso quebraria a sentença antecipadamente. Se for necessário ele deve ser substituído por "."
Há um mecanismo de reuso de documentação automática caso ela não seja fornecida para um método, utilizado no caso de interfaces ou superclasses. Ele é prático para evitar manter várias cópias de um mesmo comentário, mas não permite que seja alterado, sendo necessário reescrever todo comentário caso o do método da classe em questão seja mais especializado.
Algumas vezes a API é muito complexa e a documentação gerada pelo javadoc não é suficiente, sendo necessário incluir um link para uma documentação mais completa.




Bibliografia:
Bloch, Joshua. Effective Java.

Resumo por: Vanessa Sabino
1