19 de ago. de 2010

CMMI® ou Agile?





Há tempos venho alimentando a minha curiosidade em buscas de materiais que esclarecessem a polêmica que existe por trás de dois grandes paradigmas da Engenharia de Software: CMMI e Metodologias Ágeis. Foi então que me deparei com um excelente artigo escrito por profissionais do SEI (Software Engineering Institute) da Carnegie Mellon University. O nome do artigo? "CMMI® or Agile: Why Not Embrace Both!", numa tradução livre: "CMMI ou Ágil: por que não adotar ambos!(?)". Este post então é resultado de um pequeno resumo do artigo que, na minha opinião, contribue em muito para uma visão mais madura, no sentido profisisonal, sobre o entendimento de ambos os paradigmas, livrando-nos muitas vezes, de certo "achismos" e preconceitos. O artigo original é referenciado em um link no final deste post.



O artigo propoe desmistificar a confusão em que se tem ao adotar, em um mesmo ambiente de desenvolvimento de software, as metodologias CMMI e métodos ágeis. O autor afirma que o correto é se aproveitar ao máximo as melhores vantagens de ambos, já que as duas abordagens aplicam as melhores práticas da Engenharia de Software. Não sendo, portanto, saudável à profissão, se adotar uma postura favorável ou contra a qualquer um dos paradigmas. 

O autor ainda afirma que o mal uso de ambos os métodos por mais de 20 anos, causado pelo mal entendimento e o uso exacerbado de suas técnicas, é o que tem resultado o desentendimento e a conclusão errônea de que, as suas aplicabilidades atrapalham o sucesso de um projeto de desenvolvimento de software. 

O desentendimento muitas vezes ocorre mesmo em ambos os lados. Na comunidade CMMI existe a escassez de conhecimento profundo em torno dos métodos ágeis. Por outro lado, existe um conhecimento também superficial da comunidade ágil em relação ao CMMI. 

A falta de conhecimento muitas vezes se deve ao fato da definição de diversas terminologias específicas de seus contextos, como por exemplo, Garantia da Qualidade e Previsibilidade no CMMI e Integração Contínua e Código Coletivo em metodologias ágeis, conforme citado pelo autor. 

Outro fator de insucesso na aplicação conjunta desses dois conceitos está na diferença das duas abordagens, sendo uma bottom-up contra a outra, top-down, o que negligencia a visão de negócios, que deveria ser o que mais importa ao sucesso de um projeto de software. 

Algumas curiosidades foram encontradas no artigo. O autor reconhece que a maneira como o CMMI foi criado causou o desentendimento e a sua má aplicabilidade. Um outro ponto é que as pessoas na comunidade ágil reconhecem o fato de conhecerem muitos aspectos relacionados ao CMM mas desconhecem tudo o que envolve o CMMI. O CMM não é atualizado desde 1993, o que evidencia que encontra-se descontinuado devido à criação do CMMI. 

Uma outra cultura problemática nos tempos de hoje é que usuários do CMMI que usavam o CMM se atualizaram mas ainda continuam usando conceitos do modelo antigo. 

  • A origem dos dois extremos:

O segundo capítulo se dedica a descrever as origens de cada abordagem. As metodologias ágeis foram inspiradas no IIDD (Desenvolvimento e Projeto Iterativo e Incremental), adotado há 75 anos na área de engenharia e posteriormente proposto ao desenvolvimento de software por Edward Deming. Na década de 90, após a adoção official de alguns métodos ágeis, como o XP, introduzido na Chrysler, o manifesto ágil foi escrito e, em poucos anos esta filosofica IIDD foi disseminada rapidamente pelo mundo devido à quantidade de adeptos de renome que obtiveram sucesso em seus projetos. 

Já o CMMI teve sua origem em abordagens top-down em projetos de contratos fechados principalmente desenvolvidos na linguagem COBOL. Uma primeira solicitação de sua criação e formalização foi feita pelo DoD (Departamento de Defesa dos E.U.A) ao que hoje chamamos de SEI (Software Engineering Institute) para melhorar a qualidade de seus projetos de software, pois, chegaram à conclusão de que a maioria deles eram muito custosos e não eram entregues ou eram entregues com atraso com poucas funcionalidades como o esperado. Os sistemas desenvolvidos nesse contexto eram comumente considerados críticos, ou seja, vidas poderiam ser perdidas em decorrência das falhas de software. 

Além desses fatores, os sistemas desenvolvidos para o DoD muitas vezes tinham um alto custo de deploy e testes, e não poderiam ser mais admitidas as entregas monolíticas e inconstantes. Um sistema embarcado em um avião caça em 1980, por exemplo, não poderia ser atualizado durante o voo ao se perceber uma falha. Logo, fazer o software corretamente da primeira vez era criticamente importante. 


  • Fatores que afetam nossa percepção:



De acordo com o relatado pelo autor sobre o uso do CMMI nas organizações, o mesmo constata uma questão um tanto quanto curiosa: a perseguição pelos níveis de maturidade, através do conjunto de processos adotados, a empresa perde um pouco o foco no valores do ponto de vista do cliente, do produto, em torno dos projetos, e objetivos de negócios dos profissionais. 

Os profissionais que implementam o CMMI nas organizações muitas vezes falham em garantir que os processos adotados são totalmente implantados com sucesso nos novos projetos. Muitas vezes também não revisam os processos de acordo com as lições aprendidas e, os mesmos acabam se tornando incompatíveis com as práticas individuais e do time de desenvolvimento, além de se tornarem inflexíveis à adaptação de acordo com a necessidade do projeto. Um último ponto de falha na implantação é que, muitas vezes, os processos são descritos com um nível de formalismo que se torna de difícil entendimento pelos profissioniais, fator este que causa a sua rejeição. 

Para a implantação do CMMI com sucesso, deve-se considerar o equilíbrio exato adotado pela organização, avaliando prerrogativas do projeto e individuais, analisando as responsabilidades estabelecidas às pessoas, confiança, negócios e considerações também culturais. Se esse equilíbrio é afetado em favor da organização, os projetos e os profissionais podem perder a flexibilidade necessária que eles precisam para atingir o sucesso profissional e a motivação desejada. Por outro lado, muita flexibilidade pode expor a organização a um grande risco e podem perder a oportunidade do aprendizado organizacional, o que pode levar a uma maior qualidade dos projetos ao longo prazo. É difícil, portanto, se atingir o equilíbrio ideal. 

