WCF REST Service

Olá. Nesse post vamos falar de uma combinação bastante interessante para disponibilização de computação distribuída com aplicabilidade totalmente web. Essa combinação é serviços WCF com REST e consumo client com JSON. Entrando de cabeça no assunto, em vez de passar os nomes dos contratos e operações dentro da mensagem SOAP (WS-*), REST usa Uniform Resource Identifiers – URIs; para construir os nomes dos contratos e operações. A maioria dos clients atuais (browsers web) compreendem HTTP e pode facilmente analisar URIs, fornecendo uma excelente interoperabilidade. Serviços RESTful pode receber e devolver os seus dados usando muitos tipos de encondings, como JSON, Atom, e Plain Old XML (POX), sem a dependência de um wrapper (empacotador de mensagem) especial. Atualmente muitas aplicações web usam REST para expor seus dados. A Microsoft .NET também suporta construção de aplicações REST usando WCF Services e WCF Data Services.

JSON
JavaScript Object Notation é um subconjunto da notação de objeto de JavaScript, mas seu uso não requer JavaScript exclusivamente. Ele é um formato leve para troca de dados computacionais, sua simplicidade tem resultado no seu uso difundido, especialmente como uma alternativa para XML em AJAX. Uma das vantagens sobre XML é o fato de ser muito mais fácil escrever um analisador JSON. Em JavaScript mesmo, JSON pode ser analisado trivialmente usando a função eval().

REST
Representational State Transfer é um modelo arquitetural estruturado no conceito Web, Request-Response stateless. Enfatiza separação de interesses, camadas e cache, que são comuns em muitas arquiteturas distribuídas. Esses benefícios incluem evolução interoperabilidade, independente, interceptação, maior escalabilidade, eficiência e desempenho. REST não é sucessor do protocolo SOAP e nem podemos afirmar ser uma nova verdade, apenas uma opção a mais que pode ser combinada para obter o melhor dos mundos na questão web, interoperabilidade e aplicações corporativas e distribuídas.

1. Menos sobrecarga (não há o empacotamento da mensagem em um envelope SOAP)
2. Menos duplicação (Mensagem SOAP utilizará operações já existentes no HTTP, por exemplo: POST e GET).
3. Mais padronizado – operações HTTP são bem compreendidas.
4. Mais legível e testável (testar mensagem SOAP com apenas um navegador é difícil).
5. Não precisa usar XML (temos outras opções de texto com menos trabalho de parse).

Na verdade, apenas a diferença é como os clientes acessam o nosso serviço. Normalmente, um serviço WCF vai usar SOAP, mas se você construir um serviço REST, os clientes estarão acessando seu serviço com um estilo diferente de arquitetura (chamadas, como serialização JSON, etc.)

Método URI Template Operação RPC Equivalente
PUT users/{username} createUserAccount
GET users/{username} getUserAccount
POST users/{username} updateUserAccount
DELETE users/{username} deleteUserAccount

A partir da versão 3.5 do .Net Framework, o WCF passou a contar com a biblioteca System.ServiceModel.Web.dll que permite mapear requests http para métodos via URI templates. Para habilitar o web model aplicamos o message layer com WebHttpBinding e o dispatcher com WebHttpBehavior. Abaixo segue um exemplo da construção de um serviço WCF REST (considerando que você já tem conhecimento de criar um novo projeto WCF Services no Visual Studio).

Implementação do contrato WCF para serviços RESt no formato JSON:
WCF Rest Services Implements

Arquivo web.config para definições de binding e endpoint para o hosting do serviço:
WCF Rest Configuration

HTTP Request com verbo GET com Fiddler:
WCF Rest Get Fiddler Request

HTTP Response com o resultado no formato JSON:
WCF Rest Get Fiddler Response

HTTP Request com verbo POST com Fiddler:
WCF Rest Post Fiddler

Consumindo o serviço REST com Jquery Ajax:
WCF Rest Jquery

Para finalizar e completar, a partir da versão 4.0 do framework foi disponibilizado a feature WCF Web HTTP Service Help Page. Apenas ativando o atributo helpEnable o WCF se encarrega de gerar um página de guia e documentação dos serviços. Fácil, fácil. Até a próxima.

Web.config configurado para ativar a página de help automaticamente:
WCF Page Help

Exibindo a página de help do exemplo do post:
WCF Rest Help Page

Aplicações corporativas como serviço – SOA

Ao longo dos últimos anos as empresas tiveram de se tornar muito mais ágeis. Parcerias corporativas e grandes fusões ocorrem constantemente, acarretando em relações incorporadas e novas colaborações são estabelecidas em uma base diária. Isso tem um impacto direto sobre a indústria de TI. Se dois parceiros de negócios querem trabalhar em conjunto, divisões de sistemas e de infraestrutura precisam se adaptar e colaborar, esta é geralmente uma tarefa complicada. Os clientes exigem cada vez mais aplicações complexas com mais recursos e uma melhor integração com menor custo possível. O usuário médio tende a ser mais exigente e menos tolerante. Aplicações de hoje deve superar problemas de disponibilidade, escalabilidade e confiabilidade tornaram-se requisitos básicos. Devido à grande diversidade de tecnologias disponíveis, os sistemas são implementados usando diferentes frameworks, são implantados em vários locais em todo o mundo tornando muito difícil para eles para se comunicar diretamente uns com os outros.

SOA resolve esses obstáculos através da definição de padrões para interação entre os sistemas e tecnologias com base em políticas e contratos. Com a adoção de SOA, os cenários de integração de aplicações distribuídas que foram considerados impossíveis há alguns anos, tornaram-se trivial nos dias atuais. Houve uma considerável conscientização referente a segurança da informação, bem como a necessidade de integração com outras aplicações de forma fácil e segura. Estes desafios são relevantes em quase todos os sistemas projetados hoje. A fim de atingir esses ambiciosos objetivos, um novo estilo arquitetônico teve que ser desenvolvido. SOA foi apresentado como uma solução prática para estes desafios. SOA é um estilo arquitetônico que foi desenvolvido para lidar com os desafios impostos pela distribuídos aplicações, visa proporcionar interação flexível entre as aplicações e oferece muitas vantagens e benefícios para aqueles que desejam usá-lo.

Alguns benefícios SOA

Agilidade Trabalhando de acordo com os princípios de SOA vai permitir que seus aplicativos se adaptarem mais rapidamente a alterações ambientais e mudanças de negócios.
Produtividade Adoção de SOA em algumas organização pode ser mais trabalhoso no desenvolvimento do que outros estilos arquitetônicos, porém você pode implementar aplicações complexas usando SOA mais facilmente do que com outros estilos arquitetônicos.
Reutilizar Com a implementação de SOA, você acabará por ser capaz de reutilizar os seus serviços em todo o seu domínio em vez de reescrever os mesmos módulos de novo e de novo em cada sistema.
Redução de custo Implementação de SOA pela primeira vez terá os seus custos, mas a longo prazo, como serviços são introduzidos no sistema com mais facilidade, e mais serviços são reutilizados em vez de reescrita, você vai notar uma redução nos custos de TI.
Testabilidade Serviços são autônomos, o que favorece os testes. O teste é mais fácil quando o aplicativo é isolado do seu ambiente. Os serviços podem ser facilmente isolado de seu ambiente favorecendo um mecanismo padrão para acessá-los, tornando-os mais testáveis do que a maioria aplicações frontend.
Flexibilidade Dependências são inevitáveis​​, os serviços devem ser projetados para resolver dinamicamente dependências, permitindo a substituição dependências facilmente. O design pattern Fabric e Dependecy Injection, arquivos de configuração externo e descoberta de serviços (UDDI), são algumas abordagens que podem ajudar você minimizar as dependências do seu serviço, favorecendo a ampliação facilitada do serviço.

