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 😉

TFS – Aumentando o número de itens na board

Em muitos projetos o número de itens em uma board ultrapassa a média qual o TFS vem configurado por padrão e quando isso acontece ao acessar a board é exibida a mensagem:

“You have exceeded the number of items allowed on your taskboard.”

Não precisa se preocupar, o TFS limita a board em 500 items por medida de performance, pois todos os items são carregados em cache de forma que sua exibição se torne muito rápida.

Para resolver é necessário editar o arquivo AgileConfiguration.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 exportagileprocessconfig /collection:CollectionURL /p:ProjectName /f:"DirectoryPathAgileConfiguration.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 de AgileConfiguration.xml no notepad e localize a seção IterationBacklog, Especifique um valor para o atributo workItemCountLimit (Ex. 800).

<IterationBacklog workItemCountLimit="800">
. . .
  </IterationBacklog>

Isso significa que ao invés de 500 a board passará a exibir 800 itens.

Depois de salvar o arquivo basta importá-lo usando o mesmo comando:

witadmin importagileprocessconfig /collection:CollectionURL /p:ProjectName /f:"DirectoryPathAgileConfiguration.xml"

É a mesma sintaxe, com a diferença que agora trata-se de uma importação.
Atualize a board com F5 e as alterações irão refletir, exibindo novamente os itens com o novo limite de 800.

*PS – Aumentar demasiadamente o número de itens na board pode prejudicar a performance.

Bons projetos a todos 😉

 

TFS – Team Foundation Service – Parte II – Criando uma conta

Olá pessoal,

Como havia prometido no post anterior, este post possui um vídeo que eu gravei falando sobre o Team Foundation Service, explico a diferença com o Team Foundation Server e caminho passo-a-passo desde o início no processo da criação de uma conta no Team Foundation Service.

Aproveitem e deixem seus comentários 🙂

TFS – Team Foundation Service

TFS – Team Foundation Service, é a conhecida plataforma de gerenciamento de código fonte e colaboração da Microsoft que foi parar na nuvem.

Team Foundation Service

Quando pensamos em TFS geralmente nos vem o nome Team Foundation Server, afinal trata-se de uma plataforma local, interna e instalada em um servidor.

A Microsoft há algum tempo disponibilizou esta mesma ferramenta só que hospedada na nuvem, ou seja, nos servidores do Windows Azure.

O famoso TFS passou a ser disponibilizado como serviço, notem que está cada vez mais comum encontrar os “SaaS” Software as a Service, diversos produtos da Microsoft já foram para nuvem (ex Office 365).

Minha experiência:

Tanto em casa como no trabalho eu sou usuário do TFS, no trabalho usamos a versão internalizada, ou seja instalada, e em casa antigamente eu tinha uma virtual machine rodando um windows 2008 server apenas para suportar o TFS.

Com o lançamento do TFS 2012 veio a versão TFS Express, gratuita para 5 usuários (porém com algumas limitações), que roda inclusive em windows 8.

Não cheguei a fazer uso do TFS Express, migrei diretamente para o TFS (Service) também conhecido como TFS Preview e o melhor, é de graça para 5 usuários também.

Estou plenamente satisfeito com minha escolha, não precisei instalar nada, apenas com a conta da Microsoft (antigo Live ID) fiz o login no site https://tfs.visualstudio.com/ e criei minha conta no TFS.

Todos os serviços estão disponíveis sem limitações, mesmo para as contas gratuitas, algumas funcionalidades podem se tornarem pagas daqui algum tempo, mas por enquanto a experiência é completa, vale a pena a imersão 🙂

A intenção deste post foi apresentar o serviço do TFS e comentar sobre minha experiência.
Em continuação deste farei um post técnico onde irei explicar passo-a-passo todo processo de utilização, aguardem 🙂

Até mais e abraços!

Undo Checkout no TFS

Undo Checkout no TFS é um processo comum, mas e quando o arquivo está preso a outra pessoa? Nesse caso existem ferramentas de apoio para resolver, mas se você não tem nenhuma a solução é mais uma vez a linha de comando.

O comando é o tf undo (tf.exe) e para executá-lo você precisa do Visual Studio instalado

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)%.