Um grande e comum engano que ocorre pelas pessoas que utilizam o CMMI é a de encará-lo como um padrão, quando na verdade ele é um modelo de processos. As suas práticas propostas não são um conjunto ordenado de atividades a se seguir dentro de um processo específico. Quando se usa o termo “modelo”, a intenção é dizer que o método pode ser customizado de acordo com a necessidade, ou seja, as práticas são utilizadas conforme a necessidade da organização em qualquer momento de sua realidade. O CMMI também encoraja o experimento de outros modelos, práticas, frameworks e abordagens para a melhoria dos processos conforme a necessidade. 

Em suma, o CMMI formou ao longo de muitos anos de pesquisa, uma base sólida de conhecimentos necessários aos projetos de software e metodologias atuais. CMMI não foi concebido para ser um substituto ou uma definição de qualquer coisa no mundo real, e isto é que é um modelo. Portanto, é apenas um ideal construído para se definir boas práticas de situações no mundo real. 

O que acontece é que muitas vezes, justamente por encará-lo como um padrão, ao invés de um modelo, o CMMI acaba sendo aplicado, quando deveria, na verdade, ser implementado. Isto faz com que se perca o foco no produto e ganhe foco mais na avaliação da organização, algo puramente comercial em muitos casos. 

A implementação então, no mais correto conceito, se dá em utilizar o modelo da mesma maneira em que arquitetos e engenheiros da construção civil usam seus modelos: como uma ferramenta de aprendizado, comunicação, e principalmente, como um meio de organizar seus pensamentos. Já a aplicação é a corrida desenfreada em tentar se tornar exequível todas as práticas por ele propostas.

  • A verdade por trás do CMMI:

Um fato que muitas vezes é contrariado principalmente pela ocorrência da desinformação é que, analisando holísticamente os últimos objetivos do CMMI, os seus propósitos são os de tornar os processos de desenvolvimento de software menos pesados, eliminando tudo o que causa a improdutividade, assim como é proposto nas metodologias ágeis. Além disso, diferentemente dos métodos ágeis, o CMMI oferece toda a infra-estrutura de aprendizado organizacional e benefícios de melhorias passadas para os projetos que ainda nem começaram. 

Para se reforçar a idéia de que o CMMI é um modelo, o autor exemplifica dentro de alguns objetivos e suas práticas-chave, o único ponto que deve ser obrigatório a se seguir são os objetivos, já as práticas são opcionais, ou seja, é possível se escolher apenas algumas, desde que se atenda ao objetivo do modelo para a melhoria de uma área de processo que traga mais valor ao negócio da empresa. 

De acordo com essa preocupação de se utilizar o CMMI corretamente, foram criadas as avaliação SCAMPI, a qual é utilizada para analisar se a empresa está utilizando o CMMI como um modelo mesmo e não um padrão. Esta análise é feita através de estórias, ou temas, que sugerem visões para dar base a um analisador ou uma equipe de análise de processos. 

  • A verdade por trás das metodologias ágeis:

Na intenção de relatar as verdades que ocorrem também em torno dos manifestos ágeis o autor nos revela também pontos problemáticos na sua abordagem. Existem muitos depreciadores da mesmas que fazem um mau uso, ganhando a fama de “lacaios indisciplinados”, pois, ao analisar o Manifesto Ágil, os mesmos acabam julgando que as práticas por ele propostas são a verdade absoluta ao sucesso de um projeto, sendo que na verdade, o que o manifesto diz é que devemos buscar mais as suas práticas ao invés das sugeridas por métodos tradicionais, mas não que devemos evitá-las. Muitas vezes essas pessoas apenas usam desses argumentos para se ter a total liberdade em seus processos, o que na verdade, os torna caóticos e não caracterizam qualquer metodologia. 

Um ponto marcante das metodologias ágeis é que as mesmas privilegiam o conhecimento tácito das pessoas (como no manifesto ágil: iterações entre os indivíduos ao invés de processos e ferramentas). Este fator pode beneficiar diretamente a organização baixando o custo de seus processos de Engenharia de Software

Os riscos de processos centrados no conhecimento tácito são mitigados pelos seguintes fatores: 

- A duração do projeto e do ciclo de vida esperado (feito em “Time-Boxes” previsíveis); 

- A natureza moderna de auto-documentação dos códigos-fonte; 

- O uso de ferramentas de engenharia reversa para documentar o projeto e ferramentas que integram pequenos pedaços do código continuamente; 

- Equipes pequenas (o que traz baixa rotatividade de pessoal). 

O grande risco é quando há ausência de processos, disciplina e regras para planos ou planejamento do projeto. 

Cada palavra utilizada no manifesto ágil foi escrita cuidadosamente para denotar que se deve, portanto, dar prioridade aos conceitos estabelecidos e, no entanto, não devem ser interpretados como sendo a verdade absoluta. Algo semelhante ao engano que se comete no CMMI ao se aplicar todas as práticas rigidamente ao invés de se propor um modelo que atenda aos objetivos gerais. Algo que a abordagem SCAMPI vem tentando mudar. 

  • Conclusão: Há valor em ambos os paradigmas!



O que se prentende demostrar através de todos esses conceitos e fatos é que, há valor em ambos os paradigmas. CMMI e práticas ágeis são compatíveis pois, diferentemente do que se pensa, elas tratam de níveis diferentes de abstração, pois o CMMI trata dos processos visando a maturidade da organização, enquanto que as metodologias ágeis focam nos artefatos a nível de projeto. No entanto, quando se traz o CMMI também ao nível de projetos, é comprovado que ambos são realmente compatíveis, já que o CMMI diz o que o projeto deve fazer, e não em qual metodologia deve-se aplicar, podendo então se utilizar qualquer uma que tenha um alto nível de maturidade, como é o caso dos métodos ágeis. 


A sinergia proveniente do uso dos dois paradigmas podem trazer inúmeros benefícios. Os métodos ágeis podem fornecer o “how-to” (como fazer) para as melhores práticas do CMMI que funcionam bem ao contexto do projeto. Por outro lado, o CMMI fornece toda a engenharia para se sustentar as práticas ágeis em grandes corporações. Além disso, o CMMI pode fornecer todo o gerenciamento dos processos que ajudarão a manter e melhorar continuamente a implantação de uma abordagem ágil em uma organização. 

