Peepcode sponsors akitaonrails.com Locaweb sponsors akitaonrails.com

Quick and Clean

AkitaOnRails / 21.Feb.2007 at 04:50am

Dia 9 de fevereiro aconteceu o evento RoR eXchange 2007, da Skills Matter, co-organizadora da última RailsConf. Foi um evento de um dia que reuniu alguns bons palestrantes para discutir os últimos desenvolvimentos no mundo RoR.

Neste link vocês podem assistir a todas as palestras. Ainda não vi todas mas gostei muito da apresentação de Chad Fowler. Parte dela tem a ver com minha coluna de Janeiro na RubyOnBr – A Dieta dos Controllers – onde tentei clarear uma dúvida constante: “ok, sei que Rails é MVC, mas onde diabos coloco minha lógica de negócios?”.

Outra parte tem a ver com o que já mostramos sobre o suporte REST no novo Rails 1.2. Mas o ponto alto da palestra é um aviso (muitos não vão gostar, mas vamos lá): Ruby e Rails são anunciados como “linguagem simples”, “framework fácil”, “mais fácil e rápido que Java”, “mais simples de aprender”, etc. Tudo isso dá uma extrema falsa impressão de que qualquer peão (sem ser pejorativo, mas já sendo), que nunca programou na vida, estará desenvolvendo um Yahoo.com amanhã. Novamente, cuidado, essa é a falácia da causa e efeito: porque RoR é fácil, qualquer um aprende fácil.

Vamos consertar isso: ‘Ruby e Rails são tecnologias muito simples para todos que JÁ SÃO bons programadores hoje’. Nos últimos tempos Chad teve a oportunidade de ver muitos códigos de terceiros, muitos deles códigos de novatos. O que ele viu deve horrorizar qualquer um: Rails não protege a aplicação de um mau programador.

Como disse Chad, Java e C# são tecnologias que foram desenvolvidas para programadores idiotas. Calma! Não quer dizer que quem programa em Java é idiota mas sim que ela foi pensada em termos de dar uma série de proteções para evitar erros banais. É isso que faz o compilador: protege seu código contra erros triviais de tipos (mas apenas contra erros triviais), por exemplo, o tipo de erro que um novato cometeria.

Ruby não tem essas proteções. Linguagens como Ruby, Python, Haskell, O’Caml, foram feitas para bons programadores, aqueles que sabem exatamente o que estão fazendo. Rails é uma excelente ferramenta apenas, e somente apenas, àqueles que se deram ao trabalho de estudar como ela funciona internamente.

O exemplo de Chad é muito bom: em uma boa tecnologia de ORM como o Active Record do Rails ou mesmo um Hibernate em Java esconde boa parte do SQL que antes era feito manualmente. Agora imagine que você buscou uma lista de usuários do seu banco (find :all), colocou essa lista para iterar em um loop (.each) e está analisando as permissões de cada usuários para mostrar em uma tela. Você acabou de cair na armadilha conhecida como 1 + N, ou seja, se sua lista de usuários tinha 200 usuários, você vai fazer pelo menos mais 200 queries no banco para buscar as permissões de cada um. Eu discuto isso no meu livro e mostro a diretiva :include dos finders, que é uma das possíveis soluções nesse caso.

Você só sabe onde, quando e como usar uma técnica como :include se souber exatamente o que o ActiveRecord fará no seu banco, como queries SQL se comportam, o que é um left outer join. Se não tiver nenhum desses conhecimentos, trará um impacto que poderia ser mortal à sua aplicação no médio prazo. Outro exemplo é uma homepage “ocupada” (cheia de pequenas queries e informações dinâmicas, uma página não-Web 2.0, digamos) que também terá um impacto enorme caso o programador não tenha noção das diversas técnicas de caching do Rails (outro assunto que também discuto no meu livro).

Em outras palavras: nem Ruby nem Rails protegerá uma aplicação de um programador folgado. Quando um bom programador (que já tem experiência em bancos de dados, em otimização do modelo request-response do HTTP, em configuração de servidores web como Apache, em ORM, em MVC, em Design Patterns, etc) se encontra com Ruby on Rails, temos um excelente casamento. Quando um programador que não investiu o devido tempo a estudar todos esses assuntos se encontra com Ruby on Rails, temos um desastre. E isso não é só com Rails. Coloque um programador que não tem o costume de se auto atualizar como deveria em qualquer plataforma de desenvolvimento e sempre teremos um desastre.

