Se você não sabe ainda o que é o projeto “Quanto é”, leia isso aqui primeiro.
Muita gente se empolgou com o projeto QuantoEh, e minha ideia é trazer para cá um pouco de como ele surgiu e explicar ele tecnicamente.
Esse post é o primeiro de uma série, que não sei ainda quantos posts vai ter. O QuantoEh usa Azure, Boo, TPL, LINQ to Twitter, DDD, BDD e vários outros conceitos e tecnologias, e a ideia é explicar pelo menos um por post.
Neste post vou abordar a modelagem inicial do sistema, que sem dúvida foi algo que demorou a sair.
O projeto iniciou no TechEd 2010. É comum que o pessoal do .Net Architects se reuna para fazer algum projetinho durante os eventos de tecnologia, e a ideia surgiu de novo. O Felipe Rodrigues estava junto e se animou também. A ideia era fazer algo com Azure, já que o TechEd estava propondo isso. Queríamos terminar até o segundo dia do evento. Olhando pra trás eu dou risada, não tínhamos ideia do tamanho do desafio.
O Vinicius Quaiato trouxe a ideia de fazer uma “calculadora social”, que é o que o QuantoEh virou. Até aí, tudo muito fácil. O difícil começou quando sentamos para definir como seria o aplicativo.
O Felipe e eu somos conhecidos por falar frequentemente sobre DDD, ele, inclusive, a mais tempo do que eu. Quem é da comunidade Microsoft não o conhece tanto, mas no lado de Java ele já trazia o assunto há um bom tempo. Naturalmente o sistema seguiria por esse caminho. Como o foco era aprender, nada como pegar um sistema essencialmente não visual (não tem interface gráfica) e aplicar um conceito de DDD para ver como ele funcionaria. (Se você não sabe o que é DDD, veja este vídeo com uma palestra que ministrei ao .Net Architects em 2008).
E foi um desafio. Como bons agilistas, começamos com as especificações, usando StoryQ. Depois eu volto a falar do StoryQ, que vai merecer um post só pra ele, nesse momento vou focar no DDD. Tentamos escrever algumas especificações, tínhamos dois pares para iniciar no código. Aí começou o problema. Não concordávamos nas histórias, não concordávamos no modelo, não concordávamos nos limites do domínio. O Felipe e eu gastamos as 4 últimas horas do TechEd discutindo isso, e não concluímos.
Só fomos concluir no RubyConf, onde continuamos o projeto, cerca de um mês depois, com ajuda do Felipe e do VInicius. Aí o projeto evoluiu, eu segui com ele no Google Developer Day, onde o Felipe deu uns pitacos, e eu terminei ele em casa porque eu não aguentava mais ver ele pela metade.
Qual foi a dificuldade? A principal foi a fronteira do domínio. Tínhamos algumas entidades identificadas, como o tweet recebido e que seria processado, e o retweet para enviar. Eles são objetos de domínio. Mas haviam vários outros objetos que não tinham papel definido. E essa discussão nos tomou muito tempo.
Nos parecia claro que o WorkerRole do Azure estaria na camada de interface com o usuário, ainda que essa interface não fosse gráfica. A fila de cálculo e a fila de retweet nos pareciam repositórios, mas isso não estava claro. E o timeline e as menções do twitter, onde postaríamos as respostas e obteríamos os tweets que mencionavam o quantoeh pareciam repositórios também, mas isso não estava claro. Definir este papeis era muito importante, porque influenciaria nossas especificações, nossa arquitetura e nosso design. Paramos de escrever qualquer especificação com BDD até termos isso definido. E foi essa discussão que levou algumas horas, e evoluiu muito nosso conhecimento do negócio e sobre como modelar tudo de maneira que fizesse sentido.
Um breakthrough aconteceu quando descobrimos que, na verdade, o timeline e as menções não eram repositórios, mas parte da camada de interface com o usuário. Eles pareciam repositórios porque era através deles que chegavam e saiam os tweets, e repositórios tem essa característica de obter e guardar objetos de domínio. Mas, na prática, não era isso que nosso domínio nos apresentava. Os tweets chegavam de uma fonte externa para serem processados, eles estão fora da aplicação. Sua entrada na aplicação se dá de forma muito semelhante ao input feito por um usuário via interface gráfica, se esse fosse um sistema que tivesse telas de input. Quando ficou evidente que as menções eram um componente da camada de interface com o usuário, nossas especificações começaram a mudar. Da mesma forma, descobrimos que a timeline se comportava de forma muito parecida. É como se ela fosse a tela que mostra o resultado do cálculo, só que ela faz isso pela interface do twitter, não da nossa aplicação. Ela representa uma saída para o usuário, não um repositório onde salvamos tweets processados. Ter percebido isso facilitou muito nossa visão.
As filas de cálculo, ficou evidente depois, são repositórios. Vou voltar nelas, mas em um post futuro.
Neste post meu objetivo é deixar claro que pensar sobre o domínio é fundamental antes de escrever especificações, sejam com código ou com papel. O QuantoEh evidenciou que nem tudo que salva ou obtém dados é um repositório como muitas pessoas pensam. O mais interessante é que a timeline e o as menções depois foram implementadas por um data access object (DAO), e são componentes de interface com o usuário, contrariando o que muitas pessoas entenderiam como o correto. Você pode ver a última versão do código do DAOTwitter no BitBucket.
Eu sempre digo que DDD não é entidades + repositórios, que não é uma nova forma de pensar em forms over data. O QuantoEh confirmou isso nas primeiras horas do projeto.
Nos próximos posts eu sigo discutindo arquitetura e já devo entrar nas especificações com BDD. Até lá.
Giovanni Bassi
Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.