Um dos maiores desafios dos projetos que utilizam as metodologias ágeis nos dias de hoje, é a obtenção de escala para grandes projetos e até mesmo de manter o alinhamento quando se tem diversos projetos em uma mesma empresa. Quando não há a preocupação neste patamar organizacional, os riscos não são devidamente controlados e os requisitos não-funcionais ou arquiteturais acabam sendo deixados de lado. Para tanto, o CMMI oferece uma abordagem eficiente para gerir em grande escala. Uma outra tendência neste tipo de gerenciamento está em um novo modelo organizacional, também ágil, baseado em Scrum de Scrums

Já no CMMI o grande desafio está no que já havia sido comentado: flexibilizar o projeto e assim aplicar o tailoring correto às necessidades da empresa, priorizar os objetivos de negócio ao invés de focar na corrida da obtenção de certificação. As práticas, ao se atingir um determinado nível de maturidade, pode trazer valores imediatos. No entanto, a longo prazo, essa maturidade pode ser perdida devido à sobrecarga de processos rumo a um novo nível

O autor julga que muitas literaturas recentes para o CMMI são meras anedotas ao criticar as metodologias ágeis. O mesmo acontece no lado oposto. Há também um julgamento precoce em torno da adoção de um paradigma ou outro ao se tentar aplicá-los em um projeto piloto e o mesmo falhar. Logo, o paradigma é tachado de falho e em seguida abandonado. 

Em suma não existe um paradigma melhor que o outro, o que há são melhores abordagens para cada situação ou necessidade, variáveis instrínsecas ao perfil da organização. Em acréscimo a essa idéia, o autor afirma que, em grandes organizações, obtem-se uma melhor maturidade nos processos utilizando-se da sinergia resultando da junção dessas duas abordagens. O benefício colhido a longo prazo, sengundo pesquisas, se torna extremamente satisfatório. 

Quando o CMMI é implementado de forma adequada, pode fornecer a infra-estrutura necessária para dimensionar com êxito a gestão e as entregas de sistemas complexos, mantendo as vantagens do desenvolvimento iterativo e incremental que as metodologias ágeis oferecem. 

Segundo citações do autor, é recorrente vermos em discussões sobre o assunto pela comunidade ágil que, CMMI e metodologias mais tradicionais como o processo em cascata são colocados como sinônimos, o que é de fato errôneamente interpretado! O CMMI transcende tais definições, pois, este paradigma não se enquadra no conceito de métodos ágeis e muito menos à métodos tradicionalistas. 

A tendência em se formar campos distintos, tais como os que separam CMMI e Agile, é inerente à característica humana, mesmo quando falamos em desenvolvimento de software. O autor então defende que devemos ter um único objetivo em mente: unir as comunidades em uma só. Assim, ganhariamos em discussões com o intuito de se comparar resultados, facilitando também a experimentação e aprendizado.


  • A referência: 





Finalizo por aqui pessoal deixando a seguinte pergunta: 

Você concorda com as afirmações deste autor? O que você mudaria ou acrescentaria a essas idéias?


Um grande abraço e até o próximo post!  :-)


.

27 de jul. de 2010

CVS X Subversion





Olá pessoal,

hoje gostaria de tratar sobre um assunto que, por mais que esteja bem conceituado e conhecido por todos, sempre gera uma certa polêmica ao se tomar uma decisão a respeito. Estou falando da definição de um sistema de controle de versões (Software Configuration Management - SCM) para controlar e gerenciar a evolução dos artefatos gerados por um projeto de software.

Embora existam dezenas de sistemas dessa linha, tratarei aqui apenas dos mais utilizados atualmente no mercado: o CVS e o Subversion (SVN) frutos de uma boa e produtiva discussão gerada na empresa onde trabalho. Fato que me motivou a escrever sobre este tema após coletar dados e pesquisas suficientes para argumentar a migração do nosso SCM atual, o CVS, para o Subversion. Para uma completude das argumentações, também era necessário se levantar uma forma de migrar todos os dados hisóricos do repositório do antigo para o novo sistema.

Para resumir a comparação entre as duas tecnologias, criei uma tabela que cruza características dos dois sistemas em uma perspectiva de administração da ferramenta, que é o que no fundo mais importa, já que as ferramentas utilizadas como clientes para acessa-las são muito parecidas e de fácil assimilação, o que não influenciaria em nada como vantagem ou desvantagem entre um e outro sistema de versionamento.




CVSSubversion
ArmazenamentoÉ feito em arquivos RCS. Estes arquivos são criados em toda a árvore de diretórios do projeto para versionar arquivo por arquivo. Possibilita maior poder para recuperar possíveis falhas apenas editando esses arquivos.É feito em banco de dados Berkley DB. Existem aplicativos para a recuperação de falhas.
ConcorrênciaExistem problemas de acesso concorrente por se tratarem de arquivos em disco.Acesso concorrente transacionado pelo banco de dados.
VelocidadeMais lento pelo fato de usar file system.Mais rápido. O único problema de velocidade está no momento de se conectar ao repositório e fazer o primeiro checkout, já que ele traz uma cópia local de todos os arquivos.
VersionamentoGerencia versões diferentes para cada arquivo do projeto. Permite a criação de branchs e tags por arquivo. Não permite restaurar a versão do projeto à partir de uma tag específica.Para cada branch ou tag, cria-se uma cópia no repositório e todos os arquivos do projeto ganham um número identificador de 4 dígitos. Ao se configurar um branch, o SVN cria uma tag correspondente no início, mas depois que se dá o primeiro commit, ele se transforma no branch e o novo versionamento se inicia imediatamente. Permite restaurar a versão do projeto à partir de uma tag específica.
MetadadosNão armazena metadados, somente arquivos.Permite que se vincule e versione também atributos relacionados aos arquivos, esses atributos são configurados na forma de par “chave=valor”.
Tipo de arquivos comportadosBom para armazenamento de arquivos texto. Problema em armazenar binários. Também não é possível se fazer diff de binários.Todos os tipos de arquivo.
RollbackPermite, no entanto tem que se faze de arquivo por arquivo.Não permite, tem que ser fazer cópias de versões em bom estado.
Transações – IntegridadeNão possui a teoria do “ou tudo, ou nada” pois, quando há conflitos, os arquivos afetados deixam de serem “commitados”, sendo que os estão íntegros(sem conflito) vão para o repositório mesmo assim.Possui o conceito do “ou tudo, ou nada”. Assim, os números das revisões são marcados apenas quando todos os conflitos foram resolvidos e finalmente se dá o commit. Permite também configurar grupos para commit.
Lock de arquivosNão possui.Possui. Se um usuário bloqueia o arquivo, ele fica como “somente leitura” para os outros.
InteroperabilidadeNão possui.Pode se comunicar via Http e ssh.
Integração com o RedMine Possui.Possui.
Integração com o HudsonPossui.Possui.