*Atente-se ao diretório devido a qual versão do Visual Studio está usando.*

O comando deve ser chamado da seguinte forma:

tf undo [/workspace:workspacename[;workspaceowner]]
[/recursive] itemspec [/noprompt] [/login:username,[password]]
[/collection:TeamProjectCollectionUrl]

Naturalmente o usuário deverá ter permissão de Administer Workspaces para realizar esta operação.

/collection : TeamProjectCollectionUrl
Especifica a URL da coleção de projeto de equipe que contém os itens. Por exemplo: http://myserver:8080/tfs/DefaultCollection.

itemspec
Especifica o escopo de itens. Você pode especificar mais de um argumento de itemspec Para a sintaxe, consulte Referência de comandos de controle de versão do Team Foundation.

/login
Especifica a conta de usuário para usar o para executar o comando. Consulte Referência de comandos de controle de versão do Team Foundation.

/noprompt
Suprime a exibição das janelas e caixas de diálogo e redireciona dados de saída para o prompt de comando. Consulte Referência de comandos de controle de versão do Team Foundation.

/recursive
Desfaz recursivamente alterações dos itens no diretório especificado e todas as subpastas.

/workspace workspacename[;workspaceowner]
Especifica o nome do espaço de trabalho que você deseja desfazer alterações pendentes. Se não for especificado, o espaço de trabalho é aquele que mapeia o diretório atual.

Exemplos:

Remover as alterações pendentes em um arquivo
– Remove todas as alterações pendentes em program.cs

c:codeSiteAppMainSolutionAProject1>tf undo program.cs

Remova recursivamente durante alterações em todos os itens em uma pasta
– Remove todas as alterações pendentes na pasta c:codeSiteAppMain e todas suas subpastas.

c:codeSiteAppMain>tf undo * /recursive

Remover as alterações pendentes em um arquivo em um espaço de trabalho remota
– Remove todas as alterações pendentes em program.cs na coleção e o espaço de trabalho especificados.

c:>tf undo /collection:http://fabrikam-3:8080/tfs/DefaultCollection
/workspace:FABRIKAM-1;JuliaI $/SiteApp/Main/SolutionA/Project1/program.cs

Até a próxima dica 😉

Deletar Work Item no TFS

Deletar Work Item no TFS é sempre uma dúvida que surge ao implantar a ferramenta, pois sempre abrimos alguns para testar e depois não precisamos mais.

Não tem interface visual que faça a deleção do Work Item, mas existe a linha de comando, grande aliada para resolver N situações.

O comando é o witadmin e para executá-lo você precisa do Visual Studio ou Team Explorer instalado

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

cd %programfiles%Microsoft Visual Studio 11.0

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

Para ter permissão de remoção do Work Item você precisa ser Administrador do TFS ou do projeto em questão.

Execute o comando:

witadmin destroywi /collection:CollectionURL /id:id [/noprompt]

/collection:CollectionURL
Especifica a URL a coleção de projeto de equipe. o formato para o URI é o seguinte: http:ServerName: porta/VirtualDirectoryName/CollectionName/

Se nenhum diretório virtual é usado, o formato para o URI é o seguinte:
http: /ServerName: porta/CollectionName.

/id:id
A identificação de um item de trabalho a destrui-lo. Para especificar mais itens de trabalho, IDs separadas por vírgulas, sem somente espaço em branco.

/noprompt
Desativa o aviso para a confirmação.

/?ou help
Exibe ajuda sobre o comando na janela do prompt de comando.

Exemplo:

witadmin destroywi /collection:"http://dev-win-01:8080/tfs/Em Andamento/" /id:25

Até a próxima dica 😉

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.

DDD, TDD, BDD, Afinal o que são essas siglas?

Olá pessoal, Hoje vamos falar sobre DDD, TDD, BDD.

Muitas vezes pela internet em busca de novos conhecimentos nos deparamos com diversas siglas, estando elas anunciadas em algum requisito para desenvolvimento de sistema ou até mesmo citadas em alguma abordagem técnica.

Afinal o que são e para que servem?
Abordaremos de forma prática sua definição, muitos irão perceber que já estão usando e nem sabiam.

DDD – Domain-Driven Design (Desenvolvimento Guiado por Design ou Desenvolvimento orientado a Domínio)

