Erros mais freqüentes


Parâmetros sem significado

Pergunta: Qual é a interface de uma classe?  Em outras palavras, o que é que uma pessoa deve conhecer sobre a classe para utilizá-la?
Resposta: as assinaturas dos métodos não privados. (Daqui em diante passarei a tratar o construtor como um método).
Em suma, o que estou tentando dizer com        tudo isto? Um exemplo ilustrará o problema:

public Livro (String t, String a, int n)

Alguém pode dizer que parâmetros devem ser passados para este construtor de Livro? Nem eu.
A regra de ouro do jogo é a seguinte: os nomes dos parâmetros devem indicar os seus significados. Esta é a única forma de se garantir que uma outra pessoa (possivelmente um  membro da sua equipe do projeto) possa compreender o que a sua classe faz. 

Se um atributo existe, ele deve servir a algum propósito.

Esta é a situação: o Sistema Brasileiro de Televisão, em mais uma tentativa de destruir o poderio da Globo, separou um espaço em sua programação para um programa que conseguirá no mínimo 87% das TVs sintonizadas no SBT. Este programa existe, e Sílvio Santos está radiante com a possibilidade de dar um banho na empresa de Roberto Marinho!
O problema é que o programador que fez o sistema de gerenciamento da programação do SBT não proveu nenhuma forma dos funcionários da emissora colocarem este programa no ar. Todos estão desesperados, mas não adianta: o atributo da programação é privado!!! O programador, além de ser demitido, irá sofrer um processo milionário, e seus filhos e netos ficarão devendo dinheiro ao senhor Sílvio até o fim de seus dias. Triste, não?
Resumindo, se vocês usarem algum atributo nas suas classes, façam alguma coisa com ele. O que estou tentando dizer é o seguinte: se houver um atributo privado em alguma classe que vocês venham a criar, criem formas de acesso a este atributo, tanto para leitura quanto para escrita, a não ser que ele seja        usado apenas para controle interno da classe (como o atributo indice da classe Banco , lembram-se ?). O código abaixo, por exemplo, compila sem acusar erro nenhum, mas não serve para absolutamente nada.

public class DadosPessoais {
    private long identidade;
    private String cpf;
    private String Endereco;
    private int anoNascimento;
}

A César o que é de César

Este problema foi detectado em vários exercícios: várias pessoas colocaram em uma classe um atributo que não faz parte dela. Ora, uma classe Conta deve ter apenas os atributos de uma conta de um banco, uma vez que um objeto desta classe é a nossa representação para uma (e apenas uma) conta do mundo real. Não faz sentido que esta classe Conta tenha o atributo saldoTotal, pois ele (deveria) ser exatamente igual ao saldo! Outro exemplo: na classe Pessoa, será que faz sentido um dos atributos da classe ser o ano atual? Tudo bem, fica mais fácil para se fazer as contas da idade da pessoa, você pode implementar um método mudaAno()ou coisa parecida, mas isto não é natural! E a naturalidade da  implementação é uma das principais características da orientação a  objetos! Para que nadar contra a corrente? Você provavelmente irá apenas se cansar... 

Cuidado com os exageros!!!

O que eu notei que muita gente andou fazendo nos exercícios da aula 5: complicando DEMAIS o que em princípio era simples. Uma resposta correta para este exercicio: na classe Pessoa, colocar um atributo sexo, por exemplo, um metodo de acesso a este atributo, e alguma forma de determina-lo (no construtor, por exemplo). Para a classe Livro, bastava fazer a mesma coisa para o atributo autor. E só! Quem fez isso (e duas pessoas assim fizeram) tiraram a nota máxima!
O problema foi que várias pessoas criaram uma quantidade muito maior de classes que as que realmente eram necessárias. Um exemplo deste problema (real, cujo(a) autor(a) não será revelado(a)):
      class Pessoa {
private String nome;
...
private DadosPessoais dados;
...

Pessoa (String nome, String sobrenome,
DadosPessoais dadosPessoais, String telefone)
{
...
}
...
DadosPessoais getDados()
{
return dados;
}
...
}

class DadosPessoais {
private boolean ehCasado;
...
private Endereco endereco;
...

DadosPessoais(boolean ehCasado, String cpf, Endereco endereco,
int anoNascimento)
{
...
}
...
Endereco getEndereco()
{
return endereco;
}
...
}

class Endereco {
...
private String bairro;
...

String getBairro()
{
return bairro;
}
}
Este exercício estava completamente correto! Mas imagine o trabalho para se saber o bairro de uma determinada pessoa:

    Pessoa p;
    ...
    DadosPessoais dp = p.getDados();
    Endereco e = dp.getEndereco();
    String bairro = e.getBairro();
    System.out.println(bairro);

Será que esta granularidade tão fina da  implementação é realmente necessária? O que vocês tem de verificar é se o problema que vocês estão tratando realmente precisa de todo este detalhamento. Para o controle academico do CIn, por exemplo, as unicas informações necessárias para as "Pessoa"s seriam seus nomes, talvez endereços e numero de matrícula. Não há a necessidade de tanto trabalho assim...
A decisão é de vocês. A minha sugestão: não compliquem, a não ser que o problema seja realmente complicado. Nestes exercícios vocês podem até achar fácil  lidar com esta complexidade, mas quando vocês forem fazer algum  projeto grande mesmo, ou até mesmo o projeto da disciplina, vocês com certeza terão muito mais trabalho do que realmente precisariam ter.


Carlos Figueira Filho( csff@cin.ufpe.br)