Reparem que ao final da tabela de avaliação eu cito duas integrações com outros sistemas: RedMine e Hudson. O RedMine é um sistema de gerência de projetos que utilizamos na empresa. Já o Hudson é o sistema de integração contínua open-source mais utilizado do mercado. Estas duas ferramentas se tornam muito valiosas para se fechar o círculo formado pelos componentes necessários a uma Gestão de Configuração eficaz. Pretendo abordar algo sobre elas e sobre a teoria em torno da Gerência de Configuração e Mudança em breve!

Ok, podemos concluir pela tabela que, o SVN possui uma série de características mais arrojadas que o CVS, mas ainda fica uma pergunta no ar: se a necessidade era também a de migrar os dados, como faríamos isto sem que perdêssemos todos os dados históricos das tags e branchs criados?

Para a árdua tarefa de migração também já existe uma ferramenta muito difundida: o CV2SVN... Ufa! 

Esta ferramenta basicamente percorre toda a estrutura de diretórios do projeto afim de mapear e migrar todos os dados históricos de branchs e tags criadas para o novo repositório. Ela permite também que se configure os dois SCM's para sincronizar as alterações de arquivos de um para o outro.

Os nossos próximos passos são instalar então o SVN e CVS2SVN e colocar a migração em prática. Prometo relatar os resultados e todo o caminho das pedras nos próximos posts!


Seguem algumas referências importantes sobre o assunto:


Sites para documentação:




Estratégia de migração:




Outras referências:




Fiquem à vontade para deixar os seus comentários!


Um abraço a todos e até o próximo post! ;)


.

19 de mai. de 2010

Design Patterns na Prática - Parte II: Abstract Factory



Continuando a nossa série, apresento-lhes mais um padrão de projeto criacional: Abstract Factory.

Temos a seguinte situação:

Um banco possui dois tipos de contas:
  • Corrente
  • Poupança

Cada uma delas pode ser categorizada como:
  • Simples
  • Normal
  • Plus

Cada uma dessas características possuem as suas vantagens particulares. Como aplicar um padrão de projeto criacional nesses objetos de maneira a ter-se menos impacto ao inserir-se um tipo de conta nova ou mais características das contas?

Resposta:  Abstract Factory!



 Temos então 3 tipos de fábrica de contas poupança ou corrente de acordo com o tipo necessário, são elas: TipoSimples, TipoNormal e TipoPlus. Todas essas fábricas concretas são representadas pela Fábrica Abstrata TipoConta, que é quem define os métodos de criação, ou seja, qualquer que seja a nova fábrica a ser criada para contas, ela deve ser capaz de criar os novos tipos de conta de acordo com o proposto por essa abstração. Assim definimos o processo de criaçõ totalmente flexível: não precisamos mudar nenhum código existente para criarmos mais um tipo de conta!


Concluindo, apresento-lhes a ficha resumida deste padrão:  


Objetivo:
  • Fornecer uma interface a ser utilizada para criar famílias de objetos relacionados ou dependentes sem realmente especificar suas classes concretas.

Benefícios: 

  • Isola o cliente das classes concretas(da implementação). Facilita a troca de famílias de objetos;
  • Promove a consistência entre objetos.