Erick Evans lançou em 2003 o “Domain-Driven Design: Tackling Complexity in the Heart of Software” Mal imaginou que o livro tanto quanto o conceito alcançaria tal sucesso e respeito.

Trata-se de uma abordagem de design de software de forma disciplinada, abordando uma série de conceitos e técnicas sempre com foco no domínio do software.
Hoje em dia precisamos entender muitas técnicas, OO, SOA, EntityFramework, NHibernate, Injeção de Dependência e etc… O DDD não vem para substituir e também não é uma tecnologia, poderíamos dizer uma filosofia, não é algo super novo inventado e sim mais uma compilação de muito que já sabemos e aplicamos.

Como dito anteriormente o foco é no Domínio do Software, no propósito que o software deve atender, é a automatização de um processo de negócio.
Domínio nada mais é que do que você já está imaginando, ou seja, atender completamente um determinado negócio.

Ok! Mas todos os softwares corporativos não são desenvolvidos nesse propósito?
O DDD traz abordagens de como fazer isto, como atender um domínio complexo de informações. O pilar do DDD é conceitualizar em forma de Modelo o seu domínio.

Quando pensamos em modelo nos vem à cabeça: UML, Diagrama de Sequência, Diagrama de Estados e todo arsenal que pudermos montar.
Mas não exatamente, o Modelo pode ser feito de qualquer forma que possa ser entendido, Papel de pão, UML, Lego ou Massa de modelar, Não há padrão para modelo. Se o seu modelo expressar certo o funcionamento de negócio está perfeito!

E o que aborda o Modelo?
O modelo é um universo composto por cinco itens principais:
Entidades, Objetos de Valor, Factories, Serviços, Repositórios.
Já começou a ficar familiar, mas vamos entender mais um detalhe que o DDD aborda:

Ubiquitous Language:
Traduzindo, “Linguagem Onipresente”, é a que está em todo lugar. É a linguagem de quem entende do negócio.
Ex. O seu cliente, por um acaso um banco, fala Amortização (pagamento de parcelas). Logo sua equipe também fala Amortização, e isso se repete no modelo e no código.
É uma forma de todos falarem a mesma língua, a língua do negócio (Domínio).
Para se obter sucesso de um projeto DDD é necessário que todos os integrantes falem e entendam completamente o domínio.

Separação das camadas:
Na hora de desenvolver as camadas é necessário cuidado, as camadas precisam ser independentes, se duas camadas se misturam então não são duas camadas. Se você está desenvolvendo um sistema Web orientado a um domínio e resolveu migrar para ASP.Net, você necessita mudar a camada de UI (User Interface) e nada mais, pois são camadas independentes, o Core Domain (Dominio Principal) não depende da camada UI, e não só necessariamente uma UI, podemos estar falando de um WebService por exemplo, imagine que esta desenvolvendo um serviço SOA e quem consome o Core Domain seja um outro sistema.
Um software de negócios, com regras complexas pode ter N camadas, mas deve existir a camada Domínio, ela é o coração do sistema e a mais importante, afinal lá estão as regras de negócio que atendem ao domínio.

Voltando aos itens principais do modelo, começaremos com a Entidade:
Tudo que tenha valor ao domínio (regra de negócio) deve possuir uma entidade.
Voltando ao exemplo do banco, uma entidade seria o Cliente, toda entidade possui uma identidade nesse caso a Entidade Cliente possui uma Identidade (CPF).
Devemos escrever nesta camada todas as entidades ligadas ao domínio da forma mais simples, que seja implementada facilmente sem algum tipo de interface ou etc.

Objetos de valor:
São objetos reconhecidos por seus atributos e geralmente são imutáveis.
Por ex: Tipos de Conta são do tipo Corrente, Investimento, Crédito, Transitória e etc.
Sendo assim na hora de referenciar esse objeto de valor em sua entidade você necessita que ele possua estes tais atributos, pois fazem parte do domínio de seu negócio, chamamos isso de Agregação.

Serviços:
São ferramentas, pois não são entidades nem possuem objetos de valor.
Se por exemplo você precisa enviar um relatório de contas correntes ao Banco Central, sua entidade bem como os objetos de valor não estão preparados para isso, você precisa que um serviço execute essa tarefa, e por isso eles estão presentes no modelo de domínio do DDD.