SOA é baseada em serviços. Um serviço é algo que expõe uma funcionalidade e pode ser consumido por outros sistemas. Um serviço faz algo, por exemplo, ele recupera os dados, informações, atualizações ou realiza uma de processos de negócios. Para acionar um serviço, uma requisição precisa ser feita para o serviço (callee) pelo seu cliente
(caller). Uma requisições contém informações sobre o funcionamento do serviço que está sendo solicitado e quaisquer dados adicionais que a operação específica precisa ter antes de executar.

Dados não é a tecnologia específica. Serviços devem trabalhar com dados que podem ser lidos e escritos usando qualquer
tecnologia. O texto “100” pode ser tanto uma cadeia de caracteres ou um número, dependendo do que a operação espera. Um documento XML que contém o primeiro nome e o sobrenome de uma pessoa também é dados, porque quase todas as tecnologias podem interpretar XML. Em contraste, um despejo de memória de um número de ponto flutuante é tecnologia específica, porque as tecnologias diferentes representam números na memória de diferentes maneiras. Alguns serviços executam imediatamente uma requisição e depois retornar uma resposta, enviando um mensagem de resposta para o cliente. A resposta contém os dados que são o resultado da operação realizada pelo serviço. Outros serviços podem receber pedidos, mas não irá responder a elas, conhecido como “fire and forget” ou operações “one-way”. Para concluir, os serviços devem expor a funcionalidade, dados entram e dados saem. Este é o núcleo da SOA, interoperabilidade e simplicidade.

Pilares do SOA

Serviços manipula dados, não objetos
Objetos dependem de uma tecnologia específica, enquanto os dados XML não. Objetos transferidos entre um serviço e seu cliente irá forçá-los tanto para usar a mesma tecnologia, quebrando seu serviço capacidade de interagir com diversos sistemas. Além disso, o uso de objetos não permite a evolução do serviço, a cada simples mudança no objeto pode impactar no sistema. Através da troca de dados, o serviço será capaz de se comunicar com outras tecnologias, inclusive com novas tecnologias desde que utilizando os mesmos padrões pelos quais o serviço opera. Trabalhando em um mundo distribuído onde as aplicações são independentes uma das outras, mudanças são freqüentes tornando um grande risco com cada mudança feita no serviço. No entanto, utilizar dados tem seu preço, é caro a conversão de objetos em dados simples (serialização e desserialização).

Serviços são autônomos
Serviços lidam com a declaração de como os clientes podem consumir a funcionalidade do sistema, deixando implementação em outros componentes.Ao separar as duas preocupações, a tecnologia que é utilizada para implementar o serviço é transparente para os seus clientes.Como os clientes só se preocupam com o endereço do serviço e as informações que eles precisam para enviar para o serviço, o serviço é capaz de mudar o seu código de implementação, estrutura, ou tecnologia, sem que o cliente saiba e seja afetado.

Serviços tem fronteiras explícitas
O serviço é responsável por suas informações. Tudo dentro dos limites do serviço só é acessível através de suas arestas. Limites do serviço são explícitos, o que significa que o serviço especifica precisamente as mensagens que ele pode receber e que as mensagens devem conter; mensagens que não estão em conformidade com as especificações será rejeitada com uma mensagem de erro. Há muitos limites entre o cliente e o serviço: rede, segurança e tecnologia. Quando um cliente solicita o serviço, o pedido passa por esses limites: o cliente tem de abrir um canal de comunicação, fornecer todas as informações de segurança, converter objetos para dados e depois transmitir os dados pela rede. Deve ser muito claro para o cliente consumidor quando uma chamada para o serviço é realizado. Qualquer problema encontrado entre as pontas faz com que o cliente receba um erro. Assim o cliente deve usar o tratamento de exceção ao chamar serviços para lidar com a conectividade possível e erros de protocolo relativos à fronteira de transição.

Serviços expõem contrato e política
O cliente tem conhecimento apenas do contrato que serviço estabelece e do local do serviço (endpoint). O contrato do serviço define o formato dos dados que o cliente tem de utilizar quando se chama um serviço, bem como a forma da resposta que o serviço responde. A política do serviço define informações adicionais sobre os dados que estão sendo enviados. Por exemplo, uma política pode afirmar que os dados precisam ser criptografados. Você pode pensar no contrato como uma forma do serviço de deixar o cliente ciente de quais dados enviar e de que forma enviar os dados. Interoperabilidade entre clientes e serviços é baseado apenas no contrato e as políticas declarada dos serviços.

Agilidade

Agilidade no atendimento é uma das características mais importantes da SOA. Serviços são dinâmicos, eles mudam suas implementação e contrato, se deslocar de um lugar para outro, e eles são duplicados em outras localizações. Serviços têm muitos clientes e você nem sempre saber quem são os clientes, você tem precauções adicionais ao fazer alterações a um serviço. Quando você faz alterações em um sistema, geralmente testes de regressão são realizados para se certificar de que nada foi quebrado. Por os serviços serem isolados do projeto, seus clientes só estão familiarizados com do contrato do serviço, geralmente você pode fazer mudanças na implementação do serviço sem afetar seus contrato e parceiros.

A localização do serviço também é algo que pode mudar ao longo do tempo. Os serviços podem ser movidos de um máquina para outra, mudando o seu endereço.
Serviços também pode ser replicado em várias máquinas para suportar consumo massivo, e ser removido a partir da diminuição da carga (escalabilidade elástica). Enquanto os clientes poderem encontrar o serviço e enviar mensagens, o sistema vai continuar a atendendo adequadamente. Para se certificar de que os clientes podem encontrar serviços, você pode usar repositórios de serviços que contêm serviços endereços, e deixar seus clientes a usar os repositórios para encontrar a localização dos serviços, ou você pode usar a descoberta de serviços (UDDI), que permite os clientes procurarem os serviços na rede.

Agilidade também pode ser alcançada por meio de sistemas avançados de integração (Middlewares SOA), que permitem processar as mensagens antes de chegar ao serviço. Isso permite que você transforme mensagens dinamicamente para coincidir com o contrato de serviço, encaminhar mensagens para um ou mais serviços, orquestrar processos de negócios, chamando vários serviços, ponte entre diferentes protocolos e muito mais.

INVEST User Story

