Arquivo para categoria Uncategorized

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

Repositórios e Expressões Lambda

Esta semana fizemos mais uma grande melhoria na nossa camada de domínio, incorporando expressões lambda .Net nas nossas consultas e parâmetros de ordenação de repositórios. Retomando o post sobre a camada de domínio, os repositórios são utilizados para tirar a dependência da aplicação dos detalhes de persistência de objetos e para ser uma representação abstrata de uma coleção de entidades de domínio.

A idéia é que eles facilitem a busca de entidades específicas ou implementem métodos mais complexos para a execução de consultas. Como no nosso caso usamos o NHibernate para camada de persistência, nós temos duas opções de efetuar estas consultas, os Criterias (DetachedCriteria ou expressões ICriterion simples) ou o HQL, que é uma linguagem de consulta parecida com SQL só que composta pelas entidades de domínio.

Consultas HQL são baseadas em strings (ver exemplo abaixo do nosso sistema de ServiceDesk), o que é extremamente flexível porém não suporta intellisense nem é compilada (o que pode facilitar erros no caso de refactors). Mas, para o HQL não temos muita opção, a alternativa que seria usar o NH Linq ainda não é viável (pelo que eu tenho visto, ainda não suporta muitas coisas).


public int TotalInbox(User user) {
   const string hql =
       @"select count(*) from Incident i inner join i.Allocation a
         inner join a.SupportGroup s inner join s.Users u 
         inner join i.Company c
         where i.ClosedOn is null and a.SupportUser is null
         and i.State != isnull(c.WaitingUserConfirmationState,-1) 
         and i.State != isnull(c.WaitingUserInformationState, -1) 
         and u = ?";
   return (int) ExecuteScalar<long>(hql, user);
}

O uso de Criterias é mais simples e é indicado para consultas com restrições diretas na entidade base (ou nas que possuem relacionamento direto com a entidade base). Porém, nos criterias é necessário especificar o nome da propriedade como string. Novamente, sem intellisense e sujeito a problemas de refactor. Como o uso de Criterias é muito mais freqüente, nós automatizamos na nossa camada de domínio a geração de uma classe estática com todas as propriedades das entidades de domínio (usando arquivos .tt de um editor T4). Desta forma, temos intellisense e no caso de refactor que cause alguma quebra, teremos um erro de compilação (já que as classes são sempre regeradas). E, conforme falado no post da camada de domínio, construímos ainda uma fluent interface para facilitar a escrita. O exemplo abaixo mostra isto em funcionamento.

public long TotalClosed(User user) {
    return Query.Where(Restrictions.Eq(PN.User, user))
           .And(Restrictions.IsNotNull(PN.ClosedOn)).Count();
}

Esta solução estava bastante adequada até aparecer a alternativa de usarmos expressões lambda ao invés de gerar as classes estáticas. Existem algumas iniciativas já fazendo isto, como o projeto NHLambdaExtensions. Neste caso específico, porém, eles estão abordando isto como uma biblioteca à parte para a geração de Criterias do NH e não como algo integrado aos repositórios.

Felizmente, na nossa camada de domíno, os repositórios já são tipados para a entidade de domínio que eles representam. Desta foram, fica simples gerar as expressões. O exemplo abaixo mostra a mesma rotina acima, agora usando expressões lamdas.

public long TotalClosed(User user) {
    return 
      Query.Where(i => i.User == user && i.ClosedOn != null).Count();
}

Como pode ser visto, bem mais legível e intuitivo. E sem a necessidade de se usar classes estáticas de apoio! Ainda temos algum trabalho a ser feito, pois não é simples traduzir todos os tipos de lambda para restrições válidas. Mas para os casos mais simples como o acima, está já 100% funcionando.

Outro ponto interessante é que as funções que aceitam lambda podem ser expostos para camadas superiores de domínio, já que usar uma expressão lambda não causa dependência para a camada de persistência. Isto diminui de maneira significativa o próprio tamanho da implementação dos repositórios.

Finalmente, a utilização deste tipo de solução acaba sendo algo tão flexível que estamos passando a adotar em vários outros cenários. Na definição de classes de ordenação para consultas, na identificação de campos usados como atributos em formulários e controllers e assim por diante. Realmente algo muito simples que está aí desde o lançamento da versão 3.5 do .Net mas que demorou para  a “ficha cair” achar uma maneira legal de aplicar na nossa infraestrutura.

Quem quiser saber algum detalhe mais técnico da implementação basta me mandar um email. Até a próxima.

, , , , ,

Deixe um comentário

Response.Flush()

Nestes últimos 2 dias eu perdi um tempo impressionante com algo que em tese deveria ter sido extremamente simples de fazer, tipo 5 minutos…  A idéia era fazer um página que iria rodar uma operação longa ir mostrando o andamento da operação, algo como “Passo 1 executado”, “Passo 2 executado” e assim por diante…

Como a regra de negócio estava pronta, achei que fosse trivial ir gerando as tags <p> e ir mostrando o andamento com flushs… Não poderia estar mais errado! Inicialmente tentei usar o HtmlWriter do Render pra ir fazendo os Writes intercalados com os Response.Flush() (fiz um teste com Sleep() pra simular o processamento). Mas não funcionou, ele mostrava a página só no final, com todos os passos de uma vez.

Aí comecei o processo conhecido de buscar no google alguma dica ou esperiência pra entender o que estava errado. Nem precisa falar que o help da MSDN era inútil, aliás copiei e colei o exemplo deles e mesmo comportamento. Comecei a ver que este é um problema para muitas pessoas, aparentemente em algumas situações o Response.Flush() simplesmente não funciona e um mesmo código que funciona para um (como o exemplo da MSDN) não funciona pra outros.

Claro que deve ter algo na página ou no ambiente que faz com que este probelma apareça. Gastei umas boas 4 horas tentando eliminar o que era, utilizando as dicas que achei de pessoas no google para tentar mapear o que era. Mas a questão é que parecia que vários tipos de problemas acabavam se sobrepondo, o principal sendo um próprio entendimento do que o Flush() deveria fazer. Na minha visão (e na visão de várias pessoas que eu vi), ele deveria simplesmente fazer com que o conteúdo gerado até ali fosse para o browser. Mas até sobre isto haviam dúvidas. E aí vinham várias receitas, pra ligar ou desligar buffer, pra fazer com código <% %> intercalado na página ou em determinado evendo em code-behind e até para fazer várias vezes em sequência o comando Flush() para que ele funcionasse! Nenhuma alternativa funcionou pra mim, fui dormir para tentar de novo no dia seguinte.

No dia seguinte, mais 2h. O tempo gasto nisto já estava absurdo e poderia até ter feito com javascript simples, mas vocês sabem, vira questão de honra!  Continuando as busca no google, achei um comentário dizendo que uma instrução específica, faria toda a diferença: Response.BufferOutput = false. E neste cenário, realmente funcionou, mas somente no código aspx direto! Já que neste caso estava funcionando, comecei a tentar isolar o que realmente causava o probelma. Mas não tive sucesso, qualquer pequena alteração fazia com que o código deixasse de funcionar. Desisti, o código final ficou desta forma:

—————————————————————————————————————–

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”  “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”><html  >
<head><title>Correçao de Pesquisa</title></head>
<body style=”font-family: Calibri, Tahoma, Arial”>
<p>Correção em Progresso. Aguarde por favor….</p>
<%  Response.Buffer = false;
Response.BufferOutput = false;
for (var i = 0; i < 10; i++) {
%><span>teste</span><br /><%
Response.Flush();
System.Threading.Thread.Sleep(1000);
} %>
</body>
</html>
—————————————————————————————————————–
Impressionante que este código não funciona se for colocado no evento Load ou Render da página. De fato deve ter alguma coisa no ambiente que impede isto, mas tive que dar um basta no tempo perdido para este problema. Ah, mais um ponto interessante, a tag SPAN funciona melhor do que a tag P – que mesmo com o código funcionando dá uma impressão de agrupamento ao ser mostrado no browser.

Enfim, é impressionante como perdemos tempo com coisas triviais. Esta do Response.Flush é mais um exemplo. Fazer software é muito bom, mas este tipo de coisa não é muito!

, , , ,

3 Comentários

Olá!

Bom, depois de vários anos de resistência finalmente resolvi iniciar um blog. Não que eu não goste de escrever, justamente ao contrário, mas sempre pensei que não teria muito a contribuir às centenas de milhares de blogs já existentes…. E não acho que fazer algo repetindo o que já existe é uma tarefa que justifique que pessoas percam tempo lendo o que eu escrevo!.

Mas ultimamente eu tenho achado que tenho a contribuir em alguns aspectos. Na parte técnica (para os que não me conhecem, sou arquiteto de software;  desenvolver sistemas é o que mais gosto de fazer… minha plataforma atual é .NET 3.5), eu estou pensando em colocar aqui coisas que são interessantes ou receitas para evitar que outros percam tempo com algo que eu tive que perder – e como todos da área sabem, isto é extremamente comum e frustante!

Este não é um blog pessoal (até porque não acho que valha a pena deixar tão publico aspectos pessoais de nossas vidas! rsrs), porém às vezes eu vou colocar aqui itens que eu achei interessantes e que merecem ser compartilhados, mas não se preocupem: sem ctrl-c ctrl-v!

Espero contribuir de alguma forma e quem quiser entrar em contato comigo, basta me mandar um email.

Deixe um comentário