quinta-feira, 6 de março de 2008

Sobre o "ensino" de Java hoje em dia.

Java é uma linguagem orientada a objetos que contem tipos primitivos e wrappers para estes tipos, é executada sobre uma maquina virtual, com suporte a herança simples mas possui interfaces, com mecanismos de sobreescrita e sobrecarga de métodos, com um sistema de tratamento de exceções que te obriga a tratar determinadas situações e por ai vai.

Ao meu ver o estudo da linguagem deveria focar o domínio do mecanismo de herança e a construção de classes, domínio dos métodos, tipos de retorno, escopos de variavel, conversão de tipos, domínio das estruturas condicionais, de loops e de tratamento de erros, domínio das operações matemáticas e lógicas e,principalmente, domínio da classe String (ok, domínio pode ser uma palavra forte, talvez uma boa noção fosse suficiente em algumas situações).

Com disso tudo, o aluno deveria primeiro trabalhar com argumentos de linha de comando (o que vc acha que o main recebe?), depois passar a estudar a leitura e escrita em arquivo texto e, por fim, leitura pela entrada padrão.

Pois leitura pela entrada padrão é o que vc menos vai fazer em Java. Ninguem faz programa com menuzinho em Java pra console no mercado. Temos coisas mais complexas pela frente e sem conhecer tudo aquilo que eu listei antes só é possivel fazer gambiarras (como as famosas class functions, gigantescos métodos que fazem centenas de coisas com nomes adequados do tipo createTree3).

Ensina-se Java ao contrário: primeiro o camarada programa como se fosse C, perdendo tempo em fazer menus e estruturas de controle pois o usuario pode ter dado um enter, tab, "ç" ou ter digitado algo inválido quando deveria aprender os fundamentos da linguagem. Cria-se vícios que pode ser custoso para remover (como encher o código de getters/setters sem necessidade). A prova disso é que invariavelmente temos comparação de Strings usando o operador == quando deveria ser utilizado os métodos adequados para isso (imagina o susto quando a galera descobre o equalsIgnoreCase).

Eu vejo muitos estudantes incapazes de compilar e executar uma classe (o famoso hello world) pois os mesmos nunca fizeram uso da linha de comando muito menos foram apresentados ao conceito de classpath. Vejo barbaridades típicas de quem não conhece (ou não sabe ler) o javadoc das classes básicas. Fico me perguntando quando esses jovens serão capazes de ler um "Effective Java", por exemplo.

Aqui tem um excelente começo.

Espero que os professores acordem para essa realidade e que os alunos percebam que estão sendo prejudicados e passem a estudar por sua conta os tópicos necessários para sair arrasando pro ai.

11 comentários:

ferhr disse...

No início (bem no início, há mais de dez anos) via a questão dos getters/setters com muita desconfiança.

No entanto é fácil de criá-los, nem que seja através de geração de código.

Sem eles, entretanto, fica difícil fazer certas coisas com reflexão e afins.

Ana Carolina disse...

Oi Tiago.

Concordo totalmente contigo.
Trabalho com cursos e também disciplinas de cursos técnicos e sei que não adianta começar com a parte prática sem a parte teórica, e também não adianta o objetivo ser "conquistar o mundo", é com exemplos simples, mastigados e várias atividades que se consegue base para um bom profissional. Depois disso é que podemos aprofundar o assunto e abordar tópicos mais avançados.

Ah! E não é só Java.
Tenho muito aluno que vem dizendo que "eu sei trabalhar com banco de dados" e na verdade usou o Access e nem sabe o que é uma view.

Quando surge o incêndio, é a teoria que te ajuda.

Se o aluno aprende primeiro "na mão", da forma mais trabalhosa e programando em modo texto, com certeza depois ele pode ir pra uma interface gráfica, mas o contrário não é verdadeiro.

Conheço um "professor" de Linguagem C que não sabia que um for() pode ser infinito heheheh

Por esses problemas é que eu sou contra estes cursos muito curtos que ensinam "tudo" e não ensinam os fundamentos das coisas.

É por essas e outras que quem trabalha com TI sofre tanto preconceito. Todos os anos vários "fabricantes de gambiarras" aparecem por aí (mas eles não tem muito sucesso, não se preocupe! heheheh)

Um forte abraço.

Ana Carolina
http://anacarol.blog.br

Daniel Wildt disse...

Tiago, belo post. Eu vejo ser necessário ensinar o aluno que java não é dependente de uma IDE como ocorre com algumas outras linguagens de programação. Passo pelo menos 3 aulas trabalhando diretamente na linha de comando e usando um editor de texto sem sintax highlight. E desde o início trabalho identação de código fonte, organização de código fonte, enfim, o programador tem que entender a base do processo e tem que saber aplicar isto para qualquer outra linguagem de programação que venha a aprender.

