Vamos precisar reescrever essa aplicação do zero.

Quem nunca disse ou ouviu isso? Vamos entender os motivos por trás dessa icônica frase.

Vamos precisar reescrever essa aplicação do zero! É a frase de rendição, é sinal que as coisas foram para o caminho errado. Dias, meses, anos de desenvolvimento que serão jogados fora por falta de um bom planejamento.

Vamos precisar reescrever essa aplicação do zero.

Quando chegamos nessa situação geralmente estamos diante de alguns dos cenários a seguir:

  • A tecnologia da aplicação é antiga demais e os novos recursos demandam mais tecnologia.
  • A arquitetura da aplicação é uma engenhoca complexa e sem sentido.
  • Devido a diversas implementações e manutenções do passado feitas de forma irresponsável ou sem padrão a aplicação se tornou a famosa “colcha de retalhos”, qualquer tipo de mudança é sofrível e demorada.
  • A cada mudança surgem diversos bugs em todas as partes da aplicação, pois existe muito acoplamento entre suas divisões, “tudo está acoplado com tudo”.
  • O time que trabalha na aplicação atualmente não concorda com a forma com que foi escrita e não está satisfeito em trabalhar nela.

Algumas situações muitas vezes não possuem uma escapatória, por exemplo o envelhecimento natural da aplicação. É muito caro manter uma aplicação sempre alinhada com a última versão da tecnologia, logo, algumas vezes prefere-se optar por saltos (atualizar a cada X tempo) ou simplesmente reescreve-la depois de alguns anos.

O cenário de envelhecimento da aplicação é um dos menores, geralmente a aplicação morre muito antes da hora. Eu trabalhei em uma empresa onde assisti a mesma aplicação ser reescrita 1 vez ao ano durante 3 anos. O que ocorre de tão errado assim?

Existem muitos motivos para tudo dar errado:

  • Equipe tecnicamente despreparada.
  • Falta de um líder técnico ou arquiteto que conduza o time e evite a deformação da aplicação.
  • Escopo mal planejado, falta de entendimento da entrega.
  • Prazo mal calculado.
  • Falta de visão. Típico caso do sisteminha de cadastro que virou um “ERP”.
  • Gestor de equipe que pula etapas e/ou não valoriza (não conhece) boas práticas, impondo uma metodologia que funciona apenas na teoria dele.

Motivos para dar errado são muitos, fazer software da forma correta é infinitamente mais complexo que simplesmente entregar software. É necessário ter uma boa equipe, um bom líder e um bom gestor.

Software é um bem durável assim como uma TV, Geladeira ou Carro, paga-se muito caro para desenvolve-lo e muito caro para mante-lo. A diferença é que o software precisa ser flexível e adaptar-se às constantes mudanças de escopo, logo não pode possuir uma engenharia fechada como uma TV e geralmente é ai onde mora a maioria dos problemas.

Para garantir um bom funcionamento da aplicação de forma que ela se adapte às diversas mudanças de escopo com o mínimo de esforço necessário e sem gerar outros problemas secundários, é preciso projetar a aplicação, não basta simplesmente escrever a aplicação e entregar.

Alguns pontos importantes devem sempre ser abordados:

Processo

Processo de desenvolvimento de software é um tema extenso demais, portanto deixarei apenas alguns pontos em destaque que devem ser levados bastante em consideração.

Processo de desenvolvimento de software é um processo diferente de outros, porém infelizmente ainda existem gestores que imaginam que desenvolver uma aplicação é o mesmo que construir um prédio, um navio ou um avião.

Durante a construção de um prédio com a obra em estágio avançado é praticamente impossível aplicar mudanças que mudam o aspecto do projeto, existe uma engenharia fechada e projetada para ser daquela forma, qualquer mudança poderia impactar em ter que iniciar novamente do zero.

Uma aplicação bem projetada deve ser flexível e estar aberta para mudanças de escopo com menor esforço necessário, portanto não devemos nos apegar em simplesmente entregar o que foi inicialmente levantado.

Uma das formas mais práticas de atender a necessidade do cliente é a entrega contínua, releases parciais para acompanhamento e feedback do cliente, é muito mais fácil ajustar uma mudança de escopo com a aplicação 30% desenvolvida do que se estivesse 100%.

Focar em definir bem os requisitos das entregas mais próximas é muito melhor que tentar documentar 100% do projeto antes mesmo de iniciar a codificação.

