350 likes | 490 Vues
Estilo . Alfredo Goldman. “Cães latem, gatos tem estilo...” Charles Bukowiski. “Observa-se que os melhores escritores as vezes desrespeitam as regras da retórica. Mas, quando o fazem os leitores geralmente encontram na sentença um mérito compensador, maior do que o custo da violação.
E N D
Estilo Alfredo Goldman
“Cães latem, gatos tem estilo...” Charles Bukowiski
“Observa-se que os melhores escritores as vezes desrespeitam as regras da retórica. Mas, quando o fazem os leitores geralmente encontram na sentença um mérito compensador, maior do que o custo da violação. A não ser que você tenha certeza de estar fazendo o mesmo, o melhor é seguir as regras.” Strunk&White - Elementos de Estilo
Observe Fragmento de código: if ((country == SING) || (country == BRNI) || (country == POL) || (country == ITALY)) { /* If the country is Singapore, Brunei or Poland * then the current time is the answer time * rather than the off hook time. * Reset answer time and set day of week. */ ... Código bem escrito e funciona Mas pode ser melhorado !!
Princípios • Escrever programas é mais do que: • sintaxe correta • tirar erros • eficiência • Programas são lidos também por pessoas! • Um programa bem escrito pode ser entendido e modificado mais facilmente • Escrever bem => código correto
Princípios • Senso comum (confie na experiência) • Código claro e simples • lógica direta • expressões fáceis • nomes com significado • Evitar • truques • construções não usuais • formato claro • comentários bem feitos
#define INPUT_MODE 1 #define INPUT_BUFSIZE 10 #define OUTPUT_BUFSIZE 20 Um exemplo #define ONE 1 #define TEN 10 #define TWENTY 20
Nomes • Nome de variável/ atributo/ objeto • Nome de função/ método • Deve ser • informativo • conciso • memorizável • pronunciável
Nomes • Variáveis globais/ classes • Nomes longos e descritivos (lembrar significado) • ex: int npending = 0; //tamanho atual da fila de entrada • Variáveis locais • Nomes curtos • n pode ser suficiente • npoints está OK • numberOfPoints é grande demais
Exemplo Compare: for (theElementIndex = 0; theElementIndex < numberOfElements; theElementIndex++) elementArray[theElementIndex] = theElementIndex; Com: for (i = 0; i < nelem; i++) elemen[i] = i;
Nomes (consistência) • Para coisas correlatas use nomes que • mostram a sua relação; • evidenciam suas diferenças.
Exemplo (nomes) Class UserQueue { int noOfItemsInQ, frontOfTheQueue; queueCapacity; public int noOfUsersInQueue() { ...} } A palavra queue aparece como: Q, queue e Queue exemplo em uso: queue.queueCapacity = 10;
Correção (nomes) Class UserQueue { int nitems, front,capacity; public int nOfItems() { ...} } O que leva a comandos como: queue.capacity = 10; n = queue.nOfItems();
Nomes de funções • Use verbos para nomear funções: • ex: now = date.getTime(); • Para perguntas booleanas a pergunta deve ser clara: if (checkoctal(c)) .... if (isoctal(c)) ...
Seja preciso O nome fornece informações ao leitor #define isoctal(c) ((c) >=‘0’ && (c) <=‘8’) ao invés de: #define isoctal(c) ((c) >=‘0’ && (c) <=‘7’)
Seja preciso (outro exemplo) public boolean inTable( Object obj) { int j = this.getIndex(obj); // getIndex volta o índice onde obj // está, ou o tamanho da tabela return (j == nTable); }
Exercício Comente o seguinte trecho de código: #define TRUE 0 #define FALSE 1 if ((ch = getchar()) == EOF) not_eof = FALSE;
Expressões e comandos • Escreva código claro • Use espaços for(n++;n<100;field[n++]=‘\0’); *i = ‘\0’; return (‘\n’); for(n++; n<100; n++) field[n] = ‘\0’; *i = ‘\0’; return ‘\n’;
Use expressões fáceis • Dica: Escreva-as como você as falaria if (!(block_id < actblks) || (block_id >= unblocks)) ... if ((block_id >= actblks) || (block_id < unblocks)) ...
Use parenteses • Não faz mal a ninguém leap_year = y % 4 == 0 && y % 100 != 0 || y % 400 == 0; leap_year = ((y%4 == 0) && (y%100 != 0)) || (y%400 == 0);
Quebre expressões complicadas • Pessoas também devem ser capazes de ler o código *x += (*xp=(2*k < (n-m) ? C[k+1] : d[k--])); if (2*k < n-m) *xp = c[k+1]; else *xp = d[k--]; *x += *xp;
Tente ser claro • Ao invés de escrever código conciso escreva código legível !!! child = (!LC&&!RC)?0:(!LC?RC:LC); if (LC == 0 && RC == 0) child = 0; else if (LC == 0) child = RC; else child = LC;
Cuidado com efeitos colaterais • Operadores como o ++ podem ser armadilhas: str[i++] = str[i++] = ‘ ’; str[i++] = ‘ ‘; str[i++] = ‘ ’; array[i++] = i; scanf(``%d %d’’, &yr, &profit[yr]);
Melhore os seguintes trechos if (!(c ==‘y’ || c == ‘Y’)) return ; length = (length < BUFSIZE) ? lenght : BUFSIZE; flag = flag ? 0 : 1; // quais são as saídas possíveis do seguinte printf n = 0; printf(``%d %d\n’’, n++, n++);
Consistência e Idiomas • Use uma indentação consistente e um único estilo de {} • Use a linguagem normalmente • Use os ifs e elses da seguinte maneira if (condition1) statement1 else if (condition2) statement2 ... else if (conditionn) statementn else default-statement
Exercícios Rescreva os seguintes trechos: if (istty(stdin)) ; else if (istty(stdout)) ; else if (istty(stderr)) ; else return(0); for (k = 0; k++ < 5; x += dx) scanf(``%lf’’, &dx);
Exercícios Corrija os erros e rescreva o seguinte trecho: int count = 0; while (count < total) { count++; if (this.getName(count) == nametable.userName()) { return (true); } }
Macros • São muito usadas por programadores mais antigos • Não oferecem nenhum ganho especial • Devem ser evitadas
Problemas com macros #define isupper(c) ((c) >=`A’ && (c) <=`Z’) \\ o que acontece na chamada while (isupper(c = getchar()) ... \\ mas pode ser resolvido de forma simples while ((c = getchar() != EOF && isupper(c)) ...
Problemas com macros \\ podem piorar o desempenho #define ROUND_TO_INT(x) ((int) ((x) + (((x)>0)?0.5:-0.5))) \\ o que acontece na chamada size = ROUND_TO_INT( sqrt(dx*dx + dy*dy)); ... \\ A falta de parenteses pode provocar erros #define square(x) (x)*(x) \\ a seguinte expressão dá erro a = 1.0 / square(2)
Números mágicos • Dê nome aos números mágicos • qualquer número (fora 0 e 1) deve ter um nome • Defina número como constantes • não use macros • use enum (em C), const (em C++) e static final (em Java) • Use constantes caracteres, não números • Deixe a linguagem calcular o tamanho de objetos
Exemplo Como melhorar as seguintes definições: #define FT2METER 0.3048 #define METER2FT 3.28084 #define MI2FT 5280.0 #define MI2KM 1.609344 #define SQMI2SQKM 2.589988
Comentários • Não comente o obvio • comente funções e variáveis globais • Não comente código ruim, rescreva-o • Não contradiga o código • Clarifique, não confunda
Conclusão • Estilo deve se tornar um hábito • Isto se torna automático com o tempo • E naturalmente o código melhora... • (mesmo sob pressão)
Bibliografia Brian W. Kernighan e Rob Pike. The Practice of Programming. Addison-Wesley, 1999. Capítulo 1: Style