MAC 413/5715 - Tópicos de Programação
Orientada a
Objetos
Aula 6 - 25/8/6
Anti-Padrões
  - AntiPatterns - Refactoring Software, Architectures,
and Projects in Crisis
 
  
    - de W. Brown, R. Malveau, H. McCormick III
e T. Mowbray
     
  
  - Motivos da Triste Realidade do Desenvolvimento de Software (vimos na
  aula passada):
 
  
    - É 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