Sim estamos falando de metodologias ágeis como o Scrum por exemplo, um projeto de software é diferente de um projeto de construção civil e merece um framework de desenvolvimento interativo e incremental.

Planejamento

É necessário analisar qual será o porte da aplicação, não existe uma receita para todo tipo de aplicação, se ela for grande e complexa é necessário abordar alguma prática de arquitetura, por exemplo DDD.

Se a aplicação for simples é necessário evitar exageros e complexidades que não beneficiam as funcionalidades da aplicação.

Orientações como o KISS e o YAGNI dizem para evitar os exageros e manter a aplicação simples, é fato, mas isso não significa que você deve fazer tudo na camada de apresentação por exemplo, uma mínima divisão de responsabilidades é essencial para a qualidade de qualquer tipo de aplicação.

Arquitetura

Arquitetura é a base de tudo, é muito importante fazer a escolha ideal e evitar a famosa “arquitetura BOLOVO” de 3 camadas (Modelo, Business e DataAccess).
Hoje em dia está claro que apesar de funcionar e ser simples esse modelo traz muitos problemas.

É muito importante ter uma pessoa no papel de arquiteto, que conheça diversas estratégias de arquitetura e saiba aplicar bem os inúmeros patterns disponíveis.

Uma vez que possui sua arquitetura definida a aplicação deve se manter dentro do aspecto da arquitetura original, corromper camadas para acessar mais facilmente o banco ou para resolver mais rapidamente um problema pode ser considerado um crime.

Descaracterizar a arquitetura de uma aplicação é o primeiro passo para a famosa “Colcha de Retalhos”. O arquiteto ou líder técnico deve ser responsável por garantir que a arquitetura não esteja sendo corrompida e que seja mantida dentro de sua proposta em toda extensão da aplicação.

Codificação

Mesmo com uma arquitetura definida a tarefa de codificação ainda é complexa e não existem motivos para ser diferente. Codificar exige muitas habilidades além do próprio conhecimento da linguagem e plataforma.

É importantíssimo valorizar os princípios básicos da orientação à objetos como o SOLID que apesar de ser básico podemos dizer que grande parte dos desenvolvedores ainda não sabem como escrever código usando injeção de dependência (DIP) para evitar o alto acoplamento. Realizam heranças sem sentido apenas pelo fato de um objeto herdar hierarquicamente de outro no mundo real. Deixam o princípio de responsabilidade única de lado (SRP) e não criam classes extensíveis (OCP) deixando o código sempre aberto.

Entre outros pontos falhos não citados, os mencionados acima já são responsáveis por grande parte dos problemas existentes em nossas aplicações. Codificar não é uma tarefa menos grandiosa como arquitetar um sistema, pelo contrário, precisamos valorizar mais o programador que possui esses conhecimentos.

Padrões de codificação como nomenclaturas e regras são importantes para manter a expressividade e facilidade de leitura do código. Antigamente programadores se gabavam por fazer códigos que somente eles entendiam, isso não deve existir, o código é uma série de instruções que devem ser de leitura clara e leve, muitas vezes dispensando uma documentação própria.

Uma técnica de codificação que vem ganhando popularidade é o TDD, apesar do TDD ter seu nome diretamente relacionado com testes o TDD na verdade é sobre codificação, os testes que guiam a codificação via TDD servem para garantir a qualidade do código que no final também garantem a sua testabilidade.

Testes

Testes é um assunto complexo, primeiramente devemos entender que teste de software não é apenas rodar a aplicação e ver se tudo está funcionando.

Existe mais de um tipo de teste, podendo ser de unidade, de integração e etc.

Os testes de unidade são necessários quase sempre, podemos dizer que 80% de cobertura de código através dos testes é um resultado bem positivo. Testes de unidade são muito importantes para garantir a boa escrita do código e validar a sua funcionalidade durante o desenvolvimento. Se durante a codificação um teste falhar pode significar que alguma coisa foi feita de forma que o código deixou de funcionar como deveria, logo evitará o deploy prematuro em produção e que o cliente tenha a infelicidade de descobrir um novo bug.

Descobrir um bug em tempo de codificação é N vezes mais barato que descobrir um bug em produção, evita retrabalho, horas extras, replanejamento de deploy, insatisfação com o cliente etc.