Significa que não há salvação para os novatos? Claro que não, todo programador sênior já foi um júnior. A diferença é que o primeiro investiu cada hora livre de seu tempo em estudo. E eu quero dizer estudo com perspectiva, não um estudo míope de ferramentas, mas sim um estudo amplo de tecnologias. Por que o HTTP é como é? Por que SQL é como é? Por que o que chamamos de MVC atual é como é? Quais as melhores formas de usar todas essas tecnologias em conjunto? Inclusive essa é a linha mestra que guia meu livro: um livro que apenas o leva passo a passo do estágio 1 ao 2, não ensina nada. “Para buscar todas as linhas da tabela, digite find(:all)”. Esse é o tipo de ensinamento que torna possíveis bons programadores em programadores folgados. Ele não diz o principal: “por que”, “quais as alternativas”, “o que acontece por baixo”, “quais minhas opções”.

Por muito tempo associamos programação a dois estilos: quick’n dirty (rápido e sujo) ou slow’n clean (lento e limpo), ou seja, se você programar rápido demais, sem pensar muito, apenas cuspindo código, terá algo sujo, difícil de dar manutenção e cheio de bugs. Para ter um sistema estável, com código razoavelmente simples de dar manutenção futura, é preciso planejar de antemão tudo que fará e ir muito devagar. A nova geração Agile de desenvolvimento postula que é possível sim, ser quick’n clean, ou seja rápido e limpo. Mas algo que está implícito é: para ser rápido e limpo é preciso ser esforçado, auto-didata e estar sempre experimentando técnicas e tecnologias.

Ninguém consegue ser quick’n clean em qualquer plataforma, linguagem ou tecnologia, mesmo tendo Q.I. de Einstein. Experiência não se herda nem se compra: se adquire, com esforço, treinamento contínuo e de qualidade. Para um jogador profissional de basquete, fazer cestas de três pontos é algo quase trivial. Para um principiante é a coisa mais difícil do mundo, a diferença é que o primeiro provavelmente treinou esse lance por várias horas, durantes vários dias, em vários anos a ponto disso se tornar trivial. É um conceito que vale para qualquer coisa, não apenas programação: quanto mais treinamos, mais as coisas difíceis se tornam simples e podemos partir para treinar algo mais difícil.

Lembre-se: David Hansson, Marcel Molina, Sam Stepherson, Miguel De Icasa, Guido van Rossum, Rasmus Lerdorf, Larry Wall, Anders Hejlsberg, Alan Cox e mesmos outros célebres como Bjarne Stroustrup, Dennis Ritchie, Alan Kay, Niklaus Wirth, Donald Knuth e centenas de outros. Acha que está nos genes? Um bom programador nasce geneticamente bem dotado? A diferença entre um programador ruim e estes nomes é a quantidade de esforço investido em estudo, pesquisa e experimentação. Não existe fórmula mágica, curso à jato de 6 meses, voodoo, que substitua o puro e simples suor.

Enfim, Chad repete o que eu disse na minha coluna: lógica de negócios, SQL, operações no banco, devem estar nos models. Os controllers devem ser modelados na filosofia REST (que não é coisa nova) e simular operações CRUD (atenção aos models implícitos na forma de tabelas de relacionamento many-to-many). Leia meu livro, leia os artigos na categoria Rails 1.2 neste blog, assine os feeds de sites como Ruby Inside e outras dezenas de ótimos blogs como do Dr. Nic, Ryan’s Scraps, etc. E principalmente: estude, mas estude muito, constantemente e sempre. Não existe ponto final em tecnologia, ninguém jamais poderá dizer “agora já sei tudo que preciso”, qualquer um que acha isso ainda não passa de um principiante.

12 Comments

Muito bom o post. Acho que vale a pena colocar um link para o livro que é citado algumas vezes no texto, acredito que seja o Rails Recipes http://www.pragmaticprogrammer.com/titles/fr_rr/

Sim, esse é o livro de Chad Fowler, mas o “livro” que eu cito no texto de fato é o meu (Repensando a Web com Rails – fonte para quem precisa de documentação em português). Mas deixando o “momento-propaganda” de lado, também recomendo o Rails Recipe que você falou, é uma excelente fonte de boas técnicas e dicas.

Em poucas palavras: NO PAIN, NO GAIN!

Grande post.

Me lembra algo q li em algum lugar que era mais ou menos assim:

