Este documento fornece uma introdução sobre refactoring e padrões de codificação em PHP. Apresenta conceitos como padronização de nomes, comentários, classes, métodos e atributos de acordo com padrões orientados a objetos. Também explica o que é refactoring, sua origem e como aplicar pequenas modificações no código para melhorar sua estrutura sem alterar o comportamento.
2. Quem sou eu?
Guilherme Lacerda
guilhermeslacerda@gmail.com
Mestre em Ciência da Computação, área de Engenharia de Software (UFRGS)
Professor de Graduação (FACENSA) e Pós-Graduação (UniRitter)
Coordenador do Curso de Sistemas de Informação (FACENSA)
Diretor de Tecnologia da APOENA Software Livre
Pioneiro em Processos Ágeis e XP no Brasil
Fundador do XP-RS (Grupo de Usuários de Metodologias Ágeis do RS)
Vice-Coordenador do GUMA (Grupo de Usuários de Metodologias Ágeis) vinculado a
SUCESU-RS
Editor do InfoQ Brasil
4. Por que 80% a 90% dos projetos de SW
fracassam?
Fonte: Standish Group
5. Histórico de Desenvolvimento de Software
Processos Tradicionais
ciclos sequenciais, etapas dependentes
Prever o futuro
Temores (mudanças nos requisitos)
6. Manifesto Ágil
“Estamos evidenciando maneiras melhores de desenvolver
software fazendo-o nós mesmos e ajudando outros a fazê-lo.
Através desse trabalho, passamos a valorizar:
Interação entre pessoas MAIS QUE processos e ferramentas;
Software em funcionamento MAIS QUE documentação abrangente;
Responder a mudanças MAIS QUE seguir um plano.
Colaboração com o cliente MAIS QUE negociação de contratos;
Ou seja, mesmo tendo valor os itens à direita, valorizamos
mais os itens à esquerda.”
Kent Beck, Robert C. Martin, Scott Ambler, Alistair Cockburn, Ward
Cunningham, Ron Jeffries, Steve Mellor, Mike Beedle, Arie van Bennekum,
Martin Fowler, James Grenning, Jim Highsmith, Andrew Hunt, Brian Marick,
Ken Schwaber, Jeff Shuterland, Dave Thomas
Utah – Fevereiro de 2001
www.agilemanisfesto.org
8. XP – eXtreme Programming
Disciplina de desenvolvimento de SW, voltada para equipes
pequenas e médias, com requisitos vagos ou que mudam
freqüentemente
Criado por Kent Beck, Ron Jeffries e Ward Cunningham
Principal tarefa é a codificação
Ênfases
Menor em processos formais de desenvolvimento
Maior em disciplina rigorosa
Aborda
TDD, participação do cliente como membro da equipe, revisão
permanente do código, refactoring, integração contínua,
refinamento contínuo da arquitetura, planejamento
9. XP – eXtreme Programming
Práticas organizacionais
Práticas de equipe
Práticas de pares
10. O que veremos aqui?
Padrões de Codificação
Por que padronizar?
Definindo Padrões
Exemplos de Padrões de Codificação OO
Refactoring
Definição
Origem
Exemplos
Dicas
Ferramentas
12. Por que padronizar?
Grande parte do custo no ciclo de vida de um
software é manutenção!
Sistemas geralmente podem não ser mantidos
pelos autores originais
Até mesmo os autores originais precisam de padrão
Padrões e convenções de código aumentam a
legibilidade do código
13. Por que padronizar?
Facilita o trabalho em equipe
Aprendizado mais rápido
Promovem a programação em pares
Códigos mal escritos prejudicam a identificação de
bugs
Permite uma maior compreensão, rápida e direta
14. Importante:
Nenhum padrão é perfeito
Inexistência de um padrão genérico
PHP sofre muito com isso
Zend, PEAR, Squiz, MySource, CamelCase, Your
Company?
Se estabelecer um padrão, é necessário
documentá-lo
Todas as convenções podem ser quebradas
Exceto a documentação de padrões!
15. Padrões: Nomenclaturas
Procure adotar apenas um idioma (inglês é o
padrão)
Usar descritores completos
Usar $cliente ao invés de $c1
Usar terminologias aplicadas ao contexto que se
está implementando o código
Usar Customer (consumidor) ao invés de Client (mais
genérico)
Alterne entra maiúsculas/minúsculas para tornar
nomes mais legíveis (capitular)
$nomeCliente, ContaCorrente...
16. Padrões: Nomenclaturas
Evite abreviações. Se usar, faça-o de modo
eficiente
$numero por $nbr, $nro, $num
Evite nomes longos de mais
ClienteEspecialVantagemDescontoAplicadoPercentual
Evite nomes similares ou que diferem somente em
capitulares
$umSqlBd / $umSQLBD
$objetoPersistente / $objetosPersistentes
17. Padrões: Comentários
Devem ser claros e simples
Primeiro refatore o código antes de documentá-lo
Evite comentários tipo “banner”
Documente algoritmos utilizados
Documente porque algo está sendo feito e não
somente o quê
18. Padrões: Comentários
Documentação (PHPDocumentor)
/**
* Usuario - Classe responsavel por acessar informacoes de usuario
* @author Guilherme Lacerda
*/
Estilo “C” (mais de uma linha)
/* Usuario - Classe responsavel por acessar informacoes de usuario
Desenvolvido por Guilherme Lacerda */
Linhas
// Usuario - Classe responsavel por acessar informacoes de usuario
// Guilherme Lacerda
19. Padrões OO: Classes
Pacote pertencente
Descrever o pacote (subsistema) que ela faz parte
Namespace / @package
Visibilidade da classe junto a outras (escopo)
Podem ser públicas ou pertencentes a pacotes
Nomenclatura
Use capitular para o nome da classe. Ex: PacienteSus
Documentação
Objetivo da classe, histórico desenvolvimento/alteração,
exemplos de utilização, informações adicionais
Declaração ou estrutura da classe
Exemplo: Variáveis de instância, Construtores, Destrutores,
Métodos Públicos, Protegidos e Privados
20. Padrões OO: Interfaces
Nomenclatura
Use capitular para o nome da interface
Geralmente, usa-se a letra ‘I’ na frente do nome ou o
sufixo ‘Ifc’. Ex: IPacienteSus, PacienteSusIfc
Documentação
Seu propósito
Como deve ser utilizada
21. Padrões OO: Métodos
Nomenclatura
Use capitular a partir da 2ª palavra para o nome dos
métodos
Use verbos ativos ou no infinitivo. Ex: gravaPaciente(),
calculaSalario() / gravarPaciente(), calcularSalario()
Métodos accessors/mutators (getNome()/setNome())
Construtores com o mesmo nome da classe
Escopo
Procurar utilizar os escopos public, private, protected
e static
22. Padrões OO: Métodos
Documentação
O que faz, porque faz, parâmetros, valor de retorno,
exceções geradas, decisões de escopo, exemplos
Deve acrescentar clareza (nem todos os itens são
aplicáveis)
Técnicas de codificação
Use identação
public function retornaAlgo () {
return $algo;
}
23. Padrões OO: Métodos
Técnicas de codificação
Identação de mais de uma linha
$cliente = new Cliente( 1, “Guilherme Lacerda”,
“Pinheiro Machado 1429” );
Use espaços em branco
$cliente = new Cliente( 1, “Guilherme” );
$numCodigo = 1;
$totalGeral = $cliente->retornaSalario() +
$comissao;
24. Padrões OO: Métodos
Técnicas de codificação
Regra dos 30 segundos!
Possível alvo para refactoring
Escreva uma instrução por linha
Especifique ordens de operações com parênteses
Organize o código
25. Padrões OO: Atributos
Nomenclatura
Use capitular (mesmo recurso dos métodos)
Use substantivos
Notação húngara. Ex: $sNome (string), $dSalario (double)
Estilo C. Ex: $_nome
Outros padrões. Ex: $tNome, $tSalario (variáveis
temporárias); $loginUsuarioSession (variável de sessão)
Widgets (campos de formulário). Ex: btOk, bt_ok, okButton
Para constantes, usa-se tudo em maiúsculo, com
underscore como separador. Ex: TOTAL_CLIENTES
Para coleções, geralmente usa-se no plural, ou termos que
representem um conjunto de dados. Ex: $clienteLista,
$listaClientes
Use os escopos
public, protected, private, static
26. Padrões OO: Atributos
Documentação
Descrição do atributo (caso seu nome não represente seu
conteúdo)
Exemplos
Decisão de escopo
Variáveis Locais
Para nomenclatura, segue as mesmas regras dos atributos
Fluxos de controle, arquivos: $entrada, $flagAchou,
$arquivo
Loops: $indx, $indy, $indz, $i, $j, $k
Objetos de exceção: $e, $excecao, $exception
Use sempre com um propósito
Declare-as de forma agrupada
27. Padrões OO: Atributos
Parâmetros
Nomenclatura
Segue as mesmas convenções das variáveis locais
Documentação
Para que deve ser utilizado
Restrições e/ou pós-condições
Exemplos
29. Refactoring: Precisamos disso?
Problemas:
Ler um código sem necessitar de habilidades especiais
Entender para que serve o campo $text34 dentro do laço
while( $cont3 < sizeof( $colec1 ), que será persistida na
classe Est010
Mudar o fonte em um determinado ponto, sem precisar
rezar uma missa para as outras 200 mil linhas de código
Eliminar código duplicado!!!
Diminuir custo de manutenção
30. Refactoring: Precisamos disso?
Problemas:
Diminuir custos de manutenção?
XP é manutenção na essência
Diminuindo a manutenção, consequentemente
diminuimos o desenvolvimento !!!
Que venham as soluções!!
As soluções devem ser:
Simples
Comunicativas (isso mesmo, comunicar com o código)
de rápido feedback (temos que entender o que está ali!!)
Corajosas (E agora... Quem altera??)
31. Refactoring
São pequenas modificações no código
Não altera seu comportamento funcional
Melhora sua estrutura
Simplicidade
Clareza
Desempenho
Flexibilidade
Alta coesão e baixo acoplamento
32. Códigos que cheiram!!
Mudança de nome de variáveis
Mudança de “nºs mágicos” por constantes
Mudanças nas interfaces dos objetos
Pequenas mudanças arquiteturais
Encapsular código repetido em um novo método
Generalização de métodos
Como manter isso??
Testes unitários, padrões, integração contínua...
33. Refactoring: Origem
Refactoring sempre existiu
Não tinham nomenclaturas
Usados de forma empírica
O Segredo estava em catalogá-los
Vocabulário comum
Desenvolveu-se outras técnicas
Uso sistemático
34. Refactoring: Origem
Surgiu com o Smalltalk
Universidade de Illinois (Prof. Ralph Johnson, do GoF)
Kent Beck usou na indústria
Prática XP
Não está limitado a XP, podendo ser utilizado em outro
contexto
Pode ser utilizado em qualquer linguagem OO
35. Refactoring: Origem
Padrões de Projeto são alvos para o refactoring
Design Patterns: Elements of Reusable Object-Oriented
Software (Erich Gamma, Richard Helm, Ralph Johnson e
John Vlissides)
Catálogo de Refactoring
Refactoring: Improving the design of existing code (Martin
Fowler)
http://www.refactoring.com/catalog/
36. Passos para o Refactoring
Em geral, é tão simples que parece que não
ajudará muito
Porém, executados continuamente, o código
muda radicalmente sua estrutura
Demora alguns segundos/minutos
São operações sistemáticas e óbvias
Procurar ter um bom vocabulário de padrões de
refactoring
Duas possibilidades: Melhorar o código existente
ou jogá-lo fora e começar do zero!
37. Estrutura do Catálogo
Nome do refactoring
Resumo do que ele faz
Motivação
Mecânica
passo a passo do uso do refactoring
Exemplos
Uma relação de => para!!
38. Exemplos
Add Parameter
Adicionar parâmetros para obter mais informações no
método
class Calculadora {
public $valor1;
public $valor2;
function soma() { ... }
PARA
function soma( $valor1, $valor2 ) { .. }
39. Exemplos
Collapse Hierarchy
Unir duas classes (superclasse/subclasse) em uma classe
única, pois não são muito diferentes
Consolidate Conditional Expression
Método auxiliar utilizado para substituir testes (ifs) que
validam se método principal será executado
Decompose Conditional
Facilitar o entendimento de estruturas if...else
40. Exemplos
Encapsulate Collection
Evitar métodos set para coleções, criando somente um
método de retorno (get) e métodos de manutenção de
coleções (pattern Iterator)
class Lista {
public $vetor;
function getLista() {
return $this->vetor;
}
function adiciona( $elemento ) {
$this->vetor[] = $elemento;
}
41. Exemplos
Encapsulate Field
Evitar o uso de atributos públicos (quebra do
encapsulamento). Utilize métodos get/set
class Medico {
public $nome;
public $crm;
PARA
private $nome;
function setNome( $nome ) {
$this->nome = $nome;
}...
42. Exemplos
Extract Method, Extract Interface, Extract Class,
Extract ‘SuperClass, Extract SubClass
Melhorar escrita do fonte e reuso
Evitar “copiar/colar”
Classes não coesas favorecem o uso destes refactorings
Inline Method
Utilização do operador ternário para testes simples
$valor = ( $flagIncluiu )?true:false;
43. Exemplos
Move Class, Move Field, Move Method
Passar funcionalidade de uma classe para outra, com valor
semântico
Pull Up Method, Pull Down Method, Pull Up Field,
Pull Down Field
Trocar os métodos/atributos para uma superclasse ou
subclasse na hierarquia
Rename Class, Rename Field, Rename Method
Melhorar a semântica do software
44. Exemplos
Replace Error Code with Exception
Trocar o retorno de códigos de erro por instruções
throws/try/catch
Replace Magic Numbers with Symbolic Constant
Substituir valores utilizados no software que nunca
mudam seu valor pelo uso de constantes
Replace Temp with Query
Variáveis locais encorajam a criação de métodos longos.
Trocar as referências a esta expressão por métodos
45. Técnicas de Refactoring
Código duplicado
Extract Method, Pull Up Method, Form Template Method,
Extract Class e Substitute Algorithm
Método muito longo
Extract Method, Replace Temp with Query, Introduce
Parameter Object
Classe muito grande
Extract Class, Extract Subclass, Extract Interface,
Duplicate Observed Data
46. Técnicas de Refactoring
Muitos comentários “banner”
Extract Method e Introduce Assertion
Muitos parâmetros
Replace Parameter with Method, Preserve Whole Object,
Introduce Parameter Object
“Intimidade inapropriada”
Move Method, Move Field, Replace Inheritance with
Delegation
47. Dicas: Padrões de Codificação
Além de todos os outros benefícios dos padrões...
Facilita o entendimento do código
Facilita o trabalho em equipe
Sistemas geralmente não são mantidos pelos seus
desenvolvedores
Maior compreensão, rápida e direta
Pode-se gerar a documentação automática!!
PHPDocumentor
Não esqueça: Projete, codifique e documente!!
48. Dicas: Padrões de Codificação
Use os padrões!!
Acredite neles
Adote-os!
Procure segui-los durante a codificação
Programe para as outras pessoas
Projete e codifique!
Mantenha seu código simples e limpo
49. Dicas: Refactoring
Refatorar é mudar o código em pequenos passos
Se cometer um erro, é fácil consertar!!
Escreva código para os “outros”
Três laços? Está na hora de refatorar...
Quando é necessário escrever um comentário
para explicar o seu funcionamento, tente
refatorar primeiro
Refactorings podem adicionar erros
Use testes automatizados
50. Dicas: Refactoring
Antes de começar um refactoring, verifique se há um teste
para este “código que cheira”
Uma “suite” de testes é um exterminador de bugs
Economiza tempo
Quando se recebe um aviso do bug, primeiro escreva um
teste que reflita este bug
Assim como se consulta o catálogo de padrões, procure
consultar também o catálogo de refactorings!
Procure fazer métodos de até uma página
Evite a criação do programador “PageUp-PageDown”