Muitas pessoas alegam que escrever testes de unidade fazem o software custar mais caro, pois aumenta mais o esforço de codificação. Isto parece fazer sentido se olharmos apenas no sentido da entrega, mas mesmo assim não faz. Os testes exigem mais esforço de codificação, porém conforme a cobertura de testes aumenta a velocidade de entrega aumenta junto, pois os testes facilitam muito as futuras modificações.

Contabilizar o esforço apenas baseado na entrega é uma falha. Devemos sempre levar em conta a manutenção e evolução, e quando falhamos nesse aspecto estamos iniciando o ponto onde a aplicação vai se tornar cada vez mais complexa para se testar, evoluir, receber manutenções.

Costumo dizer que programamos uma aplicação durante 6 meses e a mantemos durante 3 anos ou mais, sendo assim nosso foco deveria ser na manutenção e evolução e não apenas na entrega. Todo lucro obtido numa entrega mal planejada será perdido durante a manutenção, podendo inclusive chegar ao negativo, e esse é um dos principais motivos que levam diversos projetos falharem e se transformarem em prejuízo quando deveriam continuar gerando lucros.

Os testes de unidade são de responsabilidade do desenvolvedor, os testes de integração e etc podem ser de responsabilidade de um profissional de qualidade ou simplesmente de toda a equipe (equipes multidisciplinares sabem codificar e testar).

Testes de unidade garantem a qualidade de escrita do código e de sua funcionalidade, um código que não está coberto por testes não é um código confiável. Não existe processo ágil de desenvolvimento sem testes, portanto está claro. Testar é preciso!

Quando tudo deu errado.

O planejamento da aplicação não foi bem feito, a arquitetura não foi bem desenhada para atender o propósito da aplicação, a codificação está estruturada, acoplada e sem padrão, não existem testes de unidade e realizar qualquer manutenção significa alterar diversas partes do código e ser obrigado a testar manualmente todas funcionalidades de ponta a ponta, mesmo assim sempre escapando alguns novos bugs.

As noites são longas quando é necessária alguma manutenção, o deploy em produção é uma aventura preocupante, a satisfação de trabalhar no projeto já não existe mais e a pressão não vale a pena.

O gestor do projeto não aceita mais tantos bugs e exige mais assertividade, questionando inclusive a capacidade técnica da equipe, o cliente não aceita mais os prazos para ajustes simples e não quer pagar a mais por isso também.

Não dá mais!  Vamos precisar reescrever essa aplicação do zero.


Se você estiver interessado em conhecer mais e aprender como desenvolver aplicações Web com arquitetura baseada em DDD, aplicando os princípios SOLID, diversos Design Patterns e escrevendo testes de unidade inscreva-se em meu curso:

Vamos continuar a troca de experiências, deixe seu comentário abaixo, se gostou e concorda com o artigo compartilhe com seus colegas para transmitirmos essa mensagem para o máximo de pessoas possíveis. 😉

TFS – Adicionando nova coluna de estado na board.

Adicionando nova coluna de estado na board.

Adicionar nova coluna de estado

No TFS existe como customizar o Workflow de um Work Item como podemos conferir neste artigo que escrevi.

Esse novo estado (foi criado um estado chamado “Testing” no artigo) pode ser atribuído aos Work Items que tiveram seu Workflow modificado, basta abrir o Work Item e selecionar no combo o novo estado.

Após essa implementação com certeza vai surgir outra necessidade, alterar o estado movendo o Work Item na board do TFS. E é isso que vamos aprender neste artigo.

Para isso é necessário editar o arquivo CommonConfiguration.xml do seu template e para acessá-lo basta exportar o arquivo através do comando witadmin

Para encontrar o diretório digite este caminho no Command Prompt:

cd %programfiles%Microsoft Visual Studio 11.0Common7IDE

Em uma edição de 64 bits do windows, substitua %programfiles% com %programfiles(x86)%.

Execute o comando:

witadmin exportcommonprocessconfig /collection:CollectionURL /p:ProjectName /f:"DirectoryPathCommonConfiguration.xml"

CollectionURL especifica a URL de seu Team Project Collection, ProjectName especifica o nome do Team Project, e DirectoryPath especifica o nome e local do arquivo a ser exportado.

