Posts Marcados Framework

De volta!

Oi pessoal! Longo tempo sem postar! Nos últimos meses acabamos ficando extremamente ocupados na White Fox, graças à coincidência da finalização de um grande projeto de um dos nossos maiores clientes com a finalização e o lançamento de mais um produto com a marca White Fox. Felizmente tudo correu excepcionalmente bem, apesar de ter dado muito trabalho e ainda estarmos trabalhando em um ritmo acima do normal. E, felizmente ou infelizmente (depende do ponto de vista), tudo indica que o ritmo este não vai diminuir em curto prazo, já que estamos com algumas iniciativas em andamento que, se concretizadas, irão significar mais um grande esforço adicional.

O projeto cuja primeira entrega foi no final do ano passado, representa o resultado de quase um ano de trabalho. Nele, tivemos que desenvolver um novo mecanismo de comunicação com o Banco Central do Brasil (BACEN), baseado em troca de mensagens e em substituição a um antigo formato baseado em emulação de terminais (sim, isto ainda existe!). O projeto foi de âmbito nacional e envolveu todos os bancos e corretoras de câmbio do país. A segunda fase do projeto está em andamento neste primeiro semestre e deve consumir esforço até meados deste ano. Por ser uma área de infraestrutura (mensageria), fizemos praticamente tudo utilizando o Web Service Factory, da Microsoft, que facilitou enormemente a criação de mensagens e serviços. As mensagens do BACEN são artefatos XML, o que nos fez utilizar XSLT para a geração e transformação das mesmas. As nossas escolhas permitiram que tivéssemos um desenvolvimento rápido e uma grande facilidade de manutenção, o que foi crucial para finalizarmos tudo a tempo. Estamos mantendo estas escolhas para esta segunda fase e, graças a elas, estamos adiantados no nosso cronograma.

O segundo grande evento foi a finalização da plataforma da XChange. Este produto é um site de comércio eletrônico de Internet, destinado à venda de cartões pré-pagos VISA Travel Money (VTM) para quem viaja ao exterior a turismo ou trabalho, no qual tenho participação. A White Fox foi chamada a fazer um software que funcionasse com o site estático desenvolvido por uma agência de propaganda. O desafio foi criar mecanismos que permitissem trabalhar as áreas dinâmicas do site sem prejuízo para o layout e para as funcionalidades de navegação. Para atender a este objetivo, tivemos que fazer uma evolução significativa no nosso framework de interface. O resultado foi melhor do que esperávamos, e agora o nosso framework suporta a integração em qualquer layout HTML, com um mínimo de esforço.

O princípio que utilizamos foi uma evolução do funcionamento anterior da nossa engine MVC, que era gerar HTML através de transformações XSLT. Nesta nova versão, ao invés de gerar a página inteira, nós somente geramos trechos da página. Assim, podemos apontar um determinado <DIV> em um HTML e ele é substituído, em tempo de renderização, por um <DIV> de conteúdo dinâmico. Isto facilita a construção e a visualização de páginas, permitindo a “injeção” de trechos dinâmicos nos arquivos HTML provenientes das agências, praticamente sem modificações nos mesmos (nem mesmo os famigerados <% %> das engines tradicionais MVC). O resultado foi excepcional e graças a esta nova versão, somos capazes de gerar sistemas de maneira ainda mais rápida.

Espero voltar a escrever posts com uma regularidade mínima. No próximo, vou falar um pouco sobre os desafios que enfrentamos recentemente com desenvolvimento para alto desempenho, com paralelismo em SQL Server. Até a próxima!

, , , , , ,

1 comentário

Log de Negócio

Esta semana tive uma necessidade de log específica em um de nossos sistemas, que acabou gerando uma excelente adição para o nosso framework de desenvolvimento. A necessidade era saber o que acontecia em produção que acabava gerando um bug raro de valores no final do dia, e que fomos incapazes de reproduzir mesmo com uma grande quantidade de testes unitários. Aparentemente o bug está associado a uma condição de multi-usuário que é muito complicada de reproduzir. Para resolver este bug precisaríamos saber a seqüência exata em que as operações foram realizadas, e isto só seria possível com log.

