Desenvolvimento de Software « Encarando o Desenvolvedor
As metodologias de desenvolvimento "ágeis" traçam as suas origens ao "Manifesto Ágil" de 2001. Estas, são frutos da frustração com as técnicas de desenvolvimento tradicionais, principalmente o chamado "waterfall". As metodologias tradicionais são usualmente associadas a atrasos de entrega, excesso de custos, frustração dos usuários com o produto final e também com o ritmo de trabalho maluco imposto aos desenvolvedores, especialmente próximo ao prazo final de entrega.
O "waterfall" define fases precisas e seqüenciais de "levantamento", "projeto", "construção", "integração", "testes", "implantação" e "manutenção". É uma metodologia usada com sucesso em outros ramos da engenharia, notoriamente na construção civil e manufatura, o que dá a ela certa credibilidade e facilidade de criar paralelos e metáforas, tanto para pessoal técnico como não técnico. O "waterfall" tem também outra grande vantagem: é muito fácil de ensinar, pois as etapas são precisamente definidas, assim como suas interfaces e que tipo de informação são passadas de uma fase para outra. Por estas razões, o "waterfall" atingiu altos níveis de popularidade, apesar de seus problemas.
No "waterfall", se uma fase deu errado, é sempre possível "apontar um culpado" em alguma fase anterior e resolver qualquer dilema. Em geral, a fase padrão para levar a culpa é a primeira, o levantamento. Por exemplo: o usuário não disse bem o que queria ou o analista que fez o levantamento não anotou direito. Ou seja, é "só fazer o levantamento direito que tudo dará certo na próxima vez". Ou algo parecido.
Se o waterfall é tão estudado e tão preciso, por que as coisas dão tão errado? Cada um tem uma opinião ligeiramente diferente, mas as minhas razões preferidas são as seguintes:
• É impossível capturar todas as nuances no levantamento. O usuário sempre se esquece de coisas – sem querer ou até mesmo de propósito. O analista não só não é um ser onisciente e telepata como na verdade está mais interessado em produzir um monte de documentos bonitos mesmo que sem utilidade real, já que são os outros que vão construir o software. Mesmo escalonar as prioridades, ou seja dizer o que é mais ou menos importante, é uma atividade que costuma ser ofuscada por preconceitos ou modas;
• Todo software tem alguma complexidade que só pode ser definida na implementação. Quase sempre estamos fazendo algo mais complexo do que antes e usando novas tecnologias. Isto traz inerentemente uma boa dose de risco, algo que devemos gerenciar ao invés de fingir que não existe. Por mais levantamento e projeto que façamos, eles nunca serão suficientes;
• Os negócios mudam. Eu um mundo de negócios cada vez mais dinâmico, é comum durante e execução de um projeto de software que as prioridades mudem e que as pessoas troquem de emprego. Mesmo que o levantamento seja executado 100% à perfeição – algo que considero simplesmente impossível – é muito provável que no momento da implantação aquele software perfeitamente desenvolvido não adéqüe-se mais às necessidades de negócio naquele momento.
As metodologias ágeis reconhecem que os problemas acima existem e procuram abraçá-los, de forma a conviver com eles. Existem vários métodos "ágeis", como por exemplo "Extreme Programming (XP)", "MSF/Agile" e "Scrum".
Pessoalmente eu estou cada dia mais interessado no Scrum, também apoiado por vários criadores do "Agile Manifest". Ao contrário de algumas técnicas ágeis, especialmente o XP, o Scrum inclui bastante planejamento, disciplina, responsabilidade dos integrantes da equipe e gerenciamento de riscos, em um pacote que faz sentido.
É perfeitamente possível trabalhar com Scrum sem nenhuma ferramenta de software, mas obviamente as coisas ficam mais fáceis se você tiver uma ferramenta para registrar as tarefas a fazer, as feitas e prioridades. Recentemente a Microsoft anunciou apoio ao Scrum e, com o apoio do Ken Schwaber (www.scrum.org), um dos "profetas" do Scrum, criou um template "Scrum" para o Visual Studio 2010. Isto, certamente dará um impulso extra a esta técnica na plataforma Microsoft.
O Scrum não é uma "bala de prata", pois exige mudanças culturais, tanto em quem contrata como em quem desenvolve. Ele exige que todos trabalhem em comum de forma a entregar alguma coisa que tenha valor ao negócio, substituindo o relacionamento antagonista e burocratizado tradicional.
Posted in Desenvolvimento de Software, Metodologia, Scrum | No Comments »
Todos certamente concordarão que os desenvolvedores devem ter um bom ambiente de desenvolvimento. Note que por "ambiente" eu estou falando do hardware e software que eles têm à sua disposição e não considerações de ergonometria – embora isso também seja importante. Já vi desenvolvedores empilhados em condições que os operadores de telemarketing chamariam fiscais do ministério do trabalho, apesar do salário dos desenvolvedores ser bem maior.
Na minha experiência, costumo ver os desenvolvedores usando computadores capazes e com boas ferramentas do tipo "ambiente integrado" como Visual Studio ou Eclipse. O problema é que o "ambiente de desenvolvimento" não acaba por aí e as coisas ficam mais complicadas.
Em primeiro lugar, considero essencial ter algum software de "controle de versão". Existem várias opções, desde o velho Microsoft Visual Source Safe, que apesar das limitações ainda é bem melhor que nada. Na plataforma Microsoft a versão mais nova do software de controle de versão é um componente do "Visual Studio Team System". Além de outros produtos comerciais, existem também opções gratuitas "Open Source" como o CVS ou o Subversion. O assunto "controle de versão" costuma hoje ser tratado como um tópico do "gerenciamento de configuração", mas não se sinta intimidado a estudar o assunto profundamente, pois o software de controle de versão é o componente básico e o mais importante de todos. Ou seja, mesmo que você não entenda muito de "gerencia de configuração", instale um controlador de versão.
Outro aspecto muito importante é desenvolver e testar em um ambiente o mais parecido possível com o ambiente de produção, desde que isso não atrapalhe o trabalho. Desenvolver em um ambiente próximo ao de produção evita muitos problemas no momento das primeiras implantações.
Alguns problemas comuns são os seguintes:
• Diferenças de idioma/cultura, por exemplo, desenvolver com Windows em Português e rodar sob Windows em inglês. Rodar sob sistema operacional inglês é típico em servidores Web, pois as atualizações de segurança saem antes em inglês do que em outros idiomas e, portanto um servidor Web em inglês é provavelmente mais seguro. Outro cenário é a hospedagem de aplicativos Web no exterior por questões de custo;
• Desenvolver com credenciais de administrador e rodar com credenciais de usuário limitado. É difícil rodar o ambiente de desenvolvimento em si sem ser administrador, pois o suporte à depuração seria perdido. Mas isto causa desde problemas sutis como falta de permissão de acesso à diretórios até impossibilidade de acesso à banco de dados. Na medida do possível os outros componentes como o servidor Web e o servidor de banco de dados devem ser rodados com contas mais limitadas, como "NETWORKSERVICE" por exemplo. Esta também é uma razão para não usar o servidor de desenvolvimento que vem com o Visual Studio e sim o Internet Information Server completo;
• Usar versões diferentes de servidores, como por exemplo de bancos de dados ou Web. Por exemplo, o IIS do Windows Server 2008 R2 é o 7.5, enquanto a versão usada em uma estação Windows XP seria a 5.1. Mesmo que elas sejam "supostamente idênticas", existem pequenos detalhes diferentes. Uma versão mais nova pode ter quebrado a compatibilidade com a versão anterior de propósito ou mesmo acidentalmente;
• Usar massas de dados em desenvolvimento diferentes das de produção, o que costuma trazer problemas de desempenho quando encontramos massas de dados grandes em produção.
Outro ambiente importante é o de homologação, que idealmente deve ser muito idêntico ao de produção, tanto sob o aspecto de que software está instalado como também de hardware, para ser possível fazer testes de carga. É muito comum os equipamentos de homologação acabarem sendo usados para outras tarefas secundárias como, por exemplo, back-up, visto que são máquinas boas que "não fazem nada o dia inteiro". Esta é uma tentação que se não puder ser resistida, deve ao menos ser mitigada, estabelecendo procedimentos como horários reservados para a homologação.
Volta e meia me perguntam sobre a possibilidade de decompilar programas .NET. Por "descompilar" entendo "produzir a partir de um executável um programa fonte em linguagem de alto-nível que, quando compilado, tem a mesma funcionalidade que o executável original". É importante observar que qualquer programa, em qualquer linguagem de alto nível é "descompilável" pelo menos em linguagem Assembly ou similar, até porque a própria CPU do computador tem que saber executá-lo.
É então possível descompilar programas .NET, de maneira semelhante ao que era possível com descompiladores para o Clipper como "Unclip" ou "Valkyre", que tanto transtornos causaram nos anos noventa? A resposta curta é sim. Mas continue lendo.
Uma das grandes vantagens dos "assemblies".NET (.EXE ou .DLL) é que eles rodam em um "ambiente gerenciado", onde os programas não podem causar danos aos outros programas rodando no computador do usuário. Este ambiente gerenciado depende basicamente do seguinte para funcionar:
Código executável definido em uma "linguagem intermediária – IL" ao invés da linguagem do processador. Este código pode ser "verificado" em tempo de carga e execução pelo compilador "JIT", de forma que o mesmo não possa efetuar operações não permitidas pelas configurações de segurança, como acessar um endereço de memória não permitido;
Informação de tipo em tempo de execução ("metadata") de forma a validar os "casts", chamadas de funções entre diferentes DLLs e manter a integridade do sistema de tipos;
A primeira compilação (VB ou C# para IL) não deve otimizar o código, pois as otimizações podem impedir que o compilador JIT verifique o código. A presença de otimizações tem o efeito colateral de atrapalhar os descompiladores.
Evidentemente, os fatores acima facilitam a descompilação dos programas. Note que estes recursos têm como efeito principal o aumento da segurança e integridade tanto para os desenvolvedores como para os usuários finais, o que é considerado hoje em dia uma grande vantagem. Por exemplo, a maioria dos erros no gerenciamento manual de memória dos ambientes tradicionais é eliminada. A robustez e a vulnerabilidade à descompilação também são características do outro grande ambiente gerenciado utilizado atualmente, o Java.
Dito isto, como impedir que um usuário do seu software possa descompilá-los? Existem várias maneiras:
Impedir o acesso aos executáveis. Um aplicativo web, por exemplo, roda em um servidor e os usuários não têm acesso aos executáveis. Mesmo um aplicativo desktop pode ter parte da sua funcionalidade em WebServices, que também rodam em um servidor.
Escrever parte do programa como código não gerenciado, quer como DLL, objeto COM ou mesmo em código não-gerenciado dentro de programas C++ .NET. Evidentemente isto elimina as vantagens do código gerenciado pelo menos em parte do seu programa.
Escrever parte do código em Assembler IL usando recursos que dificultam a descompilação, como o uso de identificadores não suportados pelas linguagens C# ou VB.NET, por exemplo, chamando uma função com o mesmo nome de uma palavra reservada de linguagem de alto-nível.
Usar um "ofuscator" para alterar o código de forma a impedir a descompilação.
Os ofuscadores (pesquise por ".NET obfuscators" na Web) são a maneira mais fácil e direta de proteger o seu código, pelo menos a níveis comparáveis aos de outras linguagens de alto nível como C/C++ ou Delphi. Basicamente eles processam os assemblies (.EXE/.DLL) e geram outros assemblies que tem a mesma funcionalidade, mas que são mais difíceis de descompilar.
Como isso é feito? Um dos truques é renomear os símbolos (funções, propridedades, campos etc) "private" de seus executáveis. Quando um programa .NET referencia um símbolo dentro do mesmo assembly, ele não o faz por nome e sim através de um índice em uma tabela. O nome é então supérfluo e pode ser trocado para identificadores repetidos ou mesmo palavras reservadas da linguagem, tornando o fonte descompilado impossível de ser recompilado. Alguns produtos possuem recursos bastante sofisticados e o resultado é uma proteção até maior que um programa Delphi ou C++.