Boas Práticas de Programação João Arthur Brunet Monteiro Mestrando em Informática - COPIN 25/10/2008 João Arthur Brunet Monteiro 1/ 27
Roteiro Introdução 1 Introdução Objetivos Contextualização 2 Práticas de alto-nível 3 Práticas de baixo-nível 4 João Arthur Brunet Monteiro 2/ 27
Objetivos Introdução Objetivos Contextualização Apresentar boas práticas de programação Alto nível Baixo nível Apresentar o comportamento de um bom programador João Arthur Brunet Monteiro 3/ 27
Código elegante Introdução Objetivos Contextualização Any fool can write code that a computer can understand. Good programmers write code that humans can understand. (Martin Fowler) Código elegante (elegância funcional) Reuso de código Manutenção de código Diminuição de bugs Facilita comunicação Diminui curva de aprendizado João Arthur Brunet Monteiro 4/ 27
Código elegante Introdução Objetivos Contextualização Any fool can write code that a computer can understand. Good programmers write code that humans can understand. (Martin Fowler) Código elegante (elegância funcional) Reuso de código Manutenção de código Diminuição de bugs Facilita comunicação Diminui curva de aprendizado João Arthur Brunet Monteiro 4/ 27
Pensando no problema Pense no problema antes Quanto mais tempo no teclado, mais bugs são adicionados Mapeie seu problema para objetos Use boas abstrações João Arthur Brunet Monteiro 5/ 27
Programe para interface Programe para a interface, não para a implementação Interfaces são mais democráticas! Exemplo Collections.sort(List list) Flexibilidade Reuso João Arthur Brunet Monteiro 6/ 27
Programe para interface Programe para a interface, não para a implementação Interfaces são mais democráticas! Exemplo Collections.sort(List list) Flexibilidade Reuso João Arthur Brunet Monteiro 6/ 27
Respeite a lei de Demeter Não abuse dos pontos! String key = entry.getvalue().entryset().iterator().next().getkey(); Princípio do mínimo conhecimento Conhecer o mínimo possível sobre as propriedades de um objeto "Only talk to your friends" Parâmetros Objetos criados Objetos próprios Métodos próprios Inibe efeito gelatina João Arthur Brunet Monteiro 7/ 27
Respeite a lei de Demeter Não abuse dos pontos! String key = entry.getvalue().entryset().iterator().next().getkey(); Princípio do mínimo conhecimento Conhecer o mínimo possível sobre as propriedades de um objeto "Only talk to your friends" Parâmetros Objetos criados Objetos próprios Métodos próprios Inibe efeito gelatina João Arthur Brunet Monteiro 7/ 27
Padrões de Projeto Introdução Soluções padrão para problemas recorrentes Procure mapear seu problema para um já solucionado Exemplo: Expert (padrão de distribuição de responsabilidades) João Arthur Brunet Monteiro 8/ 27
Testes Introdução Teste o que você desconfia que vai falhar Evite testes de get e set Não encare como uma atividade secundária Testes aumentam a confiança no código (regressão) Testes revelam mau cheiro no código João Arthur Brunet Monteiro 9/ 27
Programação Defensiva Valide dados vindos do usuário Cheque referências nulas Commons Validator (Apache) João Arthur Brunet Monteiro 10/ 27
Não construa dependência cíclica Pacotes representam abstração diferentes (Ex.: Acesso a dados vs GUI) Dificulta entendimento Dificulta evolução Dificulta testabilidade Dificulta modularidade João Arthur Brunet Monteiro 11/ 27
Construindo métodos - Contrato Respeite contratos A assinatura de um método é o contrato do programador Implementar exatamente o que a especificação diz Um método deve cumprir com somente uma obrigação Não force leitura de corpo de método Separe o que do como João Arthur Brunet Monteiro 12/ 27
Construindo métodos - Implementação Crie variáveis somente quando for usá-las Não reuse variáveis Nomes pronunciáveis e sugestivos Evite siglas retorne result Seja coerente no uso de padrões de codificação João Arthur Brunet Monteiro 13/ 27
Uso de coleções Introdução Exemplo Declare usando a interface: List mylist = new LinkedList() João Arthur Brunet Monteiro 14/ 27
Uso de coleções Introdução Exemplo Declare usando a interface: List mylist = new LinkedList() João Arthur Brunet Monteiro 14/ 27
Evite funções com efeito colateral Exemplo de função com efeito colateral: Collections.sort(List l) Dificultam reuso São difícies de entender Difíceis de prever o comportamento Se for inevitável, comente os efeitos colaterais João Arthur Brunet Monteiro 15/ 27
Construa objetos imutáveis Objetos imutáveis Como? Facilitam testes São confiáveis para serem usados em coleções São thread-safe Permitem cache de resultados de métodos (hashcode) Ganho em memória Ótimas chaves para HashMap Não permita que a classe seja estendida (final) Atributos private e final Não permita métodos set Não permita funções com efeito colateral João Arthur Brunet Monteiro 16/ 27
Cópia Defensiva Introdução Proteção contra objetos mutáveis No construtor this.date = new Date(param.getTime()) Evita efeito gelatina Torna o código mais seguro Métodos get de coleções Collections.unmodifiableList(this.alunos) João Arthur Brunet Monteiro 17/ 27
Cópia Defensiva Introdução Proteção contra objetos mutáveis No construtor this.date = new Date(param.getTime()) Evita efeito gelatina Torna o código mais seguro Métodos get de coleções Collections.unmodifiableList(this.alunos) João Arthur Brunet Monteiro 17/ 27
Parametrize coleções Qual o problema? List alunos = new ArrayList() Melhorou? List<Aluno> alunos = new ArrayList<Aluno>(); Evita casts Evita coleções guarda-chuva Segurança ao acessar os elementos da coleção Facilita uso do for João Arthur Brunet Monteiro 18/ 27
Parametrize coleções Qual o problema? List alunos = new ArrayList() Melhorou? List<Aluno> alunos = new ArrayList<Aluno>(); Evita casts Evita coleções guarda-chuva Segurança ao acessar os elementos da coleção Facilita uso do for João Arthur Brunet Monteiro 18/ 27
Use for vs Iterator Introdução Iterator Iterator it = alunos.iterator(); while (it.hasnext()) { Aluno aluno = (Aluno) it.next() } For for (Aluno aluno : alunos) João Arthur Brunet Monteiro 19/ 27
Use for vs Iterator Introdução Iterator Iterator it = alunos.iterator(); while (it.hasnext()) { Aluno aluno = (Aluno) it.next() } For for (Aluno aluno : alunos) João Arthur Brunet Monteiro 19/ 27
Streams Introdução Exemplos Sempre feche os streams Bug conhecido! Pergunta clássica: Você fechou o stream? Use bufferização BufferedReader e StringBuffer StringBuffer X Concatenação de Strings João Arthur Brunet Monteiro 20/ 27
Streams Introdução Exemplos Sempre feche os streams Bug conhecido! Pergunta clássica: Você fechou o stream? Use bufferização BufferedReader e StringBuffer StringBuffer X Concatenação de Strings João Arthur Brunet Monteiro 20/ 27
Equals e HashCode Sempre que implementar equals, implemente hashcode Bug muito comum: hashset.contains( algo ) Effective Java [1] possui diretrizes para construção desses dois métodos João Arthur Brunet Monteiro 21/ 27
Implemente compareto Implemente Comparable Reuso do método Collections.sort(List l) Mudança na estratégia de ordenação Collections.sort(List l, Comparator c) João Arthur Brunet Monteiro 22/ 27
Como lidar com erros Mensagens de erro inúteis System.out.println("Deu erro aqui") Use mensagens de erro que façam sentido Tratamento de erros deve ser adequado Use exceções ao invés de valores extremos João Arthur Brunet Monteiro 23/ 27
Como lidar com erros Mensagens de erro inúteis System.out.println("Deu erro aqui") Use mensagens de erro que façam sentido Tratamento de erros deve ser adequado Use exceções ao invés de valores extremos João Arthur Brunet Monteiro 23/ 27
Equals vs "==" Introdução Qual o resultado? Integer i = new Integer("4"); Integer j = new Integer("4"); assert i.equals(j); assert i == j; Sempre use equals ao invés de "==" Exceção: Comparar referências João Arthur Brunet Monteiro 24/ 27
Equals vs "==" Introdução Qual o resultado? Integer i = new Integer("4"); Integer j = new Integer("4"); assert i.equals(j); assert i == j; Sempre use equals ao invés de "==" Exceção: Comparar referências João Arthur Brunet Monteiro 24/ 27
Aprenda com os gurus Cole nos caras bons Troque experiências Pair programming Joshua Bloch, Kent Beck, Marting Fowler, Eric Gahma Leia bons livros (Effective Java, Beautiful Code [4], Pragmatic Programmer [3], Design Patterns [2] etc) Discussões e Sites [5] João Arthur Brunet Monteiro 25/ 27
Não conviva com Janelas Quebradas "Don t Live with Broken Windows" Bons programadores têm coragem João Arthur Brunet Monteiro 26/ 27
Perguntas Introdução Perguntas? João Arthur Brunet Monteiro 27/ 27
J. Bloch. Effective Java: Programming Language Guide. Addison-Wesley Professional, 2001. E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design patterns: elements of reusable object-oriented software. Addison-Wesley Reading, MA, 1995. A. Hunt and D. Thomas. The Pragmatic Programmer: From Journeyman to Master. Addison-Wesley Professional, 2000. A. Oram and G. Wilson. Beautiful Code: Leading Programmers Explain how They Think. O Reilly, 2007. H. Systems. Java Practices. At http://www.javapractices.com/home/homeaction.do. João Arthur Brunet Monteiro 27/ 27