Em metodologias ágeis, pensamos em requisitos na forma de estórias do usuário. É fácil confundir o cartão de estória com a “estória toda”. Estórias em Extreme Programming têm três componentes: Cartões (seu meio físico), a conversa (a discussão em torno deles) e Confirmação (testes que verificam eles). Existe um língua chamada Pidgin, que é uma linguagem simplificada, geralmente usada para o comércio, que permite que as pessoas que não podem se comunicar em seu idioma nativo possam trabalhar juntos. Estórias de usuário funciona assim. Não é esperado que os clientes ou usuários visualizam o sistema da mesma forma que os programadores; estórias agem como uma língua pidgin onde ambos os lados podem concordar suficiente para trabalhar em conjunto de forma eficaz.

É essencial para o projeto a concepção de boas estórias, que capturam o valor do negócio solicitado pelo Product Owner. INVEST é uma abordagem amplamente utilizada para escrever estórias. Ao criar estórias, é muito importante fazer estórias de acordo com a abordagem INVEST. O acrônimo INVEST: I (Independent) – N (Negotiable) – V (Valuable) – E (Estimable) – S (Small) – T (Testable). Esse acrônimo ajuda a lembrar de um conjunto de critérios, ou lista de verificação, para avaliar a qualidade de uma estória de usuário. Se a estória não cumprir um destes critérios, a equipe deve reformular, ou mesmo considerar uma reescrita, que se traduz no ato físico de rasgar o cartão (post-it) da velha estória e escrever um novo. Abaixo estão os resumos respectivo a cada sigla.

Independent Estórias devem ser independentes uma das outras sempre que possível, é dificilmente não será possível. Em outras palavras, as estórias podem ser trabalhadas em qualquer ordem. Por que isso é importante? Ela permite a priorização individual de cada estória e um product backlog como um todo. Quando um product backlog tem suas estórias dependentes, poderá não ser possível implementar uma estória valiosa sem implementar outras histórias muito menos valiosas, comprometendo o tamanho ou objetivo da sprint.
Negotiable A estória não é um contrato, mas um convite para uma conversa. A estória capta a essência do que é desejado. O resultado real precisa ser um resultado negociável de forma colaborativa entre o cliente e o time agile. O objetivo é atender às necessidades dos clientes, não desenvolver alguma coisa de uma estória qualquer que não seja o suficiente! Lembre-se, você sempre pode fazer a pergunta mágica para ajudar a conduzir a conversa.
Valuable Se uma estória não tem valor perceptível não deve ser feita. Esperamos que as estórias sejam priorizadas de acordo com o valor do negócio, por isso ter um valor é óbvio. Algumas pessoas dizem que cada estória deve ser valiosa para o cliente ou usuário final. Na verdade isso vai além, porque o valor do negócio abrange mais do que apenas um cliente ou valor aparente ao um usuário. Inclui valor interno que é útil para coisas que são normalmente chamadas de “não-funcionais”, valor ao produto, coerência perante ao mercado ou algo similar. É melhor pensarmos que a estória tem valor para o “usuário” na estória do usuário. Desta forma, é claro que deve ser satisfeito. Finalmente, lembre-se do “para que”, cláusula presente na estória do usuário. Ele está lá por um motivo – é o valor exato que estamos tentando entregar ao completar a estória!
Estimable Toda estória tem de ser possível estimar ou dimensionar de modo que possa ser convenientemente priorizada. Um valor elevado pode ocorrer, mas o tempo de desenvolvimento extremamente custoso não pode ser o ponto base para elevar a prioridade, só porque simplesmente o período de tempo para o seu desenvolvimento é alto. O que acontece se uma estória não pode ser estimada? Você pode dividir a estória e talvez ganhar mais clareza. Às vezes, uma estória particionada não ajuda. Se essa situação ocorrer, deve-se realizar pesquisas sobre a estória primeiro. Pausa para pesquisa e melhor entendimento! Se você não fizer isso, vai privar o produto de algo que poderia ter sido feito em algum momento adequado e oportuno.
Small Obviamente estórias são pequenos pedaços de trabalho, mas quão pequenos deveriam ser? A resposta depende da equipe e da metodologia a ser utilizada. Recomendações agilistas é iterações quinzenais que permitem estórias de usuários de até 03 a 04 dias de trabalho, no máximo! Isto inclui todo o trabalho envolvido para começar a estória e passar para um status de “Pronto”. Não seja um goldplate das estórias de usuários, você deve fazer a coisa mais simples e funcional.
Testable Toda estória precisa ser testada. Precisamos compreender que critérios de aceitação testáveis devem ser escrito imediatamente. Pensando desta forma incentiva a colaboração, aplica-se qualidade, movendo-se no processo de controle de qualidade, e permite fácil aplicação do conceito ATDD – Desenvolvimento guiado por testes de aceitação. Como o item Negotiable ​​acima, fazendo a pergunta mágica que pode ajudar a garantir a estória do usuário de forma testável também. Estórias não-funcionais também devem ser testadas. Exemplo: “O sistema deverá estar 99% do tempo no ar”, de forma chula para exemplificar, tire o cabo de energia de um dos servidores e veja se tudo continua funcionando.

Se os product owners e suas equipes trabalharem em conjunto para investir em boas estórias com um product backlog coerente e eficaz, a curva de aprendizado do trabalho em conjunto será muito mais curto. O acrônimo INVEST estimula bons hábitos que eliminam alguns dos maiores problemas de estórias do usuário, como dependências, conteúdo muito grande, dificuldade de teste e etc. Aproveite o tempo para investir em boas estórias e ver a mudança dramática de como o planejamento se tornará eficaz, assim como como produtivo o time também irá se tornar.

Product Backlog

Product Backlog, repositório de requisitos (user stories) utilizado em processos ágeis, principalmente em Scrum. É relativamente fácil encontrar conteúdo falando sobre, porém quase sempre abordando o que é e como deve ser ordenado, um pouco sobre a sua manutenção após a realização de sprints. Mas quando saímos de um modelo tradicional ou um processo do tipo Rup? Será que não precisamos entender um pouco sobre a visão e conceito do mesmo para com mentalidade ágil? Sobre isso quero falar um pouco…

Quando utilizamos um processo de desenvolvimento sequencial, começamos com uma longa fase inicial de coletas de requisitos durante a qual presumimos que o produto seja totalmente especificado. A ideia é que se pensarmos com mais tempo e calma no início, não encontraremos pontos desconhecidos na fase desenvolvimento. Gosto particularmente e traduzir isso para “Imaginar todos os fluxos, caminho feliz e alternativos com seus detalhes de forma prévia antes do contato do usuário final e o sistema, ou seja, bola de cristal”. Em processos ágeis o conceito é desenvolvimento interativo (entregas pequenas com entendimento de um contexto pequeno para aprender mais e melhor com o uso do sistema) e incremental (entregas de funcionalidades de valor adicionais uma após a outra em ciclos curtos).

