Provavelmente serei crucificado por causa deste post, mas se você se der ao trabalho de ler até o final, provavelmente vai concordar comigo que comentários no código são para os fracos, programador hardcore de verdade escreve código legível!
É exatamente isto que eu estou dizendo, por exemplo, o que faz o código abaixo?
1 2 3 4 5 6 7 8 9 10 | public String write(StringBuilder fle, StringBuffer con) { File f = new File(fle.toString()); FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String lin; while((lin=br.readLine())!=null){ con.append(lin).append("\n"); } return con.toString(); } |
Difícil? E este ainda é um código simples, mas vamos dar uma melhorada nele …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public String read(StringBuilder fle, StringBuffer con) { //Opens the file with the name container in the fle parameter File f = new File(fle.toString()); //Create a file reader, then a buffered reader to make our work easier FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String lin; //Read each line of the file until it is null while((lin=br.readLine())!=null){ //Put the content read into the buffer pointed by the parameter "con" con.append(lin).append("\n"); } //The caller already have the content, because he created the buffer, but I'll return the string anyway return con.toString(); } |
Mais fácil certo? Bastou ler os comentários, mas o código continua um lixo.
Ou seja, esta é uma gambiarra utilizada por péssimos programadores para contornar a própria limitação de não conseguir escrever um código decente.
Então qual a solução que eu recomendo?
Vamos tentar reescrever este método então:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public String readFileContents(File fileToRead) { boolean canReadFile = fileToRead.exists(); if(!canReadFile) return ""; StringBuilder buffer = new StringBuilder(); BufferedReader readerForFile = openBufferedReaderForFile(fileToRead); readFileContetIntoBuffer(buffer,readerForFile); closeFileReader(readerForFile); return buffer.toString(); } private BufferedReader openBufferedReaderForFile(File fileToRead){ return new BufferedReader(new FileReader(fileToRead)); } private void readFileContetIntoBuffer(buffer,readerForFile){ String line; while((line=readerForFile.readLine())!=null){ buffer.append(line).append("\n"); } } private void closeFileReader(readerForFile){ readerForFile.close(); } |
Agora se você prestar atenção no nome do método “readFileContents” já vai saber o que o método faz, Além disto, o código do método é quase legível em inglês. A leitura dele ficaria mais ou menos assim:
if not can read file, return null
open Buffered Reader For File: fileToRead
read File Contet Into Buffer: buffer, readerForFile
close File Reader: readerForFile
return buffer.toString();
Ou seja, qualquer um que entenda inglês, como qualquer desenvolvedor tem a obrigação de entender, vai ler o método como se fosse um comentário.
E eu já vi gente fazendo pior do que isto, o código tinha comentários, mas parecia com esta coisa ai em baixo:
1 2 3 4 5 | public String write(StringBuilder fle, StringBuffer con) { File f = new File(fle.toString()); FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String lin; while((lin=br.readLine())!=null){ con.append(lin).append("\n"); } return con.toString(); } |
Com certeza tinha muito menos linhas de código do que a minha versão ![]()
Mas não é uma tarefa fácil entender o código que uma criatura destas escreve
Claro que o exemplo que eu apresentei foi um exemplo bem simples, e que escrever código legível requer uma certa prática …
Então, vou fazer uma proposta:
Vou deixar um exemplo de código abaixo, e vocês tentam torna-lo mais legível. Em um ou dois dias eu posto a minha resposta aqui.
Quem quiser pode postar nos comentários o código que escreveu.
Para que o código fique colorido no blog, basta colocar dentro de uma tag <pre lang=”java” line=”1″> … </pre>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | package blog; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class VeryBadlyNamedFile { private static final char[] asdfg = new char[] {'I', ' ', 'c', 'a', 'n', ' ', 'd', 'o', ' ', 'v', 'e', 'r', 'y', ' ', 'u', 'g', 'l', 'y', ' ', 'c', 'o', 'd', 'e'}; private String an; private BufferedReader rfsdw; private FileReader temp; public VeryBadlyNamedFile(String an, BufferedReader rfsdw, FileReader temp) { super(); this.an = an; this.rfsdw = rfsdw; this.temp = temp; } public void doIt() throws IOException { ctfiidne(); startDoing(); try { canIDoAnyThing(); } catch (RuntimeException yicdet) { nowReallyDoIt(); } } private void nowReallyDoIt() { firstDoTheOtherThing(); reallyDoItInternal(); } private void firstDoTheOtherThing() { rfsdw = new BufferedReader(temp); } private void reallyDoItInternal() { while (true) { try { imDoingIt(); } catch (Exception e) { break; } } } private void imDoingIt() throws Exception { String s = rfsdw.readLine(); if (s == null) throw new Exception("hahaha, I bet you did not understood the code"); System.out.println(s); } private void ctfiidne() throws IOException { File a = new File(an); if (!a.exists()) { FileWriter wrfedsd = new FileWriter(a); wrfedsd.write(asdfg); wrfedsd.close(); } } private void canIDoAnyThing() { if (new File(an).exists() && new File(an).canRead() && new File(an).canWrite()) throw new RuntimeException(); } private void startDoing() throws FileNotFoundException { File f = new File(an); temp = new FileReader(f); } } |
E agora um “main” só para executar o lixão acima.
1 2 3 4 5 6 7 8 9 | package blog; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { new VeryBadlyNamedFile("c:\\anyFile.any",null,null).doIt(); } } |
Os exemplos estão em java, mas em qualquer linguagem os comentários para explicar o código servem para mascarar a incapacidade dos programadores escreverem código decente.
PS.: Só para constar, eu não acho de verdade que vocês não devem comentar o código, mas se vocês não escrevem código legível, ou escrevem código que realmente precisa de um comentário para outro programador entender, então vocês não aprenderam a programar ainda!
PS2.: só para constar, o código deste post foi inventado na hora, inspirado em coisas que ja vi em diversos lugares por ai, masescrevi ele direto no blog, então existe uma grande possibilidade de não compilar.
PS3.: acho que preciso de exemplos melhores, mas vocês devem ter entendido a idéia deste post
Tags: dicas, livro2, produtividade, refactoring
“Tudo bem que tu não tenha capacidade de escrever código legível…”
“…principalmente se escritos por alguem que não leu o post todo”
Não é necessário ser vidente par saber que tu não tinha lido o post, ou pelo menos não havia prestado atenção.
PS.: não sou obrigado a publicar comentários me xingando no meu blog
[Translate]
É um problema sério mesmo. O povo por aí insiste em programar feio e dar nomes estranhos para variáveis e métodos. :O
Já vi gente colocando em arquivos de configuração coisas do tipo mod=1000 para uma variável que ia ser utilizada assim: var = userID % mod
o.O
[Translate]
Mas sua refatoração quebrou a inteface do método do exemplo! =)
Deixo um link interessante: http://ssdl-wiki.cs.technion.ac.il/wiki/index.php/SendAnEmail_case_study
[Translate]
De acordo.
Código legível dispensa comentário.
Mas cada caso é uma caso.
Esse exemplo não se refere à regras de negócio complexas em código LEGADO, nem a histórico com justificativa de alterações no LEGADO, ou ainda quando muitos recursos alterando mesmo o código.
Pegue para “mergear”(sincronizar) centenas de arquivos com regras de negócio “comentadas” e depois os “descomentados” e “sinta” a diferença
Continuo defendendo o comentário para o código “não óbvio” e para historico de alteração (aquele cabeçalho com contorno bonito feito com ASCII).
O comentário é o “work item” natural !
(para quem não Visual Studio Team System ou outro SW de controle e documentação de alterações.)
[ ]´s
[Translate]
Eu concordo, vira e mexe reclamam que meu código não tem comentários.
Eu acho que comentários deixa o código sujo, e na maioria das vezes só explica idiotices óbvias, do tipo:
//Cria uma instancia de pessoa
Pessoa p = new Pessoa();
//Atribui um nome
p.Nome = “José da Silva”;
Ora, isso só serve pra quem não sabe programar conseguir entender mais ou menos.
Eu acho que nem algoritmos complexos tem que estar no código, pois código não é um documento de especificação.
Acho que no máximo, explicar que ali se está se implementando um algoritmo X, e colocar um link para referencia sobre este.
[Translate]
Concordo que a maoiria dos comentarios são desnecessários, mas são essênciais! Da mesma forma que vocês acham que os comentários são lixos no código, existem pessoas que acham que o código “são” o lixo quando estão procurando algo nos comentários. Os comentários não são destinados a quem implementou o bloco, e sim a outros que estão procurando, ou tentando entender o código. Felizmente não existem apenas programadores hardcode, existem juniors e plenos, e quanto menos tempo as pessoas precisarem para entender seu código, seja ele de 1º classe ou feito por um newbee, vai estar economizando tempo, e tempo é dinheiro. Agora para de tentar criar polêmica e vai comentar seu código!
[Translate]
Bom, não sei se o autor sabe, mas existem programadores cegos que utilizam comentários como forma de acessibilidade ao código. Na empresa que eu trabalho temos dois excelentes programadores cegos que fazem uso desse recurso. No final das contas percebemos que os comentarios são uteis pra eles e pra os programadores que tambem enxergam, pois trazem uma compreensao rapida dos blocos que se seguem.
[Translate]
disto eu não sabia mesmo
[Translate]
[...] sei que já falei sobre comentários antes, mas acho que a abordagem não agradou muito, a maior parte das pessoas leu só o título do post e [...]
[Translate]
Cara, concordo plenamente com você. Um código bem estruturado dispensa comentários!(Salvo exceções, que você mesmo comentou, para o caso de códigos mais complexos). Os exemplos que você deu são perfeitos, refatoração de códigos, nomes mais significativos e eu ainda acrescento, uso de patterns.
Abraços.
[Translate]
Acho que o ponto é: o importante não você ter um bom comentário. O importante é ter um bom código. Não adianta você entupir seu código de comentários e ter uma porcaria de códig. Não significa que você não precisa ter um comentário. Auxilia na facil identificação de classes, funcionalidades e procedimentos. O ideal é ter um bom código bem comentado. Em algumas técnicas de desenvolvimento, o comentário de código é utilizado para a própria atualização de documentação de referência. Não inserir nenhum comentário (ou não atualiza-lo) talvez seja uma questão mais de preguiça.
[Translate]