Aplicabilidade:

  • O sistema precisa ser independente da maneira como seus objetos são criados, compostos e representados;
  • O sistema precisa ser configurado com um objeto de uma família de vários objetos;
  • A família de objetos relacionados é concebida para ser utilizada em conjunto e essa restrição precisa ser imposta;
  • Deseja-se fornecer uma biblioteca de objetos que não mostre as implementações e somente revele as interfaces. 
  •  
    Então é isto galera! Qualquer dúvida, é só deixar o seu comentário que tentarei ajudar o mais rápido possível! ;)

    Um abraço a todos e até o próximo post!


    .

    12 de mai. de 2010

    Design Patterns na Prática - Parte I: Builder



    Olá pessoal! Hoje darei início a uma série de "rapidinhas" sobre a aplicação de design patterns em exemplos práticos. Darei um problema e, em seguida, a modelagem de uma solução adequada. Espero que aproveitem!

    O primeiro padrão a ser tratado trata-se de um comumente utilizado em projetos de software quando se tem a intenção de criar objetos complexos dinâmicamente e de maneira flexível sem precisarmos fazer isto de explícitamente.

    Basicamente, o objetivo deste padrão é separar a construção de um objeto complexo da sua representação, de modo que o mesmo processo de construção possa criar diferentes objetos. Estou falando nada mais, nada menos, do incrível padrão Builder!

    Vamos então ao que interessa:

    Uma aplicação envia um XML a outra contendo os seguintes campos abaixo:

    <header>...</header> 
    <body>
                <struct1> 
                      <campo1>...</campo1>...<campo2>...</campon>….
                </struct1>
                <struct2> 
                      <campo1>...</campo1>...<campo2>...</campon>….
                </struct2>
                …. 
                <structn> 
                      <campo1>...</campo1>...<campo2>...</campon>….
                </structn>
    </body>
    <trailer>...</trailer>


    O problema é criar uma interface para enviar alguns parâmetros e buscá-los de um banco de dados (ex: um registro de uma pessoa como nome, endereço, etc...) e a mesma traga o XML apropriado montado. Utilizamos então para isto um design pattern do tipo criacional para se construir as classes necessárias para gerar esse XML: o Builder!




    Nossa classe com o papel de diretor (ManageXMLConstruct) coordenará a delegação da construção às fábricas específicas de cada classe que representa uma tag do XML de acordo com a necessidade da construção. É o Builder entrando em ação!

    É isso pessoal, fico por aqui.


    Para qualquer dúvida, por favor, não deixe de postar o seu comentário.

    Um abraço e até o próximo post da série! ;)



    .

    20 de abr. de 2010

    Padrões de Projeto ( Design Patterns ) - O que são?



    Padrões de Projeto (os Design Patterns), são combinações de classes e algoritmos associados que cumprem com propósitos comuns de projeto. São normalmente soluções consagradas que se baseiam nas estruturas da orientação a objetos em sua melhor forma.

    Cada padrão descreve um problema no nosso ambiente e o cerne da sua solução, de tal forma que você possa usar essa solução mais de um milhão de vezes, sem nunca fazê-lo da mesma maneira.

    Os padrões de projeto, basicamente, se dividem em grandes 3 categorias: Criacional, Estrutural e Comportamental.
     
    São 4 os elementos importantes que definem um Padrão (Pattern), são eles:

    • Nome: A identificação do Pattern é importante pois ele torna-se membro do vocabulário do projetista e de seus colegas; 
    • Problema: descreve quando aplicar o Pattern. Apresenta a classe de problemas em questão e seu contexto; 
    • Solução: descreve os elementos que fazem parte do design, seus relacionamentos, responsabilidades e colaborações; 
    • Conseqüências: os resultados e efeitos causados pela aplicação do pattern.

    Para se descrever e catalogar um Padrão de Projeto com total completude de informações, são necessários os seguintes dados:

    • Nome do Pattern e Classificação: Passa a fazer parte do vocabulário dos projetistas;
    • Propósito: Respostas para as perguntas - O quê o Pattern faz? Que tipo de problema ou característica particular de Design ele trata?
    • Também Conhecido Como: Conjunto de outros nomes (apelidos) conhecidos para o Pattern, se existir algum;
    • Motivação: Um cenário que ilustra o problema de Design e como as estruturas de classes e objetos no Pattern o resolvem;
    • Aplicação: Respostas para as perguntas - Quais são as situações onde este Pattern pode ser aplicado? Quais são os exemplos de Designs que ele pode tratar? Como você pode reconhecer estas situações? 
    • Estrutura: Uma representação gráfica das classes no Pattern. Participantes: As classes e/ou objetos que participam no Design Pattern, e suas responsabilidades;
    • Colaborações: Como os participantes interagem para cumprir suas responsabilidades;
    • Conseqüências: Respostas para as perguntas - Como o Pattern alcança seus objetivos? Quais são os resultados do uso do Pattern?
      Implementação: Dicas e técnicas que Designer deve saber, e possíveis armadilhas para as quais ele deve estar preparado;
    • Código Exemplo: Fragmentos de código que ilustrem como o Pattern deve ser implementado;
      Usos Conhecidos: Exemplos de utilização do Pattern em sistemas já implementados;
    • Patterns Relacionados: Lista de todos os Patterns fortemente relacionados ao Pattern em questão e as suas principais diferenças.

    Atualmente existem diversos catálogos de padrões já criados,  dentre os grandes, posso citar alguns aqui:
    • Padrões Gof 
    • Padrões JEE 
    • Padrões Microsoft
    • Padrões Corporativos 
    • Padrões de Integração 
    • Padrões SOA

    Os Patterns são oriundos de alguns princípios de programação, como por exemplo, o Design de Objetos, o que se torna algo complexo em projetos de software, já que muitos parâmetros estão implícitos neste conceito, como encapsulamento, granularidade, dependência, flexibilidade, desempenho, evolução e reutilização.

    Muitos objetos oriundam da análise, e muitos destes não são abstrações do mundo real, como vetores por exemplo. Por outro lado, existem objetos que raramente aparecem durante a análise, e sim, aparecem para auxiliarem a fase de projeto. Logo, os padrões de projeto ajudam a identificar abstrações menos óbvias bem como os objetos que podem captura-las. Padrões como Composite (tratamento uniforme de objetos que não têm uma contrapartida física), Strategy (descreve como implementar famílias de algoritmos intercambiáveis) e State (representa cada estado de uma entidade como um objeto) são bastante úteis, como exemplo.

    A granulidade de objetos:

    Objetos podem variar tremendamente em tamanho e número. Podem representar qualquer abstração. Os padrões de projeto auxiliam no tratamento da granularidade. Tem-se como exemplo:

    Façade: Descreve como representar subsistemas completos como objetos;

    Flyweight: Descreve como suportar enormes quantidades de objetos nos níveis de granularidade mais finos;

    Abstract Factory: Fornecem objetos cujas únicas responsabilidades são criar outros objetos;

    Command: Fornecem objetos cujas únicas responsabilidades são implementar uma solicitação em outro objeto ou grupo de objetos.

    Especificação de Interfaces: 

    Um bom conceito O.O para se programar utilizando padrões de projeto é: "Programa para interfaces, nunca para uma implementação".

    Uma interface é o conjunto de assinaturas declaradas por um objeto, sendo que cada operação declarada (Assinatura) especifica o nome da operação, os objetos que ela aceita como parâmetros e o valor retornado por ela.

    Um tipo é um nome usado para denotar uma interface específica. Quando um objeto tem um tipo “Janela”, significa que ele aceita todas as solicitações para as operações definidas na interface chamada “Janela”.
    As interfaces são fundamentais para a programação orientada à objetos. Objetos devem ser conhecidos somente por suas interfaces e, quando uma mensagem é enviada a um objeto, a operação específica que será executada depende da “mensagem” e do objeto “receptor”. Na prática, significa que diferentes objetos que suportam solicitações idênticas, podem possuir diferentes implementações para atender estas solicitações, é o chamado Polimorfismo entrando em cena!

    A associação em tempo de execução de uma solicitação a um objeto e a uma das suas operações é conhecida como ligação dinâmica (dynamic binding). Essa ligação auxilia o polimorfismo que por sua vez, simplifica as definições dos clientes, desacopla objetos entre si e permite a eles variarem seus inter-relacionamentos em tempo de execução. Os padrões de projeto auxiliam o uso do polimorfismo bem como o uso de interfaces, além de ajudarem a definir as interfaces pela identificação de seus elementos-chave e pelos tipos de dados que são enviados através das assinaturas das operaões contidas nas mesmas.

    Classe do objeto (implementação) x Tipo do objeto (interface): um objeto pode ter muitos tipos, e objetos de diferentes classes podem ter o mesmo tipo;

    Herança de classe x Herança de interface: a herança de classe define a implementação de um objeto em termos da implementação de outro objeto (é um mecanismo para compartilhamento de código e de representação), já a herança de interface descreve quando um objeto pode ser usado no lugar de outro.

    Dado todo este contexto, uma outra dica O.O importante é: não declarar variáveis como instâncias de classes concretas específicas. Isso dá maior flexibilidade ao código e ajudará no polimorfismo.


    Herança e Composição:

    As vantagens de se utilizar herança nos seus projetos O.O. basicamente são: simplicidade e rapidez na execução (definida em tempo de compilação) e que a mesma permite alterar com facilidade a implementação herdada (reuso). 

    Já entre as desvantagens, podemos citar: a herança não permite alterar a implementação herdada em tempo de execução e expõe para as classes descendentes, os detalhes da implementação, ferindo assim, o princípio do encapsulamento. A dependência da implementação herdada também prejudica no reuso das classes. 

    As vantagens da Composição basicamente são: os objetos são acessados somente através de suas interfaces, sem violar o encapsulamento e proporcionando independência de implementação, além do fato de que, com classes em que um número pequeno de heranças é usado e temos papéis bem definidos e focados, aumenta-se então, a capacidade de reutilização.

    As desvantagens da Composição podem ser: como neste caso a herança diminuirá, e o número de objetos no sistema aumentará, e consequentemente, a performance do sistema que utiliza a composição dependerá de como será feito o inter-relacionamento entre esses  objetos.


    Delegação:

    É um princípio muito importante e que também é largamente utilizado nos Padrões de Projetos, se baseia no envolvimento de dois objetos ou mais objetos que visam atender a uma determinada solicitação (utiliza poderosamente a composição de objetos).

    Exemplificando-se tem-se uma classe “Window” em “Rectangle”. Em vez de se fazer “Window” sub-classe de “Rectangle” (uma Janela é retangular!), ela reutilizaria o comportamento de “Rectangle”. Em vez de dizer que uma “Window” é um “Rectangle”, diremos então que uma “Window” possui um comportamento de um “Rectangle”.

    A principal vantagem disso é que se “Window” em tempo de execução, quiser ter um comportamento de um “Circle” (círculo), basta utilizar uma instância de “Circle” assumindo que ambas tenham o mesmo tipo (interface).

    Existem duas desvantagens: Um código dinâmico e altamente parametrizável é mais difícil de compreender e a performance é comprometida porque definir trocas em tempo de execução possuem um “overhead” da troca de contexto antes da execução propriamente dita.

    Conclui-se que o uso da delegação é recomendável quando a mesma simplificar e não complicar o projeto.


    Um exemplo de Padrão para ilustrar esses conceitos: Bridge.




    Este padrão estrutural do GOF basicamente define um modelo no qual separa o conceito (definido pelas classes à esquerda) das suas implementações.

    A herança é utilizada nas relações entre as classes Abstraction e RefinedAbstraction, na qual uma implementação do conceito é definida pelo seu tipo. 

    Temos herança também na relação entre a interface Implementor e suas implementações ConcreteImplementorA e ConcreteImplementorB. O propósito disto é dar flexibilidade na relação entre o conceitos e suas duas formas de implementações, configurando assim a relação de delegação polimórfica entre as duas estruturas definidas distintamente.

    A composição se dá justamente nesta relação de delegação entre as duas interfaces Abstraction e Implementor, o que nos permite compor N combinações de novas abstrações (conceitos) com N tipos diferentes de comportamentos (implementações). Tal definição nos fornece então, a granularidade de objetos almejada para este propósito.

    Podemos concluir então que, RefinedAbstraction pode invocar métodos, assumindo comportamentos, (representados por sua interface) tanto de ConcreteImplementorA ou ConcreteImplementorB

    Bom, neste ponto você já deve estar pensando que poderia muito bem fazer esta relação entre conceito <-> implementação simplesmente colocando as classes ConcreteImplementorA e ConcreteImplementorB como "herdeiras" de RefinedAbstraction, mas esta falta de separação te dará algumas dores de cabeça quando você necessitar incluir mais uma forma de implementação (ConcreteImplementorC, por exemplo), já que, para se adequar a isto, teria-se que modificar também a RefinedAbstraction, ou seja, o custo de manutenção, em um projeto real, vai aumentando exponencialmente e, certamente você não vai querer isso!

    É isso aí pessoal, concluo o meu post aqui e, espero ter esclarecido em poucas palavras, o que são os padrões de projeto e os conceitos e definições que o envolvem.

    Fiquem à vontade para comentar, tirar dúvidas ou sugerir melhorias.

    Um grande abraço a todos e até o próximo post!


    .

    31 de mar. de 2010

    15 Práticas Para Um Analista de Qualidade Altamente Eficaz




    Os testes de software são processos integrantes de toda e qualquer metodologia de software, basicamente são responsáveis por executar e garantir o sucesso de dois princípios básicos:

    VALIDAÇÃO = garante que se está construindo CERTO O PRODUTO;

    VERIFICAÇÃO = garante que se está construindo O PRODUTO CERTO;

    Ou seja, a Validação está intimamente ligada à conformidade com os requisitos de negócio do sistema. Já a Verificação está ligada ao processo de codificação correta do sistema, prevenindo-o de erros e falhas.

    Baseado nesses princípios e na busca de que o mesmos estejam nos projetos de maneira efetiva, eu gostaria de expor, de maneira bem genérica, as principais práticas de um profissional responsável por executar e gerenciar o processo de testes em projetos de software. Tais práticas são consenso de mercado e indicações de sucesso no processo de testes, o que indica que o profissional que as adota pode ser considerado um profissional altamente eficaz. Logo, se você, profissional da área de testes, almeja obter êxito em sua profissão, fique ligado às dicas! ;)

    Vamos então a elas:

    1 - Prepare um documento de abordagem de teste e plano de qualidade; 

    2 - Obtenha a aprovação durante o planejamento dos testes;

    3 - Defina os ambientes de teste necessários e garanta a clareza na execução dos testes;

    4 - Documente o gerenciamento de configuração e garanta a rastreabilidade;

    5 - Separe os testes funcionais de testes operacionais e de performance;

    6 - Estabeleça frameworks para a melhoria contínua para o processo de testes;

    7 - Tenha usuários de negócio envolvidos para identificar as regras-chave para o processo de descoberta de condições;

    8 - Use desenvolvimento de scripts de testes e revisão;

    9 - Faça testes de regressão;

    10 - Automatize o rastreamento de problemas e outros itens que requerem um vínculo;

    11 - Use ferramentas de workflow para construção de rastreamento e atividades de teste;

    12 - Estabeleça uma abordagem de reporte que permita exportar para dashboards de métricas voltadas para os gerentes, certamente eles vão te cobrar isso!

    13 - Faça a arquitetura de processos de testes e ambientes para existir durante toda a vida da aplicação;

    14 - Desenvolva um framework para testes de regressão e construa softwares de testes automatizados que deixem claro o Retorno Sobre Investimento do projeto, conhecido também, do inglês, ROI (Return On Investment);

    15 - E por último, mas não menos importante: Rigorosamente, organize os dados de teste e aplique controle de versão.


    E então, como é implementado o processo de testes em seus projetos? Há algo semelhante com o comentado aqui? Você, profissional de qualidade, se preocupa com tais práticas? Você teria mais alguma boa prática para complementar este post?

    É isso pessoal, espero que aproveitem as dicas. 

    Por favor, não deixem de opinar sobre o que foi escrito! ;)

    Um grande abraço e até o próximo artigo!


    .

    8 de mar. de 2010

    Capacidades da Arquitetura Ideal




    Gostaria de abordar hoje sobre as capacidades que uma arquitetura bem planejada deve contemplar para proporcionar bons índices de qualidade. Este tema se torna extremamente importante se olharmos sob a ótica de que a qualidade afeta diretamente a satisfação do cliente e envolvidos com o sistema, sendo um ponto fundamental para o sucesso de um projeto de software.

    Foram eleitas basicamente as seguintes 11 capacidades:

    Disponibilidade

    É a capacidade do sistema se manter no ar para uso devido. Diz-se que o sistema possui alta disponibilidade quando se mantém disponível a maior parte do tempo. Quando se contrata serviços de infra-estrutura, geralmente é acorda um percentual de disponibilidade que tal infra deve garantir, podendo pagar multas caso não cumpra o acordo, são as chamadas SLA's de disponibilidade.


     Robustez

    É a característica pela qual se mede o nível de tolerância a falhas do sistema. O software deve ser capaz de prever situações inusitadas vindas de seus usuários e reagir com medidas que o mantenha estável, ou seja, sem apresentar falhas.


    Gerenciabilidade

    É a capacidade que mede o quão um sofware é configurável. A configuração dos níveis de logs gerados por um determinado software é um bom exemplo disso.


     Flexibilidade

    Característica inerente à maneira em como um determinado software se comporta à mudanças, tanto arquiteturais quanto funcionais. Por exemplo, se um software hoje acessa uma base de dados Oracle, diz-se que ele é flexível caso seja possível mudá-lo para acessar uma base de dados SQL Server sem que para isso sejam necessárias grandes alterações em seu código-fonte.


     Desempenho

    Esta característica está relacionada à utilização de recursos, como por exemplo, o tempo de processamento de uma grande quantidade de mensagens em uma fila JMS ou o tempo de processamento de uma consulta no banco de dados.


     Capacidade

    Se refere às limitações impostas ao sistema, com o que o sistema deve suportar. Por exemplo: um sistema deve suportar 500 acessos simultâneos.


    Resiliência

    Este nome um tanto quanto "exótico" se refere ao grau de estabilidade do sistema mediante a picos de processamentos. Exemplo: um determinado sistema tem que suportar uma carga durante 3 horas e depois voltar ao seu estado normal sem sofrer quedas ou gerar defeitos.


    Escalabilidade

    É a capacidade de um determinado sistema ser flexível a ponto de prever o seu crescimento, ou seja, possbilita o seu incremento de funcionalidade e capacidades sem se tornar obsoleto, acompanhando sempre as necessidades do usuário.


    Extensibilidade

    É a capacidade que o sistema tem de crescer pela adição de novos componentes e que, muitas vezes, permita ao sistema fazer algo que ele já faz, mas de forma diferente. O polimorfismo em classes é um bom exemplo de extensibilidade em sistemas orientados a objetos, sendo possível através do uso de programação para interfaces e  nunca para classes com implementação concreta.


     Reusabilidade

    Permite que um determinado sistema seja usado em contextos diferentes, ou então, que seus componentes sejam usados também em outras aplicações. Este tipo de reusabilidade de componentes facilita muito o desenvolvimento de aplicações corporativas, pois, proporciona uma maior facilidade de manutenção e ganho na produtividade do software.


    Segurança

    É a característica que permite avaliar o quanto um sistema é protegido, dadas as suas condições de exposição, contra ataques ou falhas internas ou externas que gerem inconsistências em suas informações ou outros tipos de defeitos, compromentendo a todas as outras capacidades aqui citadas. 
    Um bom sistema deve prover condições de segurança nos quisitos autenticidade,  confidencialidade,  integridade e disponibilidade.

     

    Fico por aqui pessoal. Para qualquer dúvida ou complemento das informações aqui postadas, não deixem de postar os seus comentários.   ;)

    Um grande abraço e até o próximo post!

    .

    22 de fev. de 2010

    JEE 6 está bombando de novidades!




    A especificação JEE foi finalizada em Dezembro de 2009, trazendo algumas características novas e outras atualizadas para o mundo do desenvolvimento de aplicações corporativas. Temos por exemplo, a introdução de um novo conceito: a abordagem por perfis (profile approach), que foca nas divisões por áreas de interesse entre os desenvolvedores de aplicação, sendo o Web Profile o primeiro profile definido pelo expert group, o qual objetiva fornecer o mínimo de esforço de configuração aos desenvolvedores de aplicação web típicas. O objetivo deste post é dar uma breve descrição das novidades que pesquisei e achei mais interessantes. Espero que gostem.
    Um pouco das principais novidades do web profile:

    - Servlet 3.0:

    Em frameworks web, os servlets são comumente utilizados como um ponto de entrada da aplicação para processar as requisicões, poderiamos dizer então que eles são o núcleo de aplicações web. A nova versão 3.0 (JSR-315) oferece características inovadoras, tais como as anotações pertinentes a esses tipos de classes, tal como a @Servlet, @ServletFilter e @ServletContextListener, permitindo ao desenvolvedor, criar a classe como se fosse um POJO, uma classe simples, que não se prende à implementação das interfaces como era requerido nas versões anteriores. Com isso também são fornecidas uma maior flexibilidade e extensibilidade, já que ao integrar a sua aplicação a um framework MVC, você não precisaria de configurações extras. 

    - Integração entre XML's de configuração:

    Arquivos xml dos frameworks agora podem vir dentro de seus próprios arquivos JAR, já que temos uma interessantíssima novidade aqui: o contêiner JEE6 também agora tem a responsabilidade de "unir" todos os arquivos que se referem a fragmentos web.

    - Java Server Pages (JSP) na versão 2.2;


    - Expression Language (EL) também em sua versão 2.2;


    - Bibliotecas padrão para o JSP (JSTL) na sua versão 1.2;


    - Java Server Faces (JSF) na versão 2.0:

    Desde que a release do JSF 1.x saiu, o JSF foi apontado como um dos frameworks mais promissores do mercado. A sua fama entusiasmou desenvolvedores ao redor do mundo todo, fazendo com que fosse crescendo em inúmeras características agregadas, tais como componentização, validação, navegação, suporte à internacionalização (também conhecido como i18n) entre outras. No entanto, com todas essas características benéficas, algumas falhas e desvantagens foram ficando mais evidentes com o passar do tempo, tal como o quão é considerado complicado criar tarefas simples através da criação de componentes customizados.  A versão 2.0 vêm com o objetivo de remediar tais falhas facilitando o desenvolvimento e introduzindo novas características, tais como suporte a ajax integrado, os quais eram realizados apenas por implementações específicas e não propostas pela especificação JSF em si.


    Algumas das grandes novas características do JSF 2.0:
    • Composição de componentes





    Para implementar componentes customizados utilizando JSF 1.x era realmente uma tarefa nada simples. Você teria que implementar um componente visual (UI componente) e a classe tag, com a opção também de um Renderer para a marcação e então configurar tudo isso dentro do arquivo faces-config.xml e arquivos tld (Ufssss pausa pra retomar o ar!!!). JSF 2.0 simplica isso tudo através da abordagem de componentes compostos introduzidas com o Facelets.




    • Suporte integrado a Ajax



    Agora você pode utilizar-se dos poderes do ajax com toda sua API e infra-estrutura através das tags f:ajax sem se importar com a tecnologia em particular que está realizando essa implementação.




    • Manutenção de estado de objetos





    JSF 2.0 vem com uma solução para manipular requisições particulares com classes tais como PartialViewContext e PartialStateHolder, fazendo o uso de mecanismos responsáveis por guardar o estado dos objetos manipulados nessas requisições parciais. Isto já havia sido implementado antes pelo uso do Apache Trinidad, porém, estas novas classes provêm uma maneira mais elegante de realizar tal manipulação. O objetivo é ter uma versão "leve" do estado salvo para ir e voltar nas navegações de páginas web.




    • Novos escopos





    Em adição ao escopo de página (page), requisição (request), sessão (session) e aplicação (application), JSF 2.0 também introduz os chamados escopos View e Flash. Os beans cujo escopo é de View têm um ciclo de vida que é maior que uma requisição, mas é menor que beans no escopo de sessão. Já os escopos Flash são como os escopos View que irão viver dentro de uma determinada view, incluindo redirecionamentos, e que serão removidos se você os estiver movendo para uma outra view.




    • Navegação



    No JSF 1.x toda regra de navegação deveria ser adicionada ao facez-config.xml. Com a versão 2.0, navegações implícitas também podem ser usadas, no caso de uma saída retornada por um método do bean corresponder a um view id de mesmo nome. Agora também é possível se fazer navegações condicionais dentros das tags navigation-case através de marcações de expressões regulares dentro do face-config. A versão 2.0 também provê facilidades para requisições via método GET para os componentes h:link and h:button, suportando a integração de parâmetros na requisição. O benefício de se usar tais componentes é o de tornar suas páginas passíveis de serem adicionadas aos favoritos (bookmark).




    • Configuração com Annotations

    Você pode agora anotar seus beans com as novas anotações @ManagedBean e pode também       especificar o escopo do bean através das anotações @RequestScoped, @SessionScoped, @ViewScoped, @NoneScoped entre outras.


    Outras novidades:

    - Enterprise JavaBeans (EJB) 3.1 Lite;

    - Java Transaction API (JTA) 1.1;

    - Java Persistence API (JPA) 2.0;

    Na minha opinião, as principais características desta release são a nova API para queries criteria e o suporte à validações. 

    - Contexts and Dependency Injection (CDI)

    Em atendimento à Java Specification Request JSR-299, o propósito desta especificação é unir o modelo de componentes do JSF Managed-Beans com o modelo de componentes EJB, proporcionando um modelo de fácil implementação para aplicações web. CDI também torna possível para outros componentes JEE interagirem uns com os outros usando o design pattern Observer. Isto nos facilita, por exemplo, integrar enterprise beans com suporte transacional, através do lançamento de eventos de um para o outro. JSR 330 também se tornou parte do JEE 6, oferecendo um conjunto de anotações padrão que podem ser usadas para a injeção de dependência, como por exemplo, as @Named, @Inject, @Qualifier entre outras. A WELD é a implementação de referência para o CDI.

    - Bean Validation and Hibernate Validator

    A Bean Validation, JSR 303, define uma modelo de metadados e uma API para validação de beans. Sua implementação de referência é a Hibernate Validator que, em sua última versão, adiciona alguns recursos legais, tais como agrupamento de validações, integração nativa com JPA 2 e JSF 2, além de um conjunto de anotações novas.


    É isso aí pessoal, isso aqui foi só uma palinha do que de mais novo está acontecendo dentro das implementações corporativas Java, e como vocês puderam notar, JEE 6 vem bombando de novidades que aparentemente demonstram o quanto esta arquitetura vêm evoluindo em uma tendência a padronizar o que já vem sendo escrito por diversos frameworks: abordagem que exigem menos configurações e alto nível de acoplamento automático de implementações independentes. Na página da Sun vocês podem conferir a lista completa. 

    Agora é só esperarmos a comunidade java agitar com seus primeiros projetos para que a quantidade de exemplos e tutoriais aumentem!

    E vocês, podem citar outras importantes novidades do JEE 6?

    Um grande abraço e até o próximo post! ;)



    .