A necessidade de log de negócio acaba surgindo vez por outra em aplicações. E, praticamente para cada sistema que eu já participei, foi feita uma solução diferente para log, com vantagens e desvantagens. Alguns usam log em banco, colocando triggers nas tabelas e replicando as informações, o que é extremamente simples de fazer mas gera grandes problemas de contenção e espaço utilizado. Outros usam versões do log4net gerando dados em arquivos, o que também é relativamente simples de fazer porém gera também dificuldade em ambientes massivamente multi-usuário – sem falar na dificuldade de processar os arquivos depois. Já fiz também log em banco, com e sem log4net, com bons resultados, mas sempre com uma solução específica para cada caso, o que causava um bom esforço de manutenção.

Outro ponto que sempre me incomodou é a questão da intrusividade das funções de log na regra de negócio. Tirando a solução em trigger de banco, qualquer implementação de log4net foi sempre feita com chamadas específicas de log dentro da rotina de negócio. Isto polui a rotina e dificulta a manutenção. Eu sempre tentei criar algo tipo AOP, mas nunca consegui uma solução boa. Mesmo atualmente, as bibliotecas conhecidas de AOP (PostSharp, Spring.Net etc.) não são uma boa opção para o nosso ambiente por serem um framework completo, de grande impacto…. Usar qualquer uma delas só pra log de algumas regras de negócio pra mim seria usar um canhão pra matar uma mosca.

Assim, resolvemos desta vez fazer algo decente, já incorporado ao framework, e que usasse uma abordagem AOP na medida do possível. Graças à tecnologia do Castle Windsor IoC usada atualmente no framework, isto foi relativamente simples de ser feito. Definimos na nossa arquitetura que o log de uma regra deveria ser expresso através da observação de parâmetros e retornos da função, antes e depois dela ser executada. Através do uso destas condições pré e pós, é possível identificar exatamente como aquela função afetou os dados.

Para implementar, o que fizemos foi usar o log4net para salvar eventos em banco. Até aí, solução padrão. O passo seguinte foi definir atributos AOP para marcar uma regra de negócio como sendo logada. O ideal teria sido definir as condições pré e pós no próprio atributo, porém o C# atualmente não suporta nada que não seja estático nos atributos; e usar strings eu acho uma prática ruim. A solução usada foi definir um tipo para o atributo que apontasse para uma classe que definiria quais são todas as condições, utilizando lambda.

O resultado ficou excelente. Abaixo está um exemplo do atributo na regra de negócio:

[Log(typeof(AtualizarValorDePosicaoLog))]
public void AtualizarValorAnterioDePosicao(Contrato contrato, 
                                    Posicao posicao, decimal valor) {
 

E no tipo de definição das condições, fica assim:

public class AtualizarValorDePosicaoLog : LoggerBase {

  public AtualizarValorDePosicaoLog() : base(
    Properties.PreCondition("valor"),
    Properties.PreCondition<Contrato>(
      c => c.Id, c => c.Tipo, c => c.TipoBacen, 
      c => c.Moeda, c => c.Posto, c => c.ValorMoedaEstrangeira, 
      c => c.ValorMoedaNacional, c => c.ValorUSD, c => c.TipoPagamento),
    Properties.PreCondition<Posicao>(
      p => p.Id, p => p.ValorPosicaoAnterior, p => p.Conformidade, 
      p => p.Baixa, p => p.Transferencias, 
      p => p.TotalCompra, p => p.TotalVenda, p => p.Moeda, p => p.Posto, 
      p => p.Tipo),

    Properties.PostCondition<Posicao>(
      p => p.Id, p => p.ValorPosicaoAnterior, p => p.Conformidade, 
      p => p.Baixa, p => p.Transferencias, 
      p => p.TotalCompra, p => p.TotalVenda, p => p.Moeda, p => p.Posto, 
      p => p.Tipo)) { }
    }
 

Na execução, o interceptor da classe de serviço busca o atributo, instancia o tipo de definição e coleta os dados, antes e depois da rotina executar. Para minimizar o impacto em tempo de execução, o logger simplesmente armazena um dicionário com todas as condições recolhidas, serializando num XML. Posteriormente, de maneira assíncrona e com baixa prioridade, um executor analisa os registros de log gerados e expande cada condição em tabelas do tipo dicionário.

Com isto o impacto ficou bem pequeno e conseguimos fazer algo quase puramente AOP e sem nenhuma definição em string! Finalmente conseguimos uma implementação boa para log, que deve nos atender por muito tempo.

Nesta solução, alem da equipe da WhiteFox, tivemos a colaboração do arquiteto Fernando Bichara, da Perlink.

, , , , ,

4 Comentários

White Fox: O Conceito

Nestes mais de 15 anos de carreira, meu sonho sempre foi ter meu próprio negócio, uma empresa de desenvolvimento de software que fosse algo diferente e reconhecida pela qualidade do seu pessoal e de seus produtos. Nestes anos, eu tive algumas empresas, todas buscando atingir esta meta, porém, por várias razões, nenhuma delas chegou a atingir este ideal.

Sonhos não morrem, eles permanecem no inconsciente e em momentos propícios, voltam com toda a força. E mais uma vez, está chegando a hora de tentar de novo e atingir o meu ideal. Estou na fase de concepção de uma nova empresa, a White Fox Consultoria e Desenvolvimento de Software. Neste post quero falar um pouco sobre o que estou buscando, quais as motivações e que valores eu estou trazendo para esta nova empresa.

Desta vez acho que tenho grandes chances de atingir meu sonho. Em todos estes anos, eu tive a oportunidade de ver o que funciona e o que não funciona na gestão de uma empresa de desenvolvimento, tanto em aspectos de relação interpessoal quanto na parte de resultados e controle. Acredito que esta experiência, acumulada com muitos erros e acertos (quero crer que tenham sido mais acertos do que erros), é essencial para que a White Fox possa ter sucesso.

Uma das lições mais importantes que eu aprendi é que para que uma pequena empresa tenha sucesso, os seus sócios devem fazer mais do que gerir. Não tenho dúvida que administrar bem em todos os aspectos (especialmente o financeiro) é fundamental para o sucesso. Porém isto não é nem de longe o suficiente. Pois por melhor que seja, um bom gerente administrativo não é capaz de trazer aquilo que cada vez mais eu acho que seja o mais importante: a paixão pelo que se faz, a inspiração para si e para seu time de fazer o melhor e buscar o melhor sempre, o orgulho e o prazer de se estar fazendo algo excepcional. E tudo isto só é possível quando o líder consegue ser a representação disto para todo o time; desta forma ele tem que ser (ou pelo menos ter sido) antes de tudo, um excelente técnico.

Assim, a White Fox está sendo concebida com o melhor de todos estes mundos. A paixão por desenvolvimento e tecnologia é o que move cada integrante da nova empresa. A gestão transparente e minimalista garante que todo o esforço seja voltado para o negócio da empresa, que é fazer bom software para seus clientes. E um time ultra-selecionado, com os melhores profissionais da área produz a mistura que irá permitir que ela tenha muito sucesso.

A White Fox traz alguns conceitos pouco usuais na nossa área. Um deles é que o time seja realmente formado por somente arquitetos/seniores, do tipo que é capaz de fazer um sistema do zero em pouco tempo e que é capaz de atuar em todos os aspectos de um sistema, do banco de dados à interface, passando pela gestão de atividades e pela interação com o cliente. A excelência técnica e o pragmatismo são as características mais relevantes dos membros do time da White Fox. Outro conceito é que cada integrante é um sócio na empresa, sendo responsável pelas decisões da sua alçada e recebendo uma parcela do resultado geral do negócio. Finalmente, iremos buscar um ambiente de trabalho extremamente agradável, sem nenhum tipo de burocracia desnecessária. A idéia é fazer da White Fox o local ideal de trabalho para um desenvolvedor.

O formato de desenvolvimento é o agile. Fortemente baseado no Scrum, mas sem ser Scrum, a empresa irá ter como missão produzir com software com ROI extremamente vantajoso para os seus clientes. O formato implica também uma certa maturidade do cliente. Contratar no formato agile significar que o cliente é também parte do desenvolvimento e o sucesso de qualquer projeto é diretamente proporcional à qualidade e envolvimento do pessoal do cliente. Claro que este formato não é para todos, mas para os que se encaixarem neste perfil, a recompensa será software sendo desenvolvido de maneira rápida e com um ROI excepcional.

Outro diferencial é emprego de um framework de desenvolvimento em todos os produtos construídos. Este framework tem sido evoluído ao longo de vários anos e agora está maduro o suficiente para permitir o desenvolvimento incrivelmente rápido de sistemas sem nenhum sacrifício de usabilidade ou manutenabilidade. O uso e padronização do framework no desenvolvimento da White Fox facilita também o treinamento de pessoal e a manutenção de todos os sistemas produzidos. E, pela qualidade das pessoas do time, o framework vai sendo evoluído a todo tempo para permitir ainda mais velocidade e qualidade final.

A empresa será lançada oficialmente no início do ano que vem. Extra oficialmente ela já está a todo vapor, o time inicial está definido e ela já tem faturamento suficiente para garantir o início das operações. O web site está sendo construído para representar todos estes valores e os clientes estão sendo apresentados à esta nova forma de trabalho (com muito sucesso até agora!). Antes que perguntem sobre o nome, Fox é uma palavra de relevância especial para mim, ligada à agilidade que quero representar. A cor branca transmite simplicidade, clareza e transparência. O logo final está abaixo:

 

logowhitefox

 

Se você se identificou com este sonho e quiser fazer parte deste empreendimento, me mande um email. O time inicial está pronto, mas a perspectiva é de crescimento rápido. Aguardem então para mais notícias sobre o andamento desta nova empresa!

, , , , ,

3 Comentários

Produtividade – Camada de Interface Parte 1

Em mais um post sobre a série sobre produtividade, vou escrever sobre a camada de interface. Por interface eu me refiro à web, já que é raro nós termos grandes desenvolvimentos de aplicativos Windows – e mesmo nestes casos não é algo problemático, o desenvolvimento em Windows Forms do .NET é bastante tranqüilo para aplicações de pequeno porte. Intrefaces baseadas em serviços também são super simples para serem construídas, ainda mais usando a WCF Factory. Assim, o foco é a construção de páginas web. Para não tornar este post muito longo, eu o dividi em duas partes.

Na minha experiência, o desenvolvimento de interfaces web é onde se gasta mais de 90% do tempo de desenvolvimento e manutenção de qualquer sistema de médio ou grande porte. É também onde a evolução tecnológica se faz mais sentir, a disseminação de uso do AJAX, por exemplo, mudou completamente o modo como se desenvolve para web. E para os usuários, a qualidade da interface e navegabilidade muitas vezes é um dos maiores fatores de sucesso ou fracasso de um sistema, fazendo com que o investimento nestes artefatos seja primordial.

Para ilustrar o que busco, vou começar descrevendo o que pra mim é o pior cenário possível para interfaces. Tenho certeza que quem desenvolve para web já viu algo assim em algum momento da carreira. Todo sistema começa bem e o ASP.NET WebForms ainda é o método mais comum de construção utilizado. Assim, no início da vida do sistema, as telas são feitas de maneira mais ou menos rápida. Porém com o tempo, os usuários pedem evoluções para suportar algo pouco usual, um ou outro desenvolvedor menos experiente acaba colocando sua “contribuição” para as telas e o que antes era simples se torna extremamente complexo. Depois de alguns anos (ou meses, dependendo do sistema), o que temos é uma coleção de aberrações, cada tela com código específico, com coisas indo pra sessão outras para viewstate, código inline (com o famigerado <% %>), regras de negócio em .cs de páginas (ou ainda, pesadelo dos pesadelos, no mais famigerado <% %>). Se o sistema foi portado do ASP então, a visão dantesca se completa, pois nestes caos é difícil encontrar qualquer coisa minimamente estruturada. O uso de componentes de terceiros ou frameworks só complica, pois também tendem a gerar ainda mais telas fora do padrão, com todos os tipos de “puxadinhos” imagináveis. Ou seja, em casos como este é muito mais fácil refazer a aplicação do que tentar arrumar. Porém quando se resolve reconstruir, o ciclo se repete e daqui a alguns anos (ou meses!) está tudo como era – normalmente deixando mais um legado para se manter, para a infelicidade de quem ficou.

Como resolver isto? Como desenvolver rapidamente e ainda assim gerar sistemas que não se autodestruam com a manutenção/evolução? A solução que eu uso são frameworks de interface que tentam garantir a estruturação das interfaces de uma maneira que facilite que os desenvolvedores fiquem em um padrão pré-estabelecido e ao mesmo tempo tentando gerar o máximo de flexibilidade possível. Nesta linha, eu tenho sistemas desenvolvidos há quase oito anos que continuam bem estruturados. Naquela época a amarração era tão forte que as telas produzidas eram muito simples, gerando sistemas de usabilidade ruim, comparando com os atuais. Porém existem vários operando até hoje que são simples de manter e (até hoje) de evoluir. De lá pra cá a evolução do framework já permite gerar telas extremamente amigáveis, mantendo ainda os níveis de manutenabilidade originais. Claro que esta não é uma solução para qualquer empresa ou time, o nível de treinamento e envolvimento com o framework é muito alto para ser facilmente replicável. Mas no nosso caso está sendo muito bem sucedido.

O framework utiliza um tipo de padrão MVC, porém com uma separação clara em 4 componentes: 1) Estruturas de Interface – aqui entram caixas de texto, checkbox, botões, listas etc. São itens que contém os dados sendo apresentados e que serão manipulados pelos usuários. 2) Layout – que é como as estruturas de interface são mostradas em tela. No layout entra toda a parte visual como estilos, manipulação visual (via jQuery por exemplo), controles, figuras e até coisas como uso de janelas popup ou chamadas AJAX. 3) Dados – utilizando um conceito que também utilizado no Microsoft Sharepoint, definido em uma ilha de dados XML que contém todas as informações que serão utilizados pela interface. 4) Controllers – controladores da interface, onde os dados são construídos e as ações executadas, fazendo uso das entidades de domínio e chamando os serviços da mesma.

Separando desta forma, fica fácil notar quais elementos são afetados quando há uma mudança, fazendo com que a mesma impacte o menos possível os demais. Esta estruturação faz com que o desenvolvimento de novas telas seja concentrado em 2 pontos, na definição de estrutura de interface e nos controllers. A clara separação existente evita que uma área afete outra.

Na minha experiência, o Layout é um dos pontos que mais evoluem na interface. Embora em linha gerais ele fique estático (p. ex., pode se definir que o sistema vai ter um cabeçalho com o nome do sistema, usuário logado e menu; no meio com uma área de formulários e listas e com inclusões em popup, tudo usando Ajax), as pequenas modificações acabam sendo freqüentes. É a inclusão de um novo elemento no cabeçalho, o suporte de uma lista hierárquica, um novo tipo de componente e assim por diante. Para garantir que não aja uma mistura de responsabilidades, eu uso XSLT para a definição de todos os artefatos de layout. Este é um dos pontos de maior dificuldade de aprendizado no framework, já que não é usual que desenvolvedores usem diariamente XSLT. Mas, como falei no post sobre princípios, o XSLT é uma linguagem declarativa que evita o uso de código imperativo e o uso de artefatos como sessão, viewstate etc. E uma vez dominado, o XSLT é extremamente eficiente para se gerar o HTML final (sem falar que já gera o HTML correto!).

Para gerar o HTML final, os arquivos XSLT de layout utilizam duas fontes de transformação: os dados e a estrutura de interface. Isto já faz com que os dados tenham que ser facilmente descritos em XML. Eu vou a um ponto mais extremo, fazendo com que todos os nossos dados sejam descritos somente em XML – também como é feito no Microsoft Sharepoint. Com isto, minimizamos o uso de objetos DTO e tornamos a estrutura de dados da interface completamente maleável e fácil de evoluir.

Finalmente, a estrutura de interface também deve ser descrita em XML, para que seja facilmente transformável. O que fizemos foi criar uma DSL, integrada ao Visual Studio (com intellisense, claro), para descrever cada elemento de interface. Vejam como fica um exemplo simples de um formulário de login:

Exemplo de DSL de Interface:

<Form defaultFocus="Login">
     <Field data="Login" type="textbox" required="true" label="Login"  />
     <Field data="Senha" type="textbox" required="true" label="Senha"  password="true" />
     <Command label=”Logar” action=”Login”/>
</Form>

Exemplo de XSLT de Layout (super reduzido para efeito de ilustração):

<xsl:stylesheet version="1.0" >
     <xsl:template match="Form">
          <html>
                <body>
                     <form method="post">
                          <xsl:apply-templates select=”Field|Command” mode=”Control”/>
                     </form>
                 </body>
           </html>
      </xsl:template>
</xsl:stylesheet>

No XSLT acima, cada Field é transformado em um input box e o Command em um button. Percebam que não há código inline – não existe o <% %>. Este tipo de arquitetura era muito dificil de ser construída e mantida no ASP.NET Webforms, o que tornava o framework bastante complexo. Felizmente com o advento de bibliotecas MVC, isto ficou muito mais simples. Inicialmente, criamos  uma View Engine para suportar esta DSL no Castle Monorail. Com o advento posterior do ASP.NET MVC, criamos uma a View Engine para ele que funciona com exatamente a mesma DSL e os mesmos arquivos de layout. Esta migração mostrou a capacidade de evolução do framework, o que me deixa tranquilo para encarar a manutenção dos nossos sistemas por, quem sabe, outros 8 anos por vir.

No próximo post vou explicar como as ações são executadas e entrar nos detalhes dos controllers, mostrando como isto tudo se integra.

Até breve!

, , , , , , , , ,

1 comentário