MAC 413/5715 - Tópicos de Programação Orientada a
Objetos
Aula 11 - 22/09/2003
Anti-Padrões
- AntiPatterns - Refactoring Software, Architectures,
and Projects in Crisis
- de W. Brown, R. Malveau, H. McCormick III
e T. Mowbray
- A Triste Realidade do Desenvolvimento de Software
Hoje (fonte: pesquisa com centenas de projetos [J. Johnson 95]):
- Aproximadamente 1/3 dos projetos de software
são cancelados.
- 2/3 dos projetos de software custam mais do que 200% do que o planejado
inicialmente.
- Mais do que 80% dos projetos de desenvolvimento de software são
considerados fracassados em algum aspecto.
- Motivos:
- É uma área nova (apenas 1/2 século; apenas
20 anos com OO; < 10 anos com padrões) ??
- Os desenvolvedores não possuem educação apropriada
para implementar sistemas de forma correta ??
- Os gerentes não possuem educação apropriada
para administrar projetos de software ??
- Volto a bater na tecla da flexibilidade:
- Adaptabilidade é a qualidade mais importante do software.
- Mais da metade do custo do software se deve a mudanças nos
requisitos e na necessidade de implementar extensões a sistemas existentes
[Horowitz 93].
- Ao contrário do que muitos pensam (e ensinam), desempenho
(velocidade) NÃO é o fator mais importante em software;
aliás, hoje em dia, em 90% dos casos, é um fator irrelevante.
- O que são Anti-Padrões?
- Anti-Padrões identificam formas más de design, abordagens
técnicas equivocadas e práticas de desenvolvimento erradas que
levam ao desenvolvimento de software de má qualidade e ao fracasso
de projetos.
- "O estudo de Anti-Padrões é um tópico
importante para pesquisa. A presença de 'bons' padrões num
sistema de sucesso não é suficiente; você precisa mostrar
também que estes padrões não estão presentes
em sistemas fracassados. Da mesma forma, é útil mostrar a presença
de certos padrões (Anti-Padrões) em sistemas fracassados e
mostrar a ausência deles em sistemas de sucesso." - Jim Coplien.
- Anti-Padrões são divididos em três classes:
- Anti-Padrões de Desenvolvimento - relacionados à programação.
- Anti-Padrões Arquiteturais - relacionados à estrutura
dos sistemas.
- Anti-Padrões Gerenciais - relacionados aos processos e métodos
de desenvolvimento nas empresas e grupos de desenvolvimento de software.
- Formato de um Anti-Padrão:
- Nome
- Raízes do Problema
- Historinha que evidencia ocorrência do anti-padrão
( Anecdotal Evidence)
- Sintomas e Conseqüências
- Causas Típicas
- Exceções Conhecidas
- Solução Refatorada
- Exemplo
- Soluções Relacionadas (pode se referir a outros Anti-Padrões
e refatoramentos)
Anti-Padrões de Desenvolvimento
- The Blob
- referência a filme B com monstro extra-terrestre de geléia
que come tudo a sua volta e cresce cada vez que come algo. O alienígena
chega do espaço sideral na forma de uma gotinha gelatinosa e vai crescendo
até se tornar uma ameaça para o planeta inteiro :_
- ocorre freqüentemente com programadores novos em OO que vem
de linguagens não-OO e que concentram a maior parte do sistema em uma
classe central que passa a ter dezenas de métodos e atributos. Outas
classes pequenas orbitam o Blob e servem apenas para guardar pequenas estruturas
de dados.
- Causas Típicas:
- falta de arquitetura OO
- falta de arquitetura, o sistema é uma grande massa disforme
- preguiça: ao estender o sistema, ao invés de adicionar
novas classes, programadores incham as classes existentes.
- Solução refatorada: remova responsabilidades do Blob
e as transfira para as classes que o orbitam. A longo prazo, o objetivo é
um desenho OO de melhor qualidade onde os objetos interagem entre si e não
numa arquitetura de estrela centrada no Blob.
- Exceção conhecida: um Blob é aceitável
quando estamos encapsulando um sistema legado dentro de uma grande classe.
Não queremos modificar o sistema legado, queremos apenas acessá-lo
a partir do nosso sistema OO.
- Lava Flow
- Hostorinha-Evidência:
- "AAHHH, isso? Bem, o Marcelo e o Edson escreveram esta rotina
quando o João (que saiu da empresa no mês passado) estava tentando
resolver o problema das funções de entrada e saída implementadas
pela Irene (que agora trabalha no departamento de vendas). Eu acho que esse
código não é mais utilizado, mas não tenho certeza.
O Marcelo não escreveu nenhuma documentação e nós
não temos testes automatizados, então acho melhor não
mexer nisso pois pode quebrar alguma coisa. Afinal, está funcionando
do jeito que está, não está? Então é melhor
não mexer."
- Forma geral:
- Fluxo de Lava é encontrado muitas vezes em sistemas que
começaram como experimentação mas que acabaram em produção.
- É caracterizado por ondas de código disforme de
versões anteriores que deslizam para as versões novas sem termos
muito controle sobre elas.
- Partes da lava podem se solidificar na forma de grandes rochas
e serem carregadas pelo fluxo de lava derretida. Como grandes partes de código
antigo que são incorporados ao sistema sem sabermos exatamento o que
ele faz e se ele é realmente necessário.
- Sintomas e Conseqüências:
- alta freqüência de variáveis e fragmentos de
código não justificados
- funções aparentemente importantes completamente
não-documentadas que na verdade não se relacionam claramente
à arquitetura do sistema
- Grandes blocos de código entre comentários sem justificativa
- Muitos comentários do tipo /* Substituir isso */
/* Em construção */
- Interfaces nos arquivos de cabeçalhos que não são
usadas e que não podem ser explicadas pelos programadores atuais
- Se a lava se solidifica, se torna impossível a compreesão
e documentação do código existente e a falta de conhecimento
da arquitetura se torna tão grande que fica praticamente impossível
implementar melhorias no sistema.
- Refactored Solution:
- Só há uma maneira de evitar: garantir que a todo
momento se tenha uma clara noção da arquitetura do sistema
e que todo o código seja compatível com esta arquitetura.
- Quando o fluxo de lava já existe, a cura em geral é
muito dolorosa:
- especialistas devem conduzir uma mineração do
código cuidadosa (investigar o que há lá e tentar entender
a arquitetura) e daí remover as partes inúteis e refatorar
a arquitetura.
- às vezes, implementar o item anterior é tão
difícil que a solução é jogar o código
fora e começar de novo com uma arquitetura clara.
- Poltergeists
- um poltergeist é um fantasma que aparece de repente no meio
da noite, esbarra na nossa frente e desaparece misteriosamente.
- é comum com programadores muito especialistas nas especificidades
de uma determinada linguagem e que usam esse conhecimento para o mal.
- por exemplo, programadores de LISP ou C que usam efeitos colaterias
da linguagem para fazer coisas importantes no sistema.
- poltergeists podem se manifestar na forma de classes estranhas dentro
do sistema que não fazem parte da arquitetura mas que são
usadas de vez em quando para realizar alguma tarefa-chave que ficou faltando.
- uma forma muito comum entre "maus-bons programadores" são
trechos de código ultra eficientes e geniais que ninguém
entende a não ser o próprio programador.
- Spaghetti Code
- Historinha-Evidência: "Argh, que meleca! Você sabe que
em Java você pode ter mais do que uma classe por aplicação,
né? Do jeito que está é mais fácil re-escrever
tudo do que tentar consertar".
- Forma Geral: aparece em sistemas que tem muito pouca estrutura.
Em geral, temos poucas classes com poucos métodos, e cada método
é enorme.
- Exceção aceitável: quando se está testando
uma arquitetura e se implementa uma das componentes do sistema usando código-espagueti.
A interface da componente tem que ser muito bem feita para não contaminar
o resto do sistema. Uma vez terminado o teste, deve-se jogar fora o código-espagueti
e re-implementá-lo decentemente.
- Solução refatorada: utilizar técnicas de refatoramento
de código para redistribuir o código de forma mais OO, criando
novas classes e métodos.
- Input Kludge
- software que falha com entradas triviais
- Historinha: "O programador disse que o programa estava pronto
e que funcionava perfeitamente e que eu poderia testar. Sentei na frente do
computador, apertei <enter> e o sistema deu Falha de Segmentação
".
- Cut-and Paste Programming
- Historinhas:
- "Ei, eu pensei que você já tinha consertado esse
erro, por que está acontecendo de novo?"
- "Puxa, vocês são bons mesmo, 400.000 linhas de código
novo em duas semanas? Que progresso, parabéns!"
- Programação baseada em copiar e colar é a pior
forma de re-utilização de código. Herança (re-utilização
caixa branca) é melhor pois evita a repetição do código.
Componentes tipo caixa preta é ainda melhor pois evita repetição
e incentiva o desacoplamento.
- Soluções relacionadas: em geral, código-espagueti
está cheio de cut-and-paste programming. Identificar repetições
e criar um único método para elas.
- Mushroom Management
- Em algumas empresas se diz que os desenvolvedores não devem
ter contato com usuários finais, que a intermediação
deve ser feita por Analistas de Requisitos especializados nisso.
- Historinha: "Mantenha os seus desenvolvedores no escuro e alimente-os
com fertilizante".
- Normalmente, os desenvolvedores acabam construindo o sistema errado.
Anti-Padrões Arquiteturais
- Vendor Lock-In
- Construção de sistemas que são altamente dependentes
de interfaces proprietárias.
- Solução:
- use interfaces padrão (p.ex. CORBA, assim você não
depende de um só fabricante)
- crie uma camada de isolamento arquitetural entre o seu sistema
e a plataforma de um fabricante específico
- Design by Committee
- Muita gente trabalhando junto para projetar a mesma arquitetura
sem um método bem organizado
- Conseqüência: arquitetura excessivamente complexa para
atender a todas as diferentes opiniões e pontos de vista.
- Solução:
- limite grupo a não mais do que 10 pessoas.
- use processos bem definidos e planejados (p.ex. processo do OMG
para definição de CORBA) (será?)
- Swiss Army Knife
- É uma classe cuja interface é grande demais. O projetista
tenta antecipar na interface todos os possíves usos da classe no futuro.
- Reinvent the Wheel
- Historinha: "Este problema é único no mundo. Antes
de continuar implementando os requisitos básicos, vamos implementar
uma biblioteca nova para cuidar desta questão".
Anti-Padrões Gerenciais
- Analysis Paralysis
- Analistas buscam o entendimento perfeito e completo do problema.
Passam meses estudando as questões relacionadas ao problema ao invés
de colocar a mão na massa e começar a projetar e implementar
o sistema.
- Solução: desenvolvimento incremental.
- Death by Planning
- Excesso no planejamento do que se vai fazer. Cronogramas excessivamente
complexos que se mostram impraticáveis na vida real.
- Intellectual Violence
- Utilização prepotente de um conhecimento sobre uma
determinada teoria, tecnologia ou jargão específico para intimidar
outras pessoas numa reunião.
- Smoke and Mirrors
- Também conhecido como Vaporware
- Gerentes pedem para programadores criarem GUIs com a casca de um
sistema ainda não desenvolvido para mostrar a potenciais clientes o
que poderia ser feito.
- Programadores explicam para gerentes e vendedores que nada está
feito na realidade e que demoraria meses ou anos para fazer de verdade.
- Vendedores ignoram advertência dos programadores e VENDEM
o sistema antes de que ele exista.
Referência
- W. Brown, R. Malveau, H. McCormick III e T. Mowbray.
AntiPatterns - Refactoring Software, Architectures, and Projects in
Crisis. Wiley Computer Publishing, 1998.
- O sítio de Anti-Padrões
na teia
possui informações interessantes incluindo os slides de
um tutorial e um catálogo de anti-padrões.
Próxima Aula
Aula Anterior
Página de MAC 5715
Página do Fabio
Página do DCC