Arquivo de dezembro \30\UTC 2010

Como eu Desenvolvo Software – Parte 4

Oi pessoal, espero que todos tenham tido um ótimo natal! Eu consegui descansar um pouco, aproveitando para passar um fim de semana agradabilíssimo com a família em Bonito – MS. Para quem não conhece, recomendo muito, a região é fantástica, com locais maravilhosos.

Retomando o post anterior, eu estava falando sobre a minha maneira de desenvolver software, com o objetivo de fornecer uma perspectiva possível para os que estão começando, ou uma outra visão para os que estejam tentando definir uma forma prática para trabalhar com desenvolvimento. No post anterior, eu apresentei um problema fictício e a decisão de construir um sistema web para resolvê-lo. Iniciei com a análise sobre as condições de contorno do sistema e toda a parte de infra-estrutura envolvida. Estávamos no ponto onde tínhamos o esqueleto definido, com a parte de segurança já estabelecida. Até este momento, estávamos vendo questões de caráter não-funcional do sistema. Num cenário real, estas questões podem ser muito mais complexas do que o meu exemplo, pois pode já haver algum tipo de restrição de desempenho ou de segurança, por exemplo, que exija uma infra-estrutura muito mais complexa, fazendo com que esta etapa se torne um projeto em si.

Mas assumindo que seja algo padrão, a próxima fase seria começar a trabalhar na parte funcional do sistema. Neste momento, o que eu faço é começar por uma tarefa que seja algo que possa dar valor imediato para o cliente. Se o objetivo do sistema é controlar despesas de viagem de funcionários, algo que poderia ter valor imediato seria disponibilizar a lista das últimas viagens realizadas, com a consulta de viagens individuais e o cadastro de nova viagem. Claro que fazer algo de grande valor pode fazer com que seja necessário existir previamente toda uma gama de telas de apoio. Por exemplo, se estamos controlando viagens, teríamos que ter o cadastro de funcionários, de destinos, de tipos de despesa contabilizadas etc. Neste ponto começa a surgir o conceito de “Domínio” do problema (ver DDD), onde os termos já passam a ter um significado específico (ubiquitous language) e são utilizados para uma melhor comunicação com o cliente. Esta comunicação é fundamental para o sucesso e a evolução posterior do sistema, portanto é de grande importância tentar definir os termos corretos e já empregá-los toda vez que houver alguma comunicação.

Cada entidade de apoio deve ter seu mecanismo de persistência definido. No meu caso, diferentemente do DDD, eu não utilizo agreggates para centralizar a persistência. Para mim, cada entidade de domínio vai ser traduzida diretamente em uma tabela do banco de dados – a única exceção são as entidades que são classificadas como enumerations (enums), estas ficam só em código. O que diferencia enums de entidades de apoio, para mim, é o significado para o sistema da inclusão de novos registros. Se um usuário puder incluir uma instância da entidade e o sistema não tiver que ter sua parte de negócio alterada por causa disto, ela é uma tabela; caso contrário, é uma enum. Por exemplo, um cliente pode cadastrar uma cidade de destino a qualquer momento e nenhuma regra de negócio precisa ser alterada. Agora, imaginemos que existam categorias de faturamento pré-definidas que vão definir graus de reembolso. Se cadastrar um novo tipo de categoria ou uma categoria inteira implicar na necessidade de alteração do sistema, ela é um enum. Claro que sempre pode-se tentar modelar um sistema onde haja pouca necessidade de modificações, com quase tudo parametrizado em entidades e praticamente nenhuma enum. Mas pode ser que isto não valha a pena em determinados cenários.

Uma vez que as entidades de apoio estejam definidas, vão ser criados os objetos de domínio que as irão representar. No meu caso, esta tarefa é feita na seguinte ordem: 1) Primeiro a entidade tem seu principais atributos identificados (mentalmente); 2) É criada a tabela no banco de dados que vai armazenar a entidade – eu tento manter a tabela com os nomes de colunas o mais próximo possível dos atributos do objeto; 2) Usamos o framework, para gerar a entidade no diagrama do ActiveWriter; 3) Usamos os geradores de código .TT do framework para efetivamente construir a entidade e o respectivo repositório (sim, cada entidade tem o seu) e factory. Este processo é muito rápido, é questão de segundos fazer uma entidade usando esta sequência. Como tudo é feito no framework, a partir da geração tudo está 100% funcionando, já que não há nenhuma intervenção manual; assim nem é necessário utilizar testes unitários para entidades. Alguns até argumentam que eles seriam úteis para facilitar na evolução no caso de modificações de entidades; porém na minha experiência, este tipo de coisa é tão rapidamente detectado e corrigido que não justifica o esforço de testes (nem mesmo o esforço de tentar automatizar a construção dos mesmos via framework, pelo menos não até o momento).

Sempre com o objetivo de gerar a tela de melhor valor, deve-se então identificar, das entidades de apoio, quais são as necessárias para cadastrar dados que irão ser utilizadas na tela. É importante detectar dados de apoio que são tão importantes que merecem ser tratados como uma tarefa própria. Neste nosso exemplo, existe uma grande chance de o cadastro de funcionário ser um caso destes, seja pelo volume de informações, seja pela necessidade de um maior número de regras de negócio que devem ser seguidas durante o cadastro. Para cada um destes casos identificados é criada uma nova tarefa, de prioridade maior e da qual a tela de melhor valor será dependente.

Para os outros casos, é criada uma tela de CRUD. Telas deste tipo são também feitas com suporte do framework; construí-las é simplesmente definir colunas de visualização e busca na lista de entidades, definir os campos que serão utilizados no formulário de inclusão/alteração e escrever eventuais regras de validação de inclusão/modificação. Um CRUD simples pode ser feito no framework em poucos minutos (o meu record é 8 minutos para uma entidade simples, considerando a criação da tabela, da entidade e das telas). E como todas as telas de CRUD também são construídas de forma padronizada, também não utilizamos testes unitários para este tipo de tela. A criação de CRUDs é um processo tão rápido que há uma tentação de se tentar fazer um sistema inteiro usando telas deste tipo. Isto dificilmente é viável. Primeiro porque telas que possuem formulários muito grandes podem ser confusas para o usuário. Segundo porque para fazer uma atividade simples, um usuário teria que navegar em muitas telas, o que também atrapalharia a usabilidade. Assim, eu prefiro somente utilizar CRUDs para as entidades de apoio mesmo.

Neste ínterim o cliente está sempre sendo atualizado. Ele é notificado e participa cada vez que uma nova tarefa é gerada. A cada CRUD liberado ele também é notificado. Em novos sistemas, os primeiros releases já podem conter várias telas de CRUD 100% operacionais. Isto contribui para que o cliente perceba o andamento do projeto e já possa atuar em eventuais falhas de comunicação ou entendimento.

Novamente este post já está muito grande. Vou parar por aqui, continuo na semana que vem. Acho que em mais 1 ou 2 posts eu consiga finalizar esta série. O assunto é muito extenso, cada um dos tópicos que eu mencionei poderia se tornar um post completo. Espero que esteja conseguindo ao menos dar uma visão geral do processo. Por favor, fiquem à vontade para perguntar ou sugerir.

Desejo a todos um feliz 2011, repleto de realizações e com muita saúde e sucesso!

, , , , ,

Deixe um comentário

Como eu Desenvolvo Software – Parte 3

Continuando o post anterior sobre desenvolvimento, estava falando sobre como um software surge a partir de uma necessidade. É importante notar que, apesar da necessidade orientar o desenvolvimento do um sistema, ele sempre vai existir em uma plataforma, sendo exemplos de plataformas comuns: Windows (consumindo serviços WCF ou acessando direto o banco), web (hospedado localmente ou em algum provedor e acessado por um browser) ou alguma plataforma móvel (android, iOS). A definição da plataforma normalmente implica em algum tipo de restrição ou característica especial no software sendo construído.

Existem ainda as diversas questões de infra-estrutura: a aplicação vai usar banco de dados (SGBD)? Qual? Onde será hospedado? Qual versão de .NET? MS-MVC ou Monorail? E assim por diante… Para simplificar, vou assumir a plataforma web MS-MVC (devo comentar algo sobre outras plataformas no decorrer dos artigos), utilizando a versão mais atual do .NET, utilizando um banco de dados típico (que no meu caso usualmente é o Microsoft SQL Server) e que será desenvolvida utilizando o nosso framework – aplicações que não fazem uso dele ficam tão mais caras que na maior parte das vezes são inviáveis.

Voltando ao exemplo do post anterior, imaginem uma planilha para, por exemplo, controlar viagens de funcionários de uma empresa. As viagens são controladas por funcionário e cada viagem possui informações como data, custo, meio de transporte, destino, despesas diversas e reembolsos. Por alguma razão (volume, por exemplo), alguém avaliou que um sistema poderia diminuir custos de gestão desta planilha, disseminar melhor a informação e facilitar a vida do usuário permitindo, por exemplo, que ele digite as informações diretamente por uma página da intranet da empresa.

Se fosse assumir um sistema deste, a primeira coisa seria entender qual o custo atual do cliente para operar as planilhas, o quanto ele espera gastar e obter com o sistema e avaliar se o que é esperado é factível dentro do que eu acho que seria gasto, baseado na minha experiência no desenvolvimento de aplicações com nosso framework. Teria que ver também se o cliente já está familiarizado com o formato ágil de desenvolvimento e com a nossa forma de trabalho. Caso positivo, teria que identificar a seguir aspectos sobre a infra, ver se já existe um SGBD disponível, onde o servidor web está localizado, se a equipe de infra tem experiência em instalar e manter a aplicação, se os servidores estão atualizados com as últimas versões do .NET etc… Se houver algum problema com algum destes pontos, eu tento resolvê-lo antes mesmo de iniciar o desenvolvimento, pois ele pode se tornar um impeditivo para todo o projeto.

A seguir, ainda na parte de infra, eu identifico como será feita a autenticação de usuários. Normalmente, para aplicações intranet, espera-se uma autenticação integrada com o Active Directory ou algum serviço similar. Para aplicações públicas da Internet, é necessário ver também as questões de segurança, como acesso seguro, certificados para HTTPS, firewalls etc… Muitos desenvolvedores acham que estas tarefas não cabem a nós; eu não consigo concordar com isto, pois falhas nestas áreas podem tornar o melhor software do mundo completamente inútil.

Finalmente, tem-se que decidir como fica o direito de propriedade e uso do software e se o cliente deseja exclusividade sobre algumas porções do software – caso positivo, isto também torna o desenvolvimento mais caro. Como se pode ver, é um grande esforço destinado somente à análise de custo e da infraestrutura, antes mesmo que qualquer hora seja empregada no software em si. Não adianta fazer um excelente software se ele não puder se pagar, ser instalado ou ser mantido adequadamente. Mas apesar da quantidade de tópicos, um checklist com todos estes itens pode ser preenchido em uma ou duas reuniões com as pessoas certas.

Após esta fase, eu posso iniciar a construção da infra-estrutura do sistema. Utilizando o framework, eu posso montar a parte básica da aplicação, que contém uma página default, o banco de dados vazio com a tabela de usuários do sistema, a tela de login com seus respectivos controllers e toda a parte de integração com um sistema de autenticação. Normalmente eu consigo colocar isto no ar em menos de 4h após o início do projeto, pois tenho estas estruturas padronizadas no framework de desenvolvimento. Os casos que demoram mais são os que exigem uma aparência específica do site feito por um designer que me obriga a recortar htmls para a geração dos layouts. Em casos extremos, isto pode levar alguns poucos dias. Esta etapa seria o que alguns chama de Iteração 0. Eu não uso um nome específico, simplesmente utilizo uma parte do esforço da primeira iteração. Como resultado, o cliente já tem o site rodando e logando, caindo na página inicial, com toda a parte de segurança funcionando, e, quando aplicável, com funcionalidades como troca de senhas, “esqueci minha senha” e login integrado.

Paralelamente a esta fase, é feita a primeira reunião de priorização de atividades com o cliente. Nesta reunião são identificadas as funcionalidades principais do sistema e feita a priorização das mesmas. Quando eu faço isto, eu tento já identificar o que pode trazer maior ROI ou maior impacto positivo para o cliente é já sugiro uma ordem de atividades. Quando mais experiência o cliente tem em desenvolvimento no formato ágil, mais ele consegue contribuir nesta etapa. Mas, de uma forma ou de outra, eu tento sempre conduzir para que ele utilize o esforço de desenvolvimento da maneira mais benéfica possível para atingir o objetivo do sistema. No caso da planilha, o que seria mais positivo? Colocar a página pública logo para que os funcionários pudessem já ver o novo sistema e começar a testar o lançamento de dados? Ou colocar a apuração de despesas disponível? Ou facilitar, por exemplo, uma exportação de dados da planilha? Estas decisões são feitas caso a caso, mas imaginemos que no nosso o mais benéfico fosse o lançamento de dados pelo funcionário.

Bom, o post está ficando muito longo, assim vou ter que continuar num próximo, provavelmente a ser publicado só depois do Natal. Até lá e aproveito para desejar a todos um Feliz Natal e Boas Festas!

, , , , ,

Deixe um comentário