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 nom, String sobrenom,
                            DadosPessoais dadosPessoais, String tel)
          {
          ...
          }
          ...
          DadosPessoais dados()
          {
              return dados;
          }
          ...
      }

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

          DadosPessoais (boolean ehCasado, String numCpf,
                                             Endereco end, int anoNasc)
          {
          ...
          }
          ...
          Endereco endereco()
          {
              return endereco;
          }
          ...
      }

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

          String bairro()
          {
              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.dados();
    Endereco e = dp.endereco();
    String bairro = e.bairro();
    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 DI, 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@di.ufpe.br)