LazyWeb: Escolhendo um framework

November 11th, 2009 § 7 comments § permalink

Um amigo de Belo Horizonte me consultou esses dias sobre uma questão fundamental para a aplicação que ele está planejando começar a escrever nos próximos dias: framework de programação usar (e por extensão, qual linguagem)?

Como minha experiência nos últimos tempos tem sido confessadamente restrita a Rails e alguns experimentos em outros, resolvi apelar para a caridade dos meus leitores. Qual framework você usaria para seu próximo projeto?

Esse meu amigo não tem problemas com linguagens de programação em si. De fato, a não ser que seja algo tão esotérico quando Haskell ou Erlang, ele é capaz de se familiarizar com uma linguagem ou framework em alguns dias.

Obviamente, não posso dar muitos detalhes sobre a aplicação, mas dá para dizer que o objetivo é escalar gradualmente. Ela não precisar começar escalando para o mundo inteiro, mas um caminho seria bom. Um outro detalhe nesse aspecto é que a aplicação é comparativamente particionada: um usuário terá acesso a alguns itens e compartilhará esse acesso com algumas dezenas ou centenas de pessoas. Esses itens possuem moldes variáveis e seriam bom ter flexibilidade na criação do mesmos.

Finalmente, hospedagem é uma questão também. Não necessariamente preço, mas facilidade. Linode é uma opção mas preferivelmente algo que possa ser colocado em alguma coisa pequena e ir escalando conforme a necessidade, no estilo do Heroku (o que limitaria a Rails, claro). Python parece uma boa opção, mas ele precisa de evidências.

E aí, alguém anima a ajudar um pobre compadre em armas? :D

Sinergia Arquitetural

October 27th, 2009 § 3 comments § permalink

syn•er•gy |ˈsinərjē|
noun
the interaction or cooperation of two or more organizations, substances, or other agents to produce a combined effect greater than the sum of their separate effects

— Apple’s Mac OS X Dictionary

A definição acima não é muito padrão mas expressa bem o conceito em que a palavra é entendida hoje em dia. Sinergia vem do grego sunergos, que literalmente significa trabalhar em conjunto.

Em inglês, a palavra data de cerca de 1650, e tinha um sentido bastante medicinal, podendo indicar tanto a ação cooperativa entre dois ou mais músculos do corpo para a realização de um esforço ou a ação combinada de medicamentos ou drogas para criar um estímulo maior no paciente.

O Wikitionary define sinergia também com o “comportamento de um sistema que não pode ser previsto pelo comportamento de suas partes”, o que é uma definição bastante interessante e diversa do sentido necessariamente positivo que a palavra ganhou nas últimas décadas.

De fato, sinergia hoje em dia é considerada uma buzzword, uma palavra sem significado para indicar a vontade de que algum esforço conjunto qualquer resulte em mais lucro, para qualquer valor de lucro, do que um esforço individual das partes envolvidas–a palavra-chave na mudança de definição aqui sendo “vontade” versus o efeito real.

No meu trabalho com arquitetura de software, entretanto, sinergia é algo que faz sentido naturalmente no desenho de sistemas. De fato, sistemas de sistemas tender a exibir isso de uma forma quase que óbvio já que não é possível desenhar os mesmos de outra forma. Não é sem motivo que a página na Wikipedia que explica o conceito usa sinergismo, uma variação de sinergia para explicar a motivação primária desse objetivo. O Unix é um exemplo bem óbvio disso e algumas pessoas chegam a se referir a isso como o Tao do Unix pelo fato de que as peças se encaixam com tal perfeição que é impossível pensar em trabalhar de outra forma.

Sistemas de sistemas fazem sentido em praticamente qualquer situação em que a complexidade das partes individuais torne o sistema final potencialmente (e exponencialmente) difícil de ser descrito de maneira consistente.

Essa é uma das razões, inclusive, pela qual as pessoas se decepcionam tanto com frameworks como Rails ou Django quando precisam de expandir aplicações já existentes para níveis maiores de complementaridade ou escalabilidade. Frameworks fechados simplesmente não exibem esse tipo de sinergia integral necessária para garantir que os princípios aplicáveis em aplicações menores sejam os mesmos de aplicações maiores. O resultado é que, essencialmente, todos esses princípios são violados à medida que o sistema precisa crescer resultando em um entendimento completamente diferente do que se desejava a princípio. Funciona, mas sem elegância ou beleza.