Abra o arquivo no notepad e localize o seguinte trecho

  <RequirementWorkItems category="Microsoft.RequirementCategory" plural="Backlog items">
    <States>
      <State value="New" type="Proposed" />
      <State value="Approved" type="Proposed" />
      <State value="Committed" type="InProgress" />
      <State value="Done" type="Complete" />
    </States>
  </RequirementWorkItems>
  <TaskWorkItems category="Microsoft.TaskCategory">
    <States>
      <State value="To Do" type="Proposed" />
      <State value="In Progress" type="InProgress" />
      <State value="Done" type="Complete" />
    </States>
  </TaskWorkItems>

Repare que existem dois blocos, um para itens de Backlog e outro para Tasks, pois existem duas boards, uma de Backlog e outra de Tasks.

Escolha o bloco referente ao tipo de Work Item que foi editado e adicione uma nova linha, esta linha vai receber o valor do novo estado, porém o tipo nesse caso permanece “In Progress”, pois não trata-se do final de um ciclo.

No exemplo abaixo adicionei uma nova coluna para as duas boards.

  <RequirementWorkItems category="Microsoft.RequirementCategory" plural="Backlog items">
    <States>
      <State value="New" type="Proposed" />
      <State value="Approved" type="Proposed" />
      <State value="Committed" type="InProgress" />
      <State value="Testing" type="InProgress" />
      <State value="Done" type="Complete" />
    </States>
  </RequirementWorkItems>
  <TaskWorkItems category="Microsoft.TaskCategory">
    <States>
      <State value="To Do" type="Proposed" />
      <State value="In Progress" type="InProgress" />
      <State value="Testing" type="InProgress" />
      <State value="Done" type="Complete" />
    </States>
  </TaskWorkItems>

O arquivo já está modificado e pronto para ser importado. Utilize o comando de importação com os mesmos parâmetros utilizados para sua exportação:

witadmin importcommonprocessconfig /collection:CollectionURL /p:ProjectName /f:"DirectoryPathCommonConfiguration.xml"

Pressione F5 na board modificada para conferir a inclusão da nova coluna.

Atenção: O valor “nome” da coluna adicionada deve ser exatamente o mesmo do estado criado no Workflow. Para arrastar um Work Item para a nova coluna lembre-se que é necessário existir no Workflow uma transição de estados entre o estado atual e o novo.

Feedback, sugestões, dúvidas utilize o campo de comentário logo abaixo 🙂

Referências

TFS – Customizando o Workflow de um Work Item

No TFS existe a opção de escolher qual o process template da metodologia que o projeto será gerenciado, atualmente existem os process templates para Scrum, MSF for CMMI e MSF for Agile. Os process templates fornecem ao projeto suporte as terminologias e definem vários elementos que determinada metodologia aborda.

É muito comum após um process template configurado surgir a necessidade de alguma modificação / adaptação, pois o processo da equipe pode ter alguma particularidade.

Nesse artigo usaremos o process template de Scrum para o exemplo. No Scrum existe o Conceito de Pronto que significa que um time Scrum define quais critérios são necessários para dar como pronta uma atividade. Com certeza para uma atividade ser considerada pronta é necessário que ela esteja testada. O workflow de uma atividade no process template Scrum vai de In Progress para Done, não existe o estado Testing.

Nesse artigo abordaremos como alterar o workflow de uma tarefa e incluir o estado Testing.

Esse artigo aborda o uso de:

Utilizando o TFS Power Tools para editar um Work Item

Após instalar o TFS Power Tools surgirá uma opção do menu Tools do Visual Studio chamado Process Editor

O Process Editor permite que seja editado um Work Item seja ele global ou de algum projeto específico.

No exemplo será editado o Work Item de Task onde será adicionado um novo campo de valor e também modificaremos o seu workflow para prever o novo estado de Testing.

O caminho a seguir é Work Item Types > Open WIT from Server

Surgirá uma janela de diálogo com os projetos disponíveis no TFS, será necessário expandir o projeto em questão e selecionar o tipo de Work Item a ser editado, selecione Task.

Modificando o Workflow de um Work Item no TFS

Na mesma tela Work Item Type clique na aba chamada Workflow

Abaixo está a ilustração do Workflow original para o Work Item de Task no Process Template Scrum 2.2:

A alteração que será executada será adicionar o novo estado Testing e alterar o fluxo de dos estados existentes, para isso serão necessária as ferramentas de design que estão disponíveis em Toolbox