Factories:
Em português “Fábricas”, Factories criam objetos, existem cenários quais são impossíveis de definir um objeto sem a criação dele através de uma Factory, sugiro para quem não entende direito o conceito de Factory, a leitura deste exemplo.

Repositório:
Não importa onde esteja alocado seu repositório, em algum momento você vai precisar guardar e recuperar um conjunto de informações como um objeto.
Repositórios não tem regra de negócios, eles fazem a intermediação da sua camada de domínio e sua camada de mapeamento de dados. Pode ser usado NHibernate, Entity Framework entre outros, escolha bem o seu.

Enfim, qualquer abordagem de DDD é muito bem aceito numa metodologia ágil.
Receber os feedbacks dos donos do negócio ao tempo todo é fundamental para uma entrega assertiva. Dentro de uma metodologia ágil programar pequenas entregas é uma boa prática, pois não se inicia no 0% e entrega-se 100% com grandes chances de  conter desvios de entendimento.
Sprints, entregas particionadas, diminuem o risco de desvio do entendimento do domínio, assim como do retrabalho.

Lembrando que uma metodologia ágil não faz parte exatamente de uma abordagem de DDD, mas é muito bem vinda.

O DDD é indicado ao meu projeto?
O DDD é indicado para seu projeto caso ele possua um conjunto de regras complexas de negócio, para um sistema simples não é aconselhado o uso de DDD.
Na maioria dos sistemas corporativos são encontradas diversas regras de negócio e cada uma com sua particularidade e complexidade.  Iniciar um projeto usando a abordagem de DDD previne que o sistema cresça cada vez mais de uma forma não orientada ao domínio.

TDD – Test-Driven Development (Desenvolvimento Orientado a Testes)

Baseado no DDD e defendido pelo Extreme Programming  XP (outra abordagem de programação ágil) é o Desenvolvimento de Software orientado a Testes.

É uma abordagem que oferece muita agilidade dentro do ciclo de desenvolvimento, a ideia é codificar um sistema com 100% de cobertura dos testes.

O processo de desenvolvimento do TDD seria:
RedGreen, Refactor.

  1. Escrever um teste, sem mesmo ter escrito o código real a ser testado (Figure o que deseja testar).
  2. Executar os testes e acompanhar a falha (Pode ser um código falso que retorne o  erro) (Red)
  3. Escrevemos a funcionalidade do sistema que iremos testar.
  4. Testar novamente, agora para passar (Se não passou algo saiu errado, faça novamente o passo 3) (Green)
  5. Refatore sua funcionalidade e a escreva por completo (o teste também) (Refactor)
  6. Passe para o próxima estória ou caso de uso e inicie novo teste.
Para a criação de testes em .Net é bem recomendado o uso de NUnit.
Abaixo um exemplo de caso de teste desenhado:
using System;
using NUnit.Framework;

namespace TDD.ClienteBanco
{
    [TestFixture]
    public class ContaTests
    {
        [Test]
        public void TestAporte()
        {
            Conta conta = new Conta("Test");
            conta.Deposito(500.0);
            conta.Deposito(70.0);
            Assert.AreEqual(570.0, conta.Balanco);
        }
     }
}

Resumindo, é uma prática bem utilizada e entende que o desenvolvimento é feito do teste para o código.
Teste unitário não é tarefa do Tester e sim do desenvolvedor, em muitas empresas um código sem testes unitários nem sobe no repositório. Pense em código, pense em teste de cobertura de código.

Para criação dos testes é bem eficaz a utilização de Mock, Dummy, Fake, Stub, que são considerados dublês de teste, pois se passam por objetos reais sem a necessidade de codificação dos mesmos na etapa da escrita do teste.

Posso utilizar TDD com DDD?
Sim.
Posso utilizar TDD em processos não ágeis?
Sim.
TDD é útil para design de software?
Sim.
Escrever testes após desenvolvimento é TDD?
Não.

BDD – Behavior Driven Development (Desenvolvimento Guiado por Comportamento ou Desenvolvimento Orientado a Comportamento)