Ainda, que você não precisa de uma IDE com 5000 plug-ins para ter produtividade. Deve achar o que te deixa produtivo, como disse o Vitor Pamplona.

E principalmente, focar no ensino de orientação a objetos. Criar classes, entender composição e herança, saber diferenciar uma classe abstrata de uma interface. Gosto de trabalhar todos os princípios para que um aluno possa ler um livro sobre design patterns e saber como construir aquilo, porque ele entende orientação a objetos, e não porque sabe java.

Já vi aluno meu reclamar que não consegue aprender patterns porque o material que passei não era em java.

O Urubatan já falou em um post dele que aprender uma linguagem de programação deveria ser um processo rápido. Concordo com isto e no meu entendimento isto está relacionado a sua habilidade de abstração e de entender como as linguagens orientadas a objetos funcionam.

Eu aqui fico pensando em como estes profissionais que hoje tem problemas vão evoluir para novas linguagens de programação e assim manter a própria empregabilidade em alta.

Será culpa somente do aluno ou também é culpa do professor?

Como professor, me considero um cara muito chato e deixo claro sempre para os alunos que não existe melhor linguagem de programação. Semestre passado em uma disciplina de desenvolvimento para web, ensinei ASP.NET, Java Server Faces e Ruby on Rails. Só que antes disto trabalhei muito o que envolve desenvolver para a internet.

Ufa, ficou longo o comentário... :-)

paulo disse...

Oi Tiago! Agradeço o link para o blog da Caelum. Nos tentamos seguir essa linha de pensamento, focar no que é realmente importante: interfaces, polimorfismo, reescrita de método, encapsulamento. Alias, quando mostramos java.util e java.io, damos mais atencao para o bom uso das interfaces e polimorfismo desses pacotes do que a API em si. Saber fazer um bom design é o que é fundamental.

fehr, usar getters e setters gerados, como voce falou, é muito perigoso e pode gerar um dominio muito fraco. os objetos podem passar a ser apenas estruturinhas de dados:

http://blog.caelum.com.br/2006/09/14/nao-aprender-oo-getters-e-setters/

e atraves de reflection da sim para manipular os atributos, sem necessidade dos getter e setters, nao vejo reflection como motivacao para o uso dos getters e setters.

ferhr disse...

> fehr, usar getters e setters gerados, como
> voce falou, é muito perigoso e pode gerar
> um dominio muito fraco. os objetos podem
> passar a ser apenas estruturinhas de dados:

ValueObjects / encapsulação, anyone? E qual o problema de alguns objetos serem apenas "estruturinhas de dados"? Nenhum. Depende da aplicação, da idéia. Não há bala de prata.

paulo disse...

o problema está escrito la, chegou a ler o post? Voce deixa de programar orientado a objetos pra programar estruturado.

value objects nunca precisaram obrigatoriamente de getters e setters. alias, value objects imutaveis sao muito mais interessantes.

getters e setters não fazem encapsulamento por si só, isso é uma ilusão! as vezes muito pelo contrario: voce acaba expondo atributos que nao deveria expor: deveria ter criado métodos para trabalhar com esses atributos, em vez de apenas fornecer um simples par de getter e setter. Esse é o mais que conhecido anti pattern do dominio de modelo anemico:

http://www.guj.com.br/posts/list/75388.java

Seus objetos acabam virando fantoches:
http://www.fragmental.com.br/wiki/index.php?title=Fantoches

Em nenhum momento falei para nunca utilizar getter e setters, o problema é seu abuso. quem vem de linguagem estruturada e esta comecando com orientacao a objetos, costuma abusar demais disso, deixando seu sistema identico a um nao orientado a objetos.

Tiago Peczenyj disse...

Ao invés de criar um objeto cheio de get/set desnecessário, poderiamos preparar interfaces fluentes, como no exemplo do Chapiewski.

ferhr disse...

Também vejo problemas com abuso. Neste caso, concordo plenamente.

Mas também não vejo problemas com certos fantochismos, principalmente quando você tem que tratar um objeto (ou seria neste caso "dados"?) em sistemas distribuídos ou usando duas, três linguagens diferentes.

ferhr disse...

(aliás, todo problema gerado por quaisquer linguagens de programação é o abuso).

paulo disse...

tem tda razão ferhr, mas no caso do sistema distribuido estamos falando de Data Transfer Objects (DTOs). É o caso que é necessario o fantochismo (as vezes da ate pra colocar alguma funcionalidade neles... mas é raro)

Guilherme disse...

O problema é que esses tais sistemas distribuídos não existem em qualquer lugar como se fala, e as pessoas frequentemente usam objetos fantoches independente da situação. Os sistemas distribuídos acabaram virando uma "desculpa" para os "objetos burros" existirem...