Tentar criar uma linguagem de programação poderosa que proteja o programador é como criar uma faca afiada que não corte o dedo.

Ou seja, a linguagem não é o problema, é a solução, o problema é quem opera ela :D

RoR realmente um ambiente muito bom para quem ja é experienciado.

Uma coisa que me ajudou a entender como funciona o Active Record foi fazendo testes de includes, e finds, e visualizando o sql gerado no .log

Para quem ja entende de sql, da pra tirar um bom resultado disso.

[]s

Muito bom seu artigo Akita, ja faz 3 meses que comprei o livro e todo santo dia fico recapitulando alguns artigos.

Abraços

Me lembrou um texto antigo, básico, mas bacaninha: http://www.1bit.com.br/content.1bit/bom_programador

Uma vez eu conheci um cara que não fazia JOINS. Ele fazia SELECT * em todas as tabelas, fazia loops for malucos e se achava o maior. Não é mentira. Nem piada. Infelizmente.

Excelente texto, gostei dele. E quanto ao loop no select * é verdade, eu mesmo já encontrei código assim. Isso se explica em parte se o programador veio da época Clipper, Paradox e derivados. Não havia algo tão forte como SQL. Fazer “joins” não era trivial, principalmente para iniciantes. E a primeira página de muitos tutoriais de SQL é justamente um select *. A maioria não pula da primeira página e as boas documentações estão em inglês. Depois da primeira página todo mundo acha que já “entendeu” SQL: “ok, é fácil, basta puxar tudo, fazer um loop e pronto”. Ninguém pára para pensar que os dados trafegam via rede de um servidor para outro, que os dados “puxados” vão para a memória, que os dados precisam gastar ciclos de processador para serem processados (por definição). No fim o sistema fica lento como uma carroça e a solução está na ponta da língua: “esse servidor já é muito velho, precisa fazer upgrade, colocar mais memória, etc”. isso seria cômico se não fosse desastroso.

MVC sempre será um assunto desafiador. Na maioria das vezes, concentrar as regras nos modelos parecem ótimas e por assim dizer são até ‘leis’. No entanto, o cenário é diferente quando a aplicação é complexa.

A aplicação pode adquirir comportamentos que são tão complexos que iniciam desde o roteamento dos controladores e fica dificil concentra-la apenas nos modelos. Fluxos, navegações, interações são exemplos.

Por sua vez, os controladores podem ter complexidades acidentais como hierarquização (isso é comum em jogos no qual você não pode escolher a personagem sem antes ter feito a autenticação)

‘Modelos dão significados aos dados’ e aplicação das regras do negócio deveriam ficar nos modelos, mas não como regra, apeans por conveniência.

Talvez com aplicações web isso faça muito significado, pois é fácil aplicar um MVC. Mas em outras áreas no qual os modelos vão além de ‘algo junto ao banco de dados’, não é tão simples como deveria.

Esperamos ver um artigo seu dedicado ao MVC!!

t+

Ainda não é uma resposta completa como você falou, mas neste link tem uma introdução. Assim como minha última coluna na RubyOnbr que mencionei neste post.

A “diet dos Controllers” no rubyonbr eh um articulo bom. bom trabalho na traducao pra portugues… mas sera quem foi que escolheu esse nome para portugues? “diet dos Controllers” :D hehehe

aqui tem um articulo muito bom, que vale a pena ser traduzido pra portug. http://somethinglearned.com/articles/2006/05/24/best-practices-a-strong-case-for-attr_accessible-part-2

o articulo fala sobre o bom uso de attr_accessors e como eh facil de modificar dados da mensagem POST no protocolo HTTP.

por exemplo, o usuario tem um campo “admin” que por defeito eh “false” quando o usuario se registra ele poderia adicionar useradmin=true na mensagem POST

principalmente o uso de user.product_ids

ja que o usuario poderia tomar conta de todos os produtos…

(user has_many products)

www.Frederico-araujo.com

Acordei pedante hoje e nao consigo evitar de comentar uma minuncia irrelevante.

Quando voce diz “Ruby não tem essas proteções. Linguagens como Ruby, Python, Haskell, O’Caml, foram feitas para bons programadores, aqueles que sabem exatamente o que estão fazendo” alguem que nao conheca bem estas linguagens pode ficar com uma impressao errada. So para deixar bem claro, Haskell e O’Caml sao linguagens estaticamente tipadas. Haskell especificamente tem um sistema de tipos fortissimo.

Leave a Comment