A despeito do significado amortecido, uma reflexão cuidadosa sobre sinergia e sua aplicabilidade ao desenho de sistemas faria bem a qualquer desenvolvedor ou arquiteto de sistemas. Sapir-Whorf sendo fraca ou não, um entendimento real é impossível se o vocabulário natural é desprezado.

Rails é o novo ASP, redux

July 2nd, 2009 § 6 comments § permalink

E depois tem gente que acha que eu estou brincando quando digo que Rails é o novo ASP. Agora temos um Rails Rescue Handbook, especialmente voltado para projetos Rails que estão no buraco. Eu acho maravilhoso! :D

Eu fico com a baleia

April 8th, 2009 § 23 comments § permalink

Essa história toda do Twitter me impressionou particularmente por um aspecto: como pessoas que jamais tiveram experiência com sistemas de grande porte acham que são capazes de dar opiniões completamente válidas sobre os mesmos (independentemente de que linguagem usam ou preferem).

Eu não vou ofender meus leitores dizendo que tenho vasta experiência no assunto, e também não vou cometer o erro de dizer que sei alguma coisa a mais do que um bom engenheiro de software saberia. Minha experiência mais recente com o assunto–atual, por assim dizer–é acompanhar o desenvolvimento de uma aplicação que no momento serve 60 milhões de page views por mês e cujo crescimento mensal tem sido constante pelos últimos meses.

Essa aplicação é escrita inteiramente em Ruby on Rails e olhando os desafios que manter, evoluir e operar essa aplicação representam, eu já tenho toda simpatia pelos engenheiros do Twitter. Manter uma aplicação do porte do Twitter no ar, com toda a complexidade distribuída que o núcleo do mesmo precisa é algo para se aplaudir.

O que torna mais impressionante como as pessoas são rápidas para assumir que o código do Twitter é uma completa porcaria. Mesmo que fosse–e mesmo assumindo que pode ser–as críticas nesse aspecto ainda são completamente inválidas. Por mais que uma aplicação acrua débitos ténicos, o balanço entre os mesmos e o valor entre ao usuário–que é inegável no caso do Twitter–é uma decisão de negócio inquestionável.

Martin Fowler fala muito bem desse balanço um texto seu sobre débitos ténicos:

The metaphor also explains why it may be sensible to do the quick and dirty approach. Just as a business incurs some debt to take advantage of a market opportunity developers may incur technical debt to hit an important deadline. The all too common problem is that development organizations let their debt get out of control and spend most of their future development effort paying crippling interest payments.

Do meu ponto de vista, o fato de que o Twitter experimentou com outras tecnologias, fez benchmarks de plataformas, procurou melhores soluções é uma indicador claro de que estão tentando resolver seus débitos. Pedir mais do que isso é assumir uma postura de arrogância e desconhecimento, principalmente de como negócios são operados e de como código real é produzido.

Admitir publicamente problemas e tentar criar um discurso é algo que respeito; dizer coisas do tipo “As far as I’m concerned, Twitter is a case-study in how Ruby on Rails does scale, even in their hands”, por outro lado, é algo que tira qualquer possibilidade de um discurso racional. Os fanboys e pundits da comunidade Rails tem muito do que se envergonhar no seu tratamento da questão.

Programadores não operam em mundos ideais. E até que os detratores do Twitter me mostrem que fizeram o seu dever de casa em lidar com essas questões, eu fico com o Twitter e sua baleinha simpática. Proper for humans, after all.

O brouhaha sobre o Twitter e por que evangelistas puristas de linguagens/frameworks são imbecis

April 5th, 2009 § 10 comments § permalink

O cantinho de desenvolvimento de Rails na Web está quente de novo com a discussão sobre o fato de que o Twitter está reescrevendo alguns de seus sistemas de backend em Scala (1, 2, 3. 4). A coisa toda começou com a palestra que o Alex Payne, desenvolvedor responsável pela API do Twitter, deu no Web 2.0 Expo SF.