Criando um Estado no Workflow

Arrastando um item da caixa State para o Workflow

Este é a caixa do novo estado, já foi renomeado para Testing e agora é necessário criar as transições, que são responsáveis por guiar o fluxo.

Para criar uma transição basta selecionar o item Transition Link na Toolbox clicar na caixa que a transição inicia e arrastar e soltar na caixa onde termina.

A transição de estado está feita, isso significa que quanto a tarefa estiver em estado Testing, será possível mudar para Done, agora é necessário realizar algumas configurações.

Com um duplo clique na caixa Transition abrirá uma janela de diálogo Workflow Transition.

Na aba Reasons cadastraremos um novo valor para quando o estado de Testing passar para Done.

Clicando em New para preencher o valor do Reason, que é a razão pelo qual a tarefa mudou de estado.

Note que no fluxo principal, a caixa Done requer a adição de um parâmetro o Closed Date, isso significa que é necessário passar essa informação para que haja transição de Testing para Done, a passagem desse valor é feita durante a transição através do item recurso Fields.

Pressione OK e retorne a janela de diálogo Workflow Transition, selecione a aba Fields e clique em New, o combo abaixo irá exibir diversas opções selecione ClosedDate.

Além de selecionar a referência do campo a ser passado é necessário configurar a regra de passagem, clique na aba Rules e selecione New, uma janela com uma lista exibirá todas as regras existentes, nesse caso a regra SERVERDEFAULT deve ser escolhida, pois trabalharemos com uma informação do servidor.

Como estamos trabalhando com um valor do tipo DateTime selecione no combo From a opção Clock, significa que iremos utilizar a data que está no servidor como referência.

Etapa concluída, o novo estado Testing está configurado e a transição para Done foi finalizada.

Note que exitem outras transições a serem feitas como por ex:

  • In Progress > Testing (Atividade finalizada e encaminhada para testes)
  • Testing > In Progress (Bugs encontrados, necessário trabalho adicional)

Basta seguir o mesmo processo para as demais transições.
Salve as alterações pelo Visual Studio e automaticamente o novo estado Testing estará publicado.

No próximo artigo gravarei um vídeo executando este processo e fornecendo mais detalhes de como modelar o Workflow de um Work Item.

Utilizem os comentários para dúvidas ou feedbacks.
Até a próxima 😉

Um pouco sobre Scrum

Olá pessoal, o quanto vocês conhecem de Scrum? Para quem conhece muito pouco ou nada, sugiro que adentre neste universo, acredito que uma hora vai ser muito útil.

Já ouvi diversos colegas de trabalho dizendo, “onde eu trabalhava, utilizávamos Scrum, fazíamos Sprints, reuniões diárias mas não adotamos a Retrospectiva da Sprint…” 

Há de convir que atualmente existe uma certa moda em adotar Scrum, e isso não é ruim, significa que a metodologia tradicional de desenvolvimento de sistemas é falha e muitas empresas estão caindo na real sobre isso.

Mas um detalhe, adotar boas práticas de Scrum não é usar Scrum!
O Scrum é fechado, é necessário seguir todas cerimônias, papéis, recomendações e regras. Do contrário estaríamos usando “Scrum-But” ou seja “Scrum-Mas”, esse é o nome dado para quando não usamos o Scrum conforme todas as suas recomendações.

É uma prática muito comum em empresas que estão adotando uma metodologia ágil iniciar pelo Scrum-But, e até ai tudo bem, o importante é seguir no caminho até que seja alcançada a plenitude do uso do Scrum. O guia oficial diz o seguinte sobre Scrum:

  • Leve
  • Simples de entender
  • Extremamente difícil de dominar

Neste post não vou explicar tudo que é recomendado para utilizar o Scrum, mas o guia oficial dará uma visão, procure gradativamente adotar todas as práticas e aplicá-las da forma correta.

Depois de dominar o Scrum concordo que ele pode ser modificado para atender melhor a dinâmica da empresa, mas veja, depois de adquirir maturidade, não antes.

Para quem quer se tornar um profissional Scrum existem diversas certificações, e o mercado está em busca de profissionais certificados, uma boa oportunidade de melhorar o currículo.

Como disse, era apenas um pouco sobre Scrum, voltarei em breve com mais assuntos deste tema. Espero que aproveitem e no caso de dúvidas utilizem os comentários.

Até mais.