Dessa forma, as descrições dos requisitos são realizadas em alto nível e refinadas à medida que o projeto avança. Essa lista de requisitos é chamada de Product Backlog e é mantida pela Product Owner, onde os itens são classificados pela prioridade por valor de negócio. Diferente de documentações, essa lista é dinâmica, podendo acrescentar, remover e reordenar os itens conforme o avanço do projeto. Existe um grande mito envolvendo os requisitos, se você listá-los por escrito os usuários vão conseguir exatamente o que querem. Não é verdade. Na melhor das hipóteses o usuário consegue o que foi anotado, que pode ser ou não algo que queiram. Palavras escritas podem enganar, parecem mais precisas do que realmente são. A falta de uma vírgula pode gerar um guerra devido a mudança de sentido. Problema de comunicação existe e no diálogo não verbal isso agrava. E o caso chamada telefone sem fio, lembra?

  • Documentos escritos podem nos fazer seguir sem questionar, transparece algo oficial e definitivo, principalmente quando uma formatação caprichada é aplicada.
  • Com documentos escritos não revisamos o significado como faríamos em conversas. Um requisito poderia dizer “Nome do exame médico radiológico com 127 caracteres”. Existe grandes chances de que o requisito era ter o nome com no máximo 127 caracteres, mas por se tratar de um domínio específico com requisitos incomuns, como nomes compostos com letras A,C,G e T, poderia achar estranho mas não impossível de aceitar.
  • Documentos escritos diminuem a responsabilidade compartilhada pela equipe. Pois criam uma transferência sequencial que isenta a equipe de uma unidade de objetivos. Um pessoa define o produto e outro grupo constrói. A comunicação bilateral é desencorajada quando alguém escreve em detalhes que algo deve ser feito. Discussões tem o efeito oposto, traz um maior comprometimento da equipe e retiradas de dúvidas e maior entendimento entre os diálogos. Uma vez encontrei um vídeo Falha de Comunicação engraçado que ilustra o problemas na comunicação verbal, quanto mais no documentos escrito cuja a interpretação é pessoal.

Não descarte toda a documentação
Desvantagens da comunicação escrita não quer dizer que devemos abandonar os documentos de requisitos por escrito, mas utilizá-los quando apropriados e com peso diferente. O manifesto ágil tem um dos valores que é “Software funcionando ao invés de documentação abrangente”, mas muitos interpretam mal ao ponto de entender que não é preciso ter qualquer documentação. Documentos de requisitos (documentos de caso de uso) continua sendo útil para muitos projetos, principalmente aqueles que estão sedimentados em cima de normas, leis e constituições, onde os requisitos estão bem claros e na sua maioria imutáveis. Devemos ter a consciência de que documentos de requisitos são apenas um tipo de documento que pode existir em um projeto. Documentos técnicos são sempre importante (diagrama de classe, componente, sequência, deployment…).

Requisitos Emergentes
Esses requisitos que não conseguimos identificar antecipadamente são chamados de emergentes, normalmente são aqueles casos, “Ver isso me fez lembrar daquilo…” ou “Isso me deu uma idéia…” ou ainda “Puxa, nunca pensamos nisso…”. Na verdade sempre terá coisas que nunca pensamos até vermos o software. Uma das razões que metodologias ágeis dá tanta ênfase a conclusão de um código funcional ao fim de cada sprint, assim a descoberta dos emergentes é o mais cedo possível. Reconhecendo que alguns requisitos emergirão à medida que construimos, será mais fácil aceitar a ideia de que não precisamos de um documento de requisitos perfeito antecipado. Passamos a considerar que requisitos emergentes não é necessariamente uma falha de planejamento, mas em muitos casos, aperfeiçoamento com lições aprendidas.

Refinamento Progressivo

  • As coisas mudarão: No decorrer do projeto as prioridades mudarão. Outras necessidades serão descobertas e terão que ser priorizadas apropriadamente. Se reconhecermos que a mudança é inevitável, as vantagens da estruturação do product backlog como um iceberg ficarão mais evidentes. Os requisitos com mais probabilidade de mudar serão construídos mais à frente; para acomodarem a maior probabilidade de mudança, esses requisitos são descritos somente em um nível geral.
  • Não há necessidade: Os faróis de um carro não ilumina tudo que existe no horizonte porque não precisa disso. Ele ilumina o suficiente para uma para que uma ação seja tomada a tempo para que a viagem seja segura. O Product Backlog em forma de um iceberg funciona de forma semelhante. É fornecido uma visibilidade suficiente dos próximos itens para que as equipes enxerguem o bastante do futuro a ponto de evitar a maioria dos problemas.
  • O tempo é escasso: Quase todos projetos tem restrições de tempo, portanto tratar todos os requisitos como iguais é desperdício. Como tempo é um recurso muito limitado, precisamos cuidar bem dele. Quando requisitos futuros tiver de ser conhecido melhor, porque passou para o topo do iceberg do Product Backlog ou porque passou achamos que ele influenciará a implementação de outro requisito, então poderemos escrevê-lo com mais detalhe.

Não esqueça de conversar
Embora o Product Backlog de um produto seja escrito em algum local, ele não substitui perfeitamente o modelo de caso de uso ou documentos de requisitos do projeto tradicional. Tão importante quanto o que é escrito no Product Backlog são as conversas em torno dele. Essas conversas ocorrem quando a equipe e o Product Owner trabalham juntos para propor itens do backlog inicial. E ocorrem durante a sprint à medida que a equipe e o Product Owner conhecem melhor o requisito.

Lembre-se que o Scrum requer que você planeje considerando mudança. Um tempo deve ser reservado para a arrumação do Product Backlog. Isso pode não ser necessário em todas as sprints, mas você terá que fazê-lo com frequência suficiente para manter os itens pequenos, de tamanhos da sprint no topo do Product Backlog, adiando o investimento em itens que serão manipulados no futuro.

Considerações na migração do tradicional para o Scrum

Olá! Gostaria que existisse uma manual do tipo receita de bolo para migrar um processo corporativo, modelo de trabalho que garantisse o sucesso e elucidasse os problemas com o guia de resolução dos mesmos. Confesso ser muito desafiador mudança cultural de um modelo de trabalho papel de pão (teoria do caos) ou tradicional burocrático como RUP em equipes de médio-grande porte. Guando li a famosa frase de Peter Senge, “As pessoas não resistem a mudanças, resistem a ser mudadas”, concordei imediatamente, por experiência e por também acreditar que as visões e opiniões mudam com experiências diferentes e amadurecimento. É comum uma pessoa não compreender certas mudanças, pode ser o caso dela não estar preparada para aquela mudança naquele seu momento. Temos pessoas que criam grandes problemas por coisas pequenas como a troca física de mesa de trabalho, quanto mais uma evolução de processo e cultural. Por isso listo abaixo algumas dicas de fontes ricas sobre considerações para uma transição de um modelo qualquer para Scrum-Agile.

O Scrum é muito diferente
Além de mudanças geradas pela adoção do Scrum abrangerem tudo o que os membros da equipe de desenvolvimento fazem, muitas delas vão contran grande parte do que aprenderam na sua formação. Muitos testadores, por exemplo, aprenderam que seu trabalho é testar a conformidade a uma especificação. Os desenvolvedores aprenderam que um problema deve ser analisado detalhadamente e uma solução e uma solução perfeita deve ser projetada antes que a codificação comece.

Em um projeto de Scrum, testadores e programadores aprendem que teste também deve abordar a conformidade às necessidades do usuário. Os programadores aprendem que nem sempre é necessário um projeto ser considerado em sua totalidade antes que a codificação comece, isso de fato pode ser muito difícil para os programadores. Já que a transição para o Scrum envolve pedir que as pessoas trabalhem de maneiras que não lhes são familiares e ajam de forma contrária ao treinamento e experiência, com frequência elas ficam hesitantes, quando não resistem à mudança.

Se considerarmos o caso do programador, o mesmo tem que trabalhar com várias tarefas ao mesmo tempo para concluir algo no final de cada sprint. Pode ter que criar testes automatizados para executar em cada novo trecho de código. Pode até mesmo ter que alternar curtos períodos de testes e desenvolvimento de código no chamado desenvolvimento baseado em teste. E pode ter que fazer isso sem seus fones de ouvido na programação em pares. Essas são mudanças estruturais, não são algo relegado a algumas horas por dia ou semanas, como poderiam ser as inspeções de código. Esse tipo de mudança é difícil porque afeta tudo no dia de trabalho de um desenvolvedor. A resistência será maior porque o impacto é maior.

Scrum é abrangente
A adoção de Scrum também é abrangente de outro maneira. Ser ágil terá implicações para a empresa que irão bem além do departamento de desenvolvimento de software. A introdução da revisão de prontidão operacional provavelmente não afetaria os departamentos de finanças, vendas ou outros. Mas todos eles podem ser afetados pelo Scrum. O departamento financeiro terá que reconciliar as políticas de capitalização ou gastos da empresa com a maneira com os projetos Scrum são executados. As equipes de vendas vão querer considerar a alteração de como comunicam compromentimentos de data e escopo e podem mudar como estruturam os contratos. Como mais grupos são afetados por uma migração para o Scrum, há mais chance de haver resistência e sem dúvida mais probabilidade de mal-entendidos. Essas dificuldades contribuem para tornar a transição para o Scrum mais difícil do que outras mudanças.

Mudança precisa ser de baixo para cima e de cima para baixo
A mudança organizacional bem sucedida não pode ser totalmente de cima para baixo ou de baixo para cima. Em uma mudança de cima para baixo, nenhum CEO de estilo autoritário ou um líder influente compartilha a visão do futuro, consegue desenvolver a visão correta, comunicá-la para uma grande quantidade de pessoas, eliminar todos os obstáculos principais, vencer etapas de curto prazo, liderar e gerenciar dezenas de projetos de mudanças e fixar novas abordagens profundamente na cultura da empresa.

Por outro lado, em uma mudança de baixo para cima, uma equipe decide que mudanças são necessárias e começam a fazê-la acontecer. Algumas equipes assumem a mudança de baixo para cima como uma atitude de “pedir desculpas depois”. Outras se gabam de estar quebrando regras. E ainda outras tentam não ser percebidas enquanto for possível. A maioria das mudanças bem-sucedidas, principalmente a transição para um processo ágil como o Scrum, deve incluir elementos de mudança tanto de cima para baixo como de baixo para cima. Empresas que fazem a transição para o Scrum sem o apoio dos níveis mais altos enfrentarão uma resistência que não poderá ser superada a partir dos níveis inferiores. O suporte de cima para baixo será necessário para remover vários tipos de impedimentos e obstáculos, principalmente com o relacionamento externo e demais setores corporativos. Da mesma forma, sem o engajamento de baixo para cima um muro no meio operacional será instalado. A participação de baixo para cima será necessária porque serão os próprios integrantes das equipes que resolverão o problema de descobrir como o Scrum funcionará melhor dentro da empresa.

Quality Assurance com Scrum

O Scrum é um framework ágil de desenvolvimento de produtos baseado no conceito interativo e incremental, que entrega funcionalidades que agregam valor aos negócios em ciclos pequenos de duas a quatro semanas (sprints). Conceitualmente um time de Scrum é composto por 03 papéis: Product Owner, Scrum Master e Developers, cujo os mesmo devem ser multifuncionais e serem totalmente auto-organizados. De ante mão gostaria de frisar que Scrum não é uma metodologia, a diferença é que um framework é um construto fundamental de conceitos, valores e práticas, ou seja orientações e não regras. Uma analogia seria uma bússola e um GPS, onde a bússola lhe orienta ir para um sentido e o GPS lhe “obriga” um caminho em detalhes. Dessa forma, sem perder os 03 pilares do Scrum (inspeção, adaptação e transparência), podemos ajustar os detalhes a nossa realidade. O Scrum Guide diz isso, muitos não se atentam, principalmente se não existe uma boa bagagem em desenvolvimento de software.

Não devemos ignorar a equipe de garantia de qualidade, por mais que o time deve possuir conhecimentos diversos para realizar um objetivo. Equipe de QA deve ir além de escrever casos de teste e relatar defeitos de software, até porque teste deve iniciar na fase de desenvolvimento. Diferentemente de uma metodologia waterfall, em que há forte dependência entre as atividades, o Scrum considera que as atividades de desenvolvimento devem ser realizadas conforme a demanda com paralelismo. Essa quebra de paradigma levanta uma questão comum, “Como engajar os analistas de testes durante um sprint, uma vez que nada ainda foi construído?”. Nesse artigo quero compartilhar minha visão referente ao assunto, baseado na experiência, opinião da colega Priyanka, analista de qualidade e livros de referência no assunto.

Muito além de elaborar casos de teste
Em projetos waterfall o QA é envolvido apenas no fim do projeto, quando toda a codificação foi finalizada. Nesses projetos, geralmente o documento de requisitos e o código produzido são entregues ao QA, o qual é esperado que escreva e execute os casos de teste que verificarão e atestarão requisitos documentados. Em um time de Scrum, os analistas de QA participam de cerimônias e cumprem uma série de responsabilidades em conjunto com outros membros do time. São envolvidos desde o primeiro instante de um projeto e trabalham junto aos desenvolvedores e analistas de negócio. No Scrum, o QA não é um time à parte, que apenas testa a aplicação sendo construída. Ao contrário, é um time multifuncional em que os desenvolvedores, analistas de negócio e analistas de QA trabalham todos juntos. Além de montar os casos de teste, os analistas de QA também podem ajudar o Product Owner (PO) a escrever os casos de teste de aceite. Os analistas de QA também podem ajudar a manter o time sempre progredindo e engajado. Por fim, os QAs também podem interagir com o PO e analistas fazendo questionamentos e criticando as premissas do projeto, para ajudar na elicitação dos requisitos de negócio.

Participação na estimativa das estórias
Normalmente, os analistas de QA são bons em criar cenários de caso de teste baseado nos requisitos do usuário. Além disso, são excelentes em identificar e documentar cenários de caso de teste negativos e complexos. Na verdade, são geralmente melhores nesta última atividade que os desenvolvedores, que tendem a enfatizar mais o “caminho feliz” da história do usuário. Incluir os testadores durante o planejamento de entregas e iterações, no momento em que as histórias de usuário estão sendo estimadas, pode ajudar o time a pensar além do caminho feliz. Isso ajuda a elaboração de uma estimativa mais real, uma vez que ambos os caminhos feliz e infeliz são considerados.

Ajudar a manter visíveis o objetivo e as metas
Uma vez que a equipe evolui o trabalho por meio de atividades de teste e estabilização, os analistas de QA devem tomar para si a responsabilidade de planejar, organizar e envolver o time inteiro nos testes, além de manter todos motivados da mesma forma que o Scrum Master o faz. Considerando que poucos desenvolvedores apreciam fazer testes, os QAs, juntamente com o Scrum Master, devem fazer com que o objetivo e as metas de testes estejam visíveis a todos, além de de ajudar a manter a equipe motivada. Algumas vezes, essa postura facilita a criatividade quando os cenários de teste exigem ajuda dos desenvolvedores ou de outros membros do time.

Ser parceiro dos clientes e desenvolvedores
Uma das principais responsabilidades do QA é registrar o resultado dos testes e dar ciência deles ao Product Owner. Os QAs trabalham juntamente com o Product Owner para ajudá-los a desenvolver critérios de aceite detalhados para as estórias. Baseados no conhecimento aprendido pelo time a cada sprint, os QAs conseguem também ajudar o Product Owner a modificar ou melhorar as estórias de usuários já existentes, com o objetivo de tornar os requisitos mais próximos da realidade. Quanto maior o entrosamento, maior será a a compreensão dos requisitos, o aumento da clareza resultante desse trabalho em conjunto reduzirá as questões e dúvidas que os desenvolvedores frequentemente encontram durante a fase de codificação. E produzirá maior eficiência e economia de tempo, tanto para os desenvolvedores como para os testadores. Essa integração torna a equipe mais equilibrada e ajuda a dividir com todos a responsabilidade de concluir o trabalho, além de ajudar a obter a velocidade necessária para retornar os testes o quanto antes melhorando a qualidade do produto.

Fornecer feedback rápido
O ciclo desenvolvimento-testes-correções que as equipes waterfall repetem acabam resultando em muito trabalho adicional acarretando em desperdício de tempo. No Scrum esse ciclo é muito mais simples, uma vez que os QAs e os desenvolvedores trabalham juntos durante todo o processo. Os desenvolvedores podem sempre consultar os QAs a respeito do critério de aceite ou do comportamento esperado de alguma funcionalidade, a partir da perspectiva do usuário. Isso acontece enquanto estão desenvolvendo, o que resulta em redução dos ciclos de testes e ajustes do produto. Estudos do Standish Group indica que problemas encontrados mais cedos tornam o projeto 70% mais barato e com certeza maior satisfação do cliente.

Automatizar testes de regressão
Automação é o melhor amigo do analista de testes, pois possibilita maior capacidade de repetição, consistência e melhor cobertura dos testes de cada funcionalidade do software. De certa forma, isso é verdadeiro em um projeto Scrum com ciclos de sprint, pois o QA geralmente tem pouco tempo para testar a aplicação. Durante cada sprint, o QA deve desempenhar os testes completos dos novos recursos sendo incluídos, assim como deve desempenhar testes de regressão completos para todas as funcionalidades já implementadas. Testes automatizados retornam rapidamente resultados, quando os times implementam o processo de Integração Contínua. Sempre que é necessário construir uma nova versão do produto, os testes automatizados podem ser executados, retornando os resultados imediatamente, tanto para indicar se os novos recursos estão funcionando corretamente, como para dizer se houve problemas em recursos que estavam funcionando em versões anteriores.

Participar na preparação para lançamentos e demonstrações ao final de cada sprint, a equipe deve realizar uma reunião de revisão (Sprint Review), em que as estórias finalizadas durante o sprint devem ser apresentadas ao Product Owner e às demais partes interessadas. Essa reunião fornece uma dose saudável de prestação de contas ao time. E serve de motivação a todos para que seja finalizado o máximo possível de histórias do usuário. Os desenvolvedores devem se ocupar com o desenvolvimento das estórias que lhes foram designadas e com a correção dos defeitos. Enquanto isso, o QA deve escrever os casos de testes, esclarecer as dúvidas dos Product Owners e automatizar os testes das histórias de sprint anteriores.

Em ciclos pequenos de sprint significa que os desenvolvedores têm pouco tempo para explorar completamente as funcionalidades por si próprios. Como resultado, os desenvolvedores frequentemente consultam o QA para entender melhor as estórias do usuário, uma vez que ele detém o conhecimento completo das funcionalidades e conhece todos os requisitos e critérios de aceite. Por fim, pode ser uma boa prática o QA realizar a demonstração do produto na reunião de Sprint Review e expor perguntas vindas do negócio.

Reforçar a definição de pronto
Ter uma clara definição do “Pronto” é muito importante para o time de Scrum. Uma definição de pronto é uma lista de critérios de finalização definidos pelo time, ou seja, tudo que deve estar finalizado para considerar que a estória foi concluída. Essa lista geralmente inclui itens como escrever o código, realizar testes funcionais e de regressão, e obter a aprovação do Product Owner. Um exemplo bem simples de definição de pronto poderia conter:

1. Código finalizado;
2. Testes unitários concluídos;
3. Testes funcionais e de interface de usuário finalizados;
4. Aprovação do Product Owner.

Um time de Scrum eficiente irá sempre revisar a definição do pronto antes de iniciar nova estória, para ter certeza que todos tenham o conhecimento do que deve ser feito. Como não existe um líder de testes, ou mesmo uma equipe específica para testes no Scrum, construir um plano de testes ou seguir estratégias de testes específicas em um time de Scrum pode ser um problema. Segundo a filosofia do Scrum, deve ser preparada somente a documentação suficiente para apoiar as necessidades imediatas da equipe. Assim, o QA irá preparar apenas a documentação de alto nível suficiente para as estratégias de testes e para os planos de orientação da equipe. Por não existir líderes de QA no Scrum, é comum que o analista de QA decida as estratégias de teste.

Convergência das funções de QA e analista de negócio
Nos times de Scrum é comum ver as responsabilidades do QA e daqueles que fazem a análise de negócio começarem a convergir. O analista de negócio é comumente responsável por criar e manter o sprint e os backlogs do produto, analisar as estórias segundo a perspectiva do negócio, e definir a prioridade das solicitações do Product Owner nos backlogs. O QA, por sua vez, fica responsável por definir e refinar os critérios de aceite para cada história de usuário, por testar as funcionalidades finalizadas em cada sprint a partir da perspectiva do usuário, e por se certificar que todas as funcionalidades já existentes não deixaram de funcionar. Dessa forma, o QA e o analista de negócio compartilham várias responsabilidades, habilidades desejadas e objetivos gerais. Considerando que tanto testadores como analistas acabam definindo os requisitos, analisando as estórias, definindo e clarificando os critérios de aceite, construindo os casos de teste de aceite, e trabalhando próximo aos clientes, pode-se notar claramente que as duas funções estão convergindo.

Conclusões
Enquanto os QAs escrevem testes e relatam defeitos de software, também assumem diversas outras funções e responsabilidades na equipe. São uma parte importante do time e estão envolvidos diretamente no projeto desde o primeiro instante. QA pode assumir várias funções e responsabilidades, tais como analista de QA e representante do Product Owner. Também ajudar desenvolvedores a escrever casos de testes unitários, atuando como a consciência de qualidade da equipe, e mantendo o registro dos problemas e defeitos de software.

Planning Poker

Hoje quero falar de um assuntos bastante batido, mas que continuamente tem novos profissionais a procura de um entendimento claro e mais objetivo de como estimar desenvolvimento de software. Temos diversas formas de estimar, elas podem ser baseadas em tamanho, esforço, tempo e custo, onde cada técnica requer um certo conteúdo da concepção e análise, algumas técnicas são: análise de ponto por função, análise de pontos de casos de uso, Cocomo II entre outros, muitas delas estão condicionados a metodologias específicas, como RUP. A técnica abordada nesse post é denominada Planning Poker, utilizada em métodos empíricos e ágeis.

Conceito:
Seu objetivo é tão simples que muito encontram dificuldade no entendimento. A idéia é formar uma estimativa consensual no grupo de desenvolvedores, pontuar o esforço entre as estórias, técnica denominada Story Points. Primeiro passo é ter o conhecimento do esforço entre as tarefas, por exemplo: a tarefa A é bem mais simples que a B, a tarefa C é 2x mais complexa que a B. Posteriormente é realizado a soma dos pontos das tarefas, a partir daí temos que acompanhar o histórico de cada profissional para obtermos o valor médio de produtividade de pontos por estória em um determinado período, por exemplo (semana-quinzena), é empírico, conhecimento na base histórica de produtividade. Quando trabalhamos com Scrum utilizamos Planning Poker para pontuar estórias do Product Backlog (Story Points), porém no Sprint Backlog ele é utilizado para pontuar as tarefas em horas.

Como fazer:
Cada membro da equipe recebe um baralho de 13 cartas (sequência de fibonacci) conforme a imagem abaixo. Sempre que uma estória deve ser estimada, cada membro escolhe uma carta que representa a sua estimativa de tempo (em pontos por estória) e coloca-a virada para baixo sobre a mesa. Quando todos os membros da equipe tiverem feito sua estimativa, as cartas são reveladas simultaneamente. Dessa forma, cada membro da equipe é forçado a pensar por si próprio ao invés de basear-se na estimativa de outra pessoa.

PlanningPoker

Se houver uma grande divergência entre duas estimativas, a equipe discute as diferenças e tenta chegar a uma visão comum do trabalho envolvido na estória. Eles podem fazer algum tipo de decomposição de tarefas. Depois disso, a equipe faz novamente a estimativa. Esse processo é repetido até que as estimativas de tempo cheguem a uma convergência, isto é, todas as estimativas sejam aproximadamente a mesma para cada estória. É importante lembrar aos membros da equipe que eles devem estimar a quantidade total de esforço envolvido na estória.

Note que a seqüência de números não é linear. For exemplo, não há nada entre 40 e 100. Por quê? Assim evita-se a falsa sensação de precisão para grandes estimativas de tempo. Se uma estória é estimada em aproximadamente 20 postos por estória, não é relevante se ela deve ser 20 ou 18 ou 21. Todos sabemos que é uma estória grande e que é difícil estimar. Portanto, 20 é o nosso palpite aproximado. Quer estimativas mais detalhadas? Então, quebre a estória em estórias menores e estime-as! Você não pode trapacear combinando um 5 e um 2 para fazer um 7. Você deve escolher 5 ou 8. Não há um 7 nas cartas.

Algumas cartas:
• 0 = Esta estória já está feita ou é tão pequena que leva somente alguns minutos de trabalho;
• 1/2 = Particularmente considero tarefas extremamente pequenas, como ajuste de css para formatar vermelho para saldo negativo e azul para saldo positivo, algo que não ultrapasse 1h;
• 100 = Estória com esse tamanho significa algo muito grande que com certeza é possível decompor em estória menor com vários entregáveis.
• ? = Eu não tenho idéia ou não entendi a estória;
• Xícara de café = Estou cansado demais para pensar, façamos uma pausa;

Ponto muito importante para uma boa eficácia é ter estórias bem elaboradas com o entendimento claro do “Pronto”. Gosto de classificar como a Condição de Satisfação da estória. Se os desenvolvedores não se conscientizarem da condição final que classifica aquela estória como definitivamente pronta, a estimativa terá grandes chances de furar. Para os recém chegados ao mundo Agile, podemos fazer uma analogia que estórias são requisitos com o caminho feliz dos casos de uso. O livro Succeeding with Agile: Software Development Using Scrum do Mike Cohn é uma excelente referência no assunto. Espero ter conseguido dar um razoável overview sobre o assunto. Pretendo fazer muitos outros posts com abordagem Agile. That’s all folks!

Associação Bidirecional no Diagrama de Classe

Ultimamente tenho escutado de um colega de trabalho a frase “O óbvio tem que ser dito”, quando ele descobre essas frases ele repeti até cansar. Pensando nessa frase que tanto escuto por esses dias, pensei em falar de uma tipo de associação de classes da UML. Esse tipo associação que me refiro é a Bidirecional, que na verdade é um par de propriedades inversamente vinculadas. Onde por exemplo a classe Carro tem a propriedade Proprietario:Pessoa[1] e a classe Pessoa tem uma propriedade Carros:Carro[*]. Notem que propriedade Carros está de fato no plural para expressar de forma explícita a multiplicidade, uma convenção comum, mas não normativa. O vínculo inverso entre elas significa que, se você seguir duas propriedades, deverá retornar a um conjunto que contém seu ponto inicial – ou de partida. Por exemplo, se eu começar com um Toyota Corolla particular, encontrar seu proprietário e depois ver os carros de seu proprietário, esse conjunto deverá conter o mesmo Toyota Corolla a partir do que comecei.

Como uma alternativa à denominação de uma associação por meio de ma propriedade, muitas pessoas, particularmente se tiverem experiência em modelagem de dados, gostam de rotular uma associação utilizando um verbo para que o relacionamento poos ser usado em uma frase. Isso é valido e você pode adicionar uma seta na associação para evitar ambiguidade. A maioria dos modeladores de objeto prefere utilizar um nome de uma propriedade, pois isso corresponde melhor às responsabilidades e operações. Algumas pessoas nomeiam cada associação de uma certa forma, eu prefiro nomear uma associação somente quando isso melhorar o entendimento. Existem casos que alguns modeladores nomeiam algumas associações com “Tem” Has… ou “Está relacionado a” IsLinkedAs. Abaixo ilustro uma implementação interessante do exemplo do Carro com Proprietário que citei acima.

Classe Carro:

public class Carro {

private Pessoa proprietario;

public Pessoa Proprietario {
   get { return proprietario; }
   set { 
         if (proprietario != null) {
            proprietario.GetCarros().Remove(this);
         }

         proprietario = value;

         if (proprietario != null) {
            proprietario.GetCarros().Add(this);
         }

    } 

}

Classe Pessoa (Proprietário).

public class Pessoa {

   private IList carros = new ArrayList();

   public IList Carros {
      get { return ArrayList.ReadOnly(carros); }
   }

   public void AddCarro(Carro carro) {
      carro.Proprietario = this;
   }

   internal IList GetCarros() {
      // Só pode ser utilizado por Carro.Proprietario.
      return carros;
   }

}

Diagrama de classe ilustrativo sem visão de navegabilidade:

Diagrama de classe ilustrativo com visão de navegabilidade, o que prefiro veemente:

Fiz essa implementação para que notem a importância de compreendermos de fato o vínculo entre as classes e sua navegabilidade. Relacionamento de classes na modelagem orientada a objeto é muito mais que apenas reflexo de um banco de dados relacional. Uma modelagem e desenvolvimento em alto nível de abstração começa quando paramos de pensar em relacional e entendemos o ciclo de vida das entidades, seus relacionamentos, navegabilidade, responsabilidades, identidade e etc. Até +

Destilação

Destilação é uma abordagem que nos direciona em nos concentrar em no problema principal e evitar de nos afundar em um mar de problemas e questões secundárias. Uma arquitetura em camadas separa os conceitos do domínio da lógica técnica que faz um sistema computacional funcionar (log, persistência, implementações de serviços, middlewares, componentes utilitários e etc). Em um sistema grande, até mesmo um domínio isolado pode ser um problema incontrolável e complexo. Destilação é o processo de separar componentesd de uma mistura para extrair a essência em uma forma que a torne mais valiosa e útil. O modelo é uma destilação do conhecimento. A cada refatoração em direção a uma visão mais profunda, abstraímos alguns aspectos cruciais do conhecimento do domínio e propriedades.

Assim como em muitas destilações químicas, os produtos derivados separados tornam-se mais valiosos através do processo de destilação, como Subdomínios Genéricos e Mecanismos Coerentes, que abordaremos em outros posts. Mas o esforço é motivado pelo desejo de se extrair aquela parte particularmente valiosa, aquela que distingue nosso software e faz valer a pena desenvolvê-lo: o Domínio Principal. A destilação estratégica de um modelo de domínio realiza todas as seguintes tarefas:

1. Ajuda todos os membros da equipe a entender o design geral do sistema e como suas peças se encaixam

2. Facilita a comunicação identificando um modelo principal de dimensão controlável para entrar na linguagem onipresente

3. Orienta a refatoração

4. Concentra o trabalho em áreas do modelo que possuem maior valor

5. Orienta a terceirização, o uso de componentes adquiridos diretamente no mercado e descisões sobre atribuições

É bastante interessante criar um documento separado para descrever e explicar o domínio principal. Ele pode ser tão simples quanto uma lista de objetos conceituais mais essenciais. Pode ser um conjunto de diagramas concentrados nesses objetos, ilustrando suas relações mais fundamentais, percorrendo as interações fundamentais em nível abstrato ou através de exemplos. Particularmente prefiro os diagramas de classe e sequência da UML.

Um modelo profundo geralmente vem com um design flexível correspondente. Quando um design flexível atinge a maturidade, ele fornece um conjunto de elementos facilmente compreensível que pode ser combinado e sem ambiguidades para realizar tarefas complexas ou expressar informações complexas. O valor da destilação merece essa menção especial porque ele permite ver o que está fazendo, indo à essência sem se deixar distrair por detalhes irrelevantes. Um apanhado de boas práticas e alto nível em um modelo é consistido de: Mecanismos Coesos oferendo acesso através de uma Interface Reveladora de Intenções, com Afirmações e Funções Isentas de Efeitos Colaterais conceitualmente coerentes. Nos próximos posts abordarei cada uma dessas técnicas. That’s All Folks.

Integração Contínua

Quando várias pessoas estão trabalhando no mesmo contexto delimitado, há uma forte tendência de o modelo se fragmentar. Quando maior a equipe, maior o problema; até mesmo com 3 ou 4 pessoas já são suficientes para encontrar sérios problemas. Por outro lado, dividir o sistema em contextos cada vez menores (alta granularidade excessiva),acaba causando a perda de um nível valioso de integração e coerência.

Às vezes os desenvolvedores não entendem completamente a intenção de algum objeto e o mudam de forma a torná-lo inutilizável em seu propósito original. Às vezes eles não percebem que os conceitos com que estão trabalhando já estão embutidos em outra parte do sistema e duplicam equivocadamente. É muito difícil manter o nível ideal de comunicação necessário para desenvolver um sistema unificado.

Originado no XP (Extreme Programming), Integração Contínua significa que todo trabalho dentro do contexto está sendo mesclado com frequência suficiente para torná-lo mais consistente de forma que quando ocorrem problemas, estes são rapidamente identificados e corrigidos. Integração Contínua no desenvolvimento com DDD opera em dois níveis: Integração do conceito do modelo e integração da implementação (código).

A equipe deve cultivar o entendimento compartilhado do modelo que está em constante mudança. Muitas práticas ajudam, mas a mais fundamental é insistir em usar constantemente a linguagem onipresente. Enquanto isso, os artefatos da implementação estão sendo integrados por um processo de merge/construção/teste unitário que expõe prematuramente os problemas do modelo. São usados muitos processos de integração, mas os mais eficazes possuem as seguintes características em comum:

– Uma técnica de merge/construção reproduzível e detalhada passo a passo;
– Sequências de testes automatizados;
– Regras que definem um limite superior rozavelemente pequeno para o tempo de vida de mudanças não integradas;
– Exercício constante da linguagem onipresente em discussões sobre o modelo da aplicação.

A maioria dos projetos ágeis tem merge de código quase que diários. A frequência pode ser ajustada de acordo com o ritmo das alterações, desde que qualquer alteração não integrada seja mesclada antes que outros membros da equipe realizem uma quantidade significativa de trabalhos incompatíveis. Em DDD a integração de conceitos suaviza o caminho para a integração da implementação, enquanto a integração comprova a validade e a consistência do modelo, além de expor rapidamente os problemas.

Institua um processo para mesclar frequentemente todos os códigos e outros artefatos de implementações, como testes automatizados que indiquem rapidamente a fragmentação. Exercite a linguagem onipresente para forçar o compartilhamento da visão do modelo à medida que os conceitos evoluem nas cabeças das diferentes pessoas envolvidas. Por fim, não torne o trabalho maior do que ele tem que ser. A integração contínua é essencial somente dentro de um contexto delimitado que seja maior que uma tarefa realizada por duas pessoas. Ela mantém a integridade desse modelo.