Obviamente, os evangelistas do Rails já pularam em cima da oportunidade para despejar baboseira sobre o assunto como se a questão fosse a mais importante do mundo e como se o mundo Rails estive para implodir depois das declarações bombásticas do Alex Payne.

Eu me rio.

Eu estou indo para uma década e meia de desenvolvimento esse ano, quase todos na Web. Não é muito mas foi o suficiente para por sistema em produção usando Object Pascal, C/C++, VBScript, PHP, Python, Ruby, Perl, Java, C#, Smalltalk para citar algumas das linguagens que já usei em vários e vários frameworks. Caramba, eu cheguei a desenvolver um framework Web mais um ORM em Delphi que foram usados em produção para um sistema durante quatro anos até que o projeto foi eventualmente reescrito em alguma coisa mais recente depois que eu já saíra do mesmo há muito.

O que eu aprendi nesse anos em relação a linguagens e frameworks é que todos são bons e todos são ruins e que evangelismo purista é uma das expressões mais ridículas no mundo de desenvolvimento. Qualquer desenvolvedor que se sinta compelido a defender sua linguagem/framework (e pior, os que fazem isso uma carreira como os vários Javamen, Rubymen, Scalamen, Whatever-Language-Men que existem por aí) não merecem um aceno patético de respeito.

Eu assisti a palestra do Payne na Web 2.0 Expo e o que vi foi alguém em amor com uma tecnologia nova. A palestra (como a maioria das outras técnicas no evento) foi corrida e não apresentou nada concreto. De fato, durante quase 20 minutos tudo o que Payne fez foi falar sobre as características de Scala e como ela é fantástica sem apresentar um exemplo de código que fosse. Foi o suficiente para despertar curiosidade sobre a linguagem mas não prova nada–como não deveria. No meio da apresentação, Payne fez a declaração que suscitou a ira da comunidade Rails: O Twitter está movendo vários dos seus sistemas de backend para Scala onde o Ruby não está agüentando. Por algum motivo, isso foi distorcido para dizer que Rails não escala e o resto é história.

Eu já dei minha resposta sobre a questão do Rails escalar ou não em um tom mais irônico mas as pessoas parecem gostar de perder tempo sobre isso. Evangelistas de Rails, principalmente, adoram a questão. Parece que há um fator magnético associado à afirmação. Fale isso e caem dúzias de Railers incensados do céu.

O fato de que tecnologias não escalam mas design sim parece passar inteiramente despercebido. Eu já vi sistemas limpos em Rails que não são capazes de servir pouco mais do que algumas dezenas de usuários em hardware similar ao que a empresa para qual eu trabalho usa para extrair 60 milhões de requisições por mês de um backend em puro Rails. Rails escala? Pergunta errada.

Assim, quando um Obie Fernandez diz que sua resposta evangelística ao evangelístico Payne é razoável, eu digo: Bullshit! (Só não vou dizer que é pior porque veio do homem que quer o mercado Rails todo para si porque seria maldade. Ops, que maldade…) Mais engraçado do que isso só ver nego pulando de uma conclusão para outra usando o mesmo artigo como base para evitar ficar associado com o estigma. Sigh…

Anyway, para resumir meus devaneios aqui. Se você é um programador de uma linguagem/framework só que precisa defender sua tecnologia a cada rumor, precisa seriamente repensar sua carreira. Eu, por mim, acredito em segundas chances.

Rails é, definitivamente, o novo ASP

February 13th, 2009 § 14 comments § permalink

Você sabe que uma tecnologia atingiu o ponto de saturação quando alguém tem a capacidade de propor algo CMM-like para ela.

Rails é, definitivamente, o novo ASP–ou Cobol, ou PHP, ou escolha o que você achar melhor. :)

Algumas dicas para testes melhores

October 27th, 2008 § 3 comments § permalink

O Lucas Húngaro escreveu recentemente sobre a necessidade de abandonar testes quebradiços com uma forma de manter seus testes saudáveis, citando vários exemplos de como isso pode ser feito. Desnecessário dizer, concordo com o que ele disse.

Um conselho dele em particular me parece a melhor consideração sobre o assunto. Falando sobre mocks e stubs, ele diz:

Algumas soluções pra isso são: não utilizar mocks e stubs (o que é um tanto extremista), aumentar o encapsulamento das classes ou aceitar isso e continuar.

Chamo a atenção para a parte final: algumas vezes, você tem simplesmente que aceitar que alguns testes devem ser de certa forma para garantir uma cobertura mais compreensiva.

Dito isso, seguem algumas dicas para testes melhores:

Mocks e Stubs

Uma regra simples que pode ajudar a entender quando usar essas duas técnicas é a seguinte: Se o comportamento esperado deve ser conhecido, use mocks e stubs. Caso contrário, não.

Isso torna fácil perceber que testes de modelos–no caso do Rails, por exemplo–raramente (ou nunca) deve usar essas técnicas. Quando se trata do domínio da aplicação, encapsulamento é uma propriedade básica de sistemas orientados a objetos que não deve ser violada se possível. Obviamente, abstrações vazam; mas isso não deve ser uma desculpa para quebrá-las em testes.

Não teste a abstração imediatamente inferior

Se você está usando Rails, por exemplo, não faz o menor sentido testar a abstração inferior. É muito comum ver testes como:

it "should return all current books" do
  Book.current.proxy_options.should == { :conditions => { :current => true } }
end

Esse tipo de teste verifica se o Rails está funcionando da maneira como deve funcionar e não se o seu código está correto. O resultado é que pequenas mudanças e principalmente a introdução de algum comportamento ortogonal pode quebrar completamente a aplicação enquanto o teste continua a funcionar.

Digamos, por exemplo, que você agora tenha que usar alguma esquema de caching em sua aplicação. No interesse de que a abstração não vaze, você envolve o método acima em alguma abstração que faça isso. O teste acima provavelmente quebrará de imediato, porque está testando a abstração inferior e não o comportamento da aplicação.

O teste correto, nesse caso, seria verificar se a lista retorna é realmente correta, mesmo que isso envolva alguma manipulação de dados que reduza a velocidade do teste.

Use testes de sanidade

Conversamente, é importante também ter alguns testes de sanidade. Às vezes é necessário saber se alguma coisa está declarada, mesmo que a forma final daquela declaração não seja importante.

Um exemplo disso são testes em views. Geralmente, testar se algum conteúdo está aparecendo em uma view é inteiramente desnecessário e pode gerar testes que devem ser refeitos a cada pequena mudança para se adaptar a novas condições.

Mesmo assim, em alguns casos é importante a existência de testes que correm esse risco como forma de testar a sanidade da aplicação; em outras palavras, testar se condições básicas estão sendo supridas.

Não teste nada que não seja público

Uma pergunta muito comum em listas de discussão é como testar métodos privados ou protegidos de uma classe. A reposta geralmente envolve o uso de reflexão e violação de abstrações.

Um exemplo comum seria o código abaixo:

it "should prepare the environment" do
  Manager.send(:prepare_environment)
  Manager.environment.name.should == "development"
end

A resposta correta deveria ser: nunca faça isso. Se seus testes contém alguma necessidade desse tipo, você está violando o encapsulamento e isso indica alguma problema arquitetural mais básico da aplicação. Provavelmente alguma necessidade de separação de dependências que você ainda não identificou.

Nesse casos, funcionalidade básica que envolva código encapsulado pode ser melhor testada pelo seu efeito em outras partes da aplicação.

Cuidado com a ordem dos seus testes

Uma coisa interessante é tentar rodar os seus testes em ordem arbitrária. Existe opções para isso em alguns dos frameworks existentes que podem ajudar a identificar dependências escondidas em seus testes.

Finalizando

Para terminar, esse são apenas alguns dos muitos conselhos possíveis nessa área. Fiquem à vontade para usar a área de comentários do texto para expandir sobre o assunto.

Um conselho final: use seus testes como oportunidades para pensar sobre a sua aplicação. Se você se vê em uma situação em que testar está se convertendo em algo progressivamente mais complicado, alguma coisa está errada na forma como você desenhou seu código. Pare, pense sobre o assunto, e refatore. Seu código e seu tempo agradecem.

Algumas considerações sobre TDD e BDD

October 27th, 2008 § 13 comments § permalink

Parece haver muita confusão sobre a diferença entre TDD e BDD na comunidade Rails. A criação de vários frameworks competidores (RSpec, Shoulda, Expectations, etc) parece não ter ajudado muito já que cada proponente torce um pouco a visão dada por cada um deles.

A grande divisão

O problema é que a maioria das pessoas que pratica uma variante ou outra nunca leu a literatura sobre o assunto e por causa disso há uma falta de formalização sobre o assunto. Muito do que se vê escrito hoje tanto sobre TDD ou BDD é escrito da forma que aquela pessoa em particular pratica o assunto e não como o conceito foi sendo desenvolvido ao longo das anos.

Tome, por exemplo, TDD como popuralizado originalmente por Kent Beck no contexto de Extreme Programming. Existe uma granularidade envolvida no crescimento do código que pode ser descrita como orgânica.

Design ou Development?

Uma das coisas que sempre me ajudou a enxergar o modo apropriado de construir uma aplicação a partir de testes foi pensar no D final de TDD ou BDD não como desenvolvimento, mas como design.

Voltando ao tema de granularidade, se você fizer uma experimento e acompanhar dezenas de pessoas que “praticam” TDD ou BDD, o mais provável é que você perceba que os testes estão sendo escritos como uma forma de cobrir o código e não como uma forma de pensar no código em si. Um teste é escrito que demonstra um certo caso de uso da classe ou método em questão e o código para aquele trecho é então escrito.

É muito comum, dentro da prática descrita acima, que vários testes seja escritos em seqüência e o código da classe ou método inteiro seja depois implementado. Voltando ao modo como Kent Beck explicou o processo originalmente, nada por estar mais longe da realidade.

De fato, nos seus exemplos concretos sobre o assunto, Kent Beck compara o uso de TDD ao uso de uma lista de tarefas para a construção de código, o que força o desenvolvedor a pensar em detalhes sobre a arquitetura que está criando. Volta aqui o sentido de design e não de desenvolvimento puro.

Chega-se então ao ponto de que cada teste é pensado como uma forma de evoluir a arquitetura do código e pensar em como aquela classe ou método existe dentro do contexto mais generalizado da aplicação. Não é surpreendente que quando isso é feito, coberturas de 100% são factíveis, métodos ou funções não possuem mais do que algumas poucas linhas fazendo exatamente e o que deve fazer e não mais e uma delegação efetiva de responsabilidades acontece.

TDD versus BDD

Chega-se então ao ponto central da conversa? Qual é a diferença principal entre TDD e BDD? No ponto mais básico da cadeia, a resposta é: nenhuma.

Tanto TDD quando BDD são formas de se pensar em testes partindo de premissas ligeiramente diferentes mas chegando ao mesmo resultado prático. Sendo feitas de maneira apropriada, o resultado final dentro das necessidades acima (cobertura, delegação, arquitetura) é o mesmo e a conversação que deve acontecer no desenvolvimento ocorre naturalmente.

Apesar disso, há uma diferença histórica que está evoluindo com o tempo e que, em última instância, está se convertendo no foco de debate entre os dois campos. Essa diferença foi inicialmente expressa por Dan North (responsável pelo desenvolvimento do RBehave, que mais tarde se tornaria a base do Story Runner do RSpec) e depois elaborada por David Chelimsky.

Esse posicionamento coloca BDD não como uma oposição direta a TDD em termos práticas, mas como uma corrente filosófica que engloba TDD e expande o discurso para incluir elementos que vão além do metodológico e já começam a cair no processual.

Um exemplo claro disso é a ascensão de frameworks orientados a estórias (testes de aceitação de usuários) como o Cucumber. Esses esforços representam a graduação de BDD não somente com uma forma de fazer testes mas como um processo de pensar e executar testes ao longo de toda a gama de necessidades de uma aplicação (de unitários e visuais).

Essa conversa é a parte mais importante do BDD e, no caso do Rails e Ruby, o RSpec representa apenas uma faceta de tudo o que vem sendo pensado pela comunidade. Eventualmente, como Chelimsky coloca, TDD será um parte de algo maior que será chamado de BDD.

Finalizando

A confusão experimentada atualmente é mais resultado da conversação acima do que da diferença real entre os frameworks. Ainda citando Chelimsky, quando BDD era somente sobre testes unitários, não havia diferença nenhum entre TDD e BDD. Ambos eram e são sobre a melhor forma de testar uma aplicação e nada mais do que isso.

Para dar um exemplo, atualmente eu tenho preferido a combinação Test/Unit + Shoulda + RR ao invés do meu usual RSpec. Gosto da leveza dos anteriores em relação ao último quando os testes se tornam mais envolvidos. Mas isso representa apenas dores de crescimento do RSpec. É bem possível que quando este último estiver mais estabilizado, lidando mais com a magia negra que ele precisa para sua sintaxe, eu mude novamente de prática.

De uma forma geral, então, escolha o frameworks que melhor lhe convier. Desde que a forma como você faz testes esteja correta, o resultado final estará correto também.

Aprendendo Rails

October 23rd, 2008 § 9 comments § permalink

O dia nove de outubro passado marcou os dois anos da liberação do meu tutorial Rails para sua Diversão e Lucro. Oito meses depois do lançamento, o mesmo já havia ultrapassado 15 mil downloads somente no meu servidor. Considerando que a licença é GFDL e que o mesmo foi reproduzido em dezenas de sites, o número atual deve ter sido bem maior mesmo na época.

No geral, foi uma experiência bem positiva. Para um tutorial que começou como material para um curso, a quantidade de pessoas interessadas foi surpreendente. Mesmo na época, havia uma carência enorme de informações sobre o assunto. Coincidentemente, o primeiro livro de Rails no Brasil também foi lançado na mesma época. Acho muito legal, inclusive, que pessoas que hoje são extremamente ativas na comunidade tenham tido contato inicial com Rails através do tutorial.

Bem, esse monte de reminiscências é para anunciar aos leitores regulares que possam eventualmente desejar aprender Rails e aos visitantes que volta e meia chegam aqui perguntando sobre o assunto e topando com um tutorial desatualizado que uma nova versão está disponível.

No melhor espírito da GFDL, Cássio Souza atualizou o tutorial para Rails 2.1, modificando o material antigo, removendo as partes ultrapassadas e acrescentando muito material novo em um novo tutorial que reflete mais precisamente a versão atual do Rails (de 1.2 para 2.1). O material também é acompanhando de screencast que explica mais detalhes práticos sobre o assunto.

Fica aí a dica para quem quer aprender sobre Rails de maneira prática. E que venha os downloads. :)

Rails Summit ’08

October 17th, 2008 § 0 comments § permalink

Como mais de quinhentos outros Railers do Brasil, participei ontem e ante-ontem do Rails Summit ’08. Foram dois dias intensos de bastante palestras e conversas no corredores e salões do Anhembi, e, como a maioria dos participantes, fiquei bem satisfeito com a experiência.

Esse foi o primeiro evento brasileiro de Rails de larga escala, contando com a participação de palestrantes da comunidade Rails internacional e para uma primeira edição ficou bem além das expectativas que qualquer um poderia ter tido. A organização foi impecável, tanto no que prometeu fazer quanto no que teve que resolver quando algumas coisas não saíram como previsto e o resultado final foi um evento de qualidade que nada ficou a dever a conferência do mesmo porte que já são realizadas para outras comunidades.

Outros blogueiros já falaram bastante sobre as palestras e acontecimentos e não vou me estender mais sobre o assunto. Para um outro apanhado geral, o livestreaming do evento que preparamos aqui na WebCo também mostra tudo que o pessoal andou falando e ainda está falando sobre o Rails Summit.

Finalizando, um mega-parabéns ao Akita pelo esforço demonstrado antes e durante o evento na promoção da comunidade aqui no Brasil.

Where Am I?

You are currently browsing the Rails category at Superfície Reflexiva.