Foi originalmente concebido em 2003, por Dan North, como uma resposta ao TDD, tem se expandido muito assim como DDD e TDD.

É uma abordagem que funciona também muito bem com uma metodologia ágil, encorajando desenvolvedores, pessoas de qualidade, não técnicas e de negócios em um projeto de software. Também defende o uso da ubiquitous language como explicado acima facilitando a conversação entre toda equipe envolvida.

Como começa a prática do BDD:

  1. Envolver as pessoas no processo através de Outside-in Development (Desenvolvimento de Fora pra Dentro)
  2. Usar exemplos para descrever o comportamento de uma aplicação ou unidades de código
  3. Automatizar os exemplos para prover um feedback rápido e testes de regressão
  4. Usar “deve”  na hora de descrever o comportamento de software para ajudar esclarecer responsabilidades e permitir que funcionalidades do software sejam questionadas
  5. Usar dublês de teste (mocks, stubs, fakes, dummies) para auxiliar na colaboração entre módulos e códigos que ainda não foram escritos.
Como o BDD é guiado pelo comportamento do negócio uma maneira de perceber o benefício produzido é pela interface gráfica, produzindo um feedback rápido para saber se os requisitos descritos através dos comportamentos estão funcionais.Escrevendo um requisito de comportamento do sistema:
Em BDD, um desenvolvedor, ou profissional do setor de qualidade ou até mesmo o cliente podem escrever os testes que basicamente são compostos em duas partes, a definição da funcionalidade a ser implementada (User storie) e os cenários de uso que irão validar este requisito.
A funcionalidade é escrita segundo um padrão:

Funcionalidade : [Nome]

Para [ Valor ao Negócio ] Eu, como [ Papel ] Desejo poder realizar [ Funcionalidade ]

Dessa forma fica muito claro a todos quais são os objetivos que uma funcionalidade deseja atingir e é de muito fácil entendimento.
Os cenários acompanham a funcionalidade de forma que demonstram comportamentos para atendê-la:

Cenário : [ Nome ]

Dado que [ Estado inicial do sistema ] Quando [ Ação a ser realizada no sistema ] Então [ Coisas que o sistema deve fazer após a ação do Quando ]

As palavras Dado queQuando e Então (GivenWhen e Then em inglês) são quase sempre usadas para guiar os cenários, não são obrigatórias.

A criação de requisitos para teste podem ser automatizados, existe uma ferramenta chamada SpecFlow,  que se adapta ao Visual Studio e suporta o idioma português.
Através do SpecFlow no Visual Studio é necessário adicionar um arquivo do tipo Feature File “.feature” e nele seria escrever uma estória.

Um exemplo bem simples de estória de uma aplicação de vendas poderia ser: “Venda de balas na doceria”.

#language: pt-br
Funcionalidade: Vender doces
     Para quando uma doce for vendido
     Eu, como vendedor
     Desejo decrementar um item no estoque

Cenário: Baixa 1 bala do estoque
     Dado que cliente pede 1 bala
     E tenho 10 balas em estoque
     Quando ele compra realiza a compra
     Então eu fico com 9 balas em estoque

Dado esta descrição o SpecFlow irá gerar um arquivo “.feature.cs” que será usado para testes, se rodar os testes após o momento da criação do arquivo com certeza vão falhar, afinal não existe a classe escrita nem a interface desenhada.

É possível fazer testes de interface e end to end sem muito esforço, usando ferramentas como o Watin e também Mock, Dummy, Fake ou Stub como dublês de objetos.

É nesse momento que entra o desenvolvimento da sua aplicação utilizando DDD e/ou TDD (por que não?) e após desenvolvida deve-se complementar o seu arquivo “.feature.cs” com as chamadas da interface para reprodução do requisito desenhado, então você poderá acompanhar o funcionamento do seu negócio com base nesses testes.

Esta é a abordagem do BDD, estimulando os todos envolvidos da equipe, técnicos ou não a escreverem um sistema baseado em comportamentos através de requisitos, estórias, funcionalidades e cenários.

É isso ai pessoal, espero ter abordado o DDD, TDD e BDD de forma clara e que tenha conseguido explicar cada um deles, suas diferenças entre si e como podem ser trabalhados juntos.

Referências: