Pesquisa Sobre Os Eventos De TI

| Comments

Na empresa onde trabalho, Globo.com, todo início de ano temos que “escolher” para quais eventos gostaríamos de ir. Esses eventos podem ser no Brasil ou fora, sendo que devem falar sobre assuntos que tenham correlação com seu trabalho ou objetivo de seu time ou área. Diante disso, o que geralmente fazemos, é montar uma planilha com diversos eventos que vamos encontrado. Isso feito, escolhemos a partir dessa lista quais eventos desejamos ir seguindo algumas regras.

Nesse ano, conforme fomos levantando os eventos, acabou surgindo uma discussão quanto a qualidade dos eventos. Ao analisarmos as grades(temas, palestrantes, etc), eu e um grupo ficamos com a sensação ruim de estar vendo mais do mesmo, conteúdos rasos, repetição de tutoriais, e outras coisas similares. Cheguei, inclusive, a postar essa impressão no meu facebook, onde tive um retorno similar de amigos de fora da Globo.com.

Diante disso, após mais um pouco de conversa, resolvi fazer uma pesquisa para ver o quanto essa percepção em relação a qualidade dos eventos era só minha, ou, de fato, há uma certo sentimento geral.

A Pesquisa

Para fazer a pesquisa, optei por um formulário simples no GoogleDocs, onde fiz algumas perguntas como: Você se interessaria por eventos mais técnicos? Quais assuntos desejaria ver? Deixe seu comentário…

A intenção clara era de captar o nível de insastifação com relação as temas, formas, organização e nível dos conteúdos abordados. Outro ponto, é que o direcionamento também foi para pessoas com mais experiência. Publicado o form, fiz um tweet e pedi ajuda a amigos para espalharem o formulário para alcançarmos o máximo de pessoas o possível.

O Resultado

Até o momento em que escrevo esse artigo, tinhamos por volta de 170 respostas. Embora não seja um número muito grande do ponto de vista estatistico – que nos permitiria ver alguma tendência, o grande ponto vou ver o quanto o sentimento de insastifação é compartilhado.

Isso ficou bem claro, nos comentários deixados pelo pessoal no final do formulário: esse de fato foi o campo mais revelador de toda a pesquisa.

Comentários como, “Muita panelinha …”; “Sempre os mesmos assuntos…”; “Coisas que poderia aprender com tutoriais”, surgiram em quantidade expressivas, revelando que precisamos repensar a forma que fazemos evento e montamos nossas grades.

Para exemplificar, na montagem do evento do Front in Rio 2013, nós da organização discutimos muito para saber qual seria a melhor forma de escolher as palestras. Acabamos por fim abrindo um pouco a grade e escolhendo pessoas que trouxeram assuntos (e não currículos) interessantes para a comunidade.

Conclusão

Frente aos dados que levantei, as opiniões e as discussões em cima de todo esse material que tive, a conclusão que chego é que existe espaço e demanda para eventos mais técnicos e de conteúdo mais aprofundado, porém, esses não pode ser no mesmo formato dos atuais, nem invalidam a importância dos mesmos.

Vamos por parte:

  • Como disse um amigo, eventos grandes, ou para grande massas, eles tem que ser mais abrangentes, mais rasos e contar com pessoas conhecidas e famosas para atrair gente, pois esse é seu real objetivo: atrair pessoas para o meio. Famoso, chamar atenção.
  • Eventos mais técnicos não podem ser grandes pois isso inviabilizaria a discussão e troca… Não existe como conversar com 500 pessoas. Limites de 100 a 150 pessoas(ou até menos) parece-me ser a melhor opção.
  • As pessoas quando buscam por mais conteúdo querem que isso seja lhe entregue de uma forma bem mais flexível e pessoal. Sendo assim, se quisermos eventos com mais qualidade técnica, esse modelo de palco, microfone, slide com monte de imagem e palestrante em sala separada, não funciona. Ainda dentro desse item, rápidas exposições, mais conversas, e ambiente bem descontraído parece ser a melhor escolha

Por fim, é que existem pessoas que querem coisas do genero e arrisco dizer que pagariam por isso. Logo, por que não fazer?

Quando Fazer Refactoring

| Comments

TL; DR; Sempre que falo sobre refactoring, sempre ouço a pergunta de quando fazer e como alocar tempo para realizá-lo.

Para mim não existe um quando e nem quantidade de tempo para refactoring: sempre é momento de fazê-lo. Se simplesmente o refactoring não for considerado, mesmo que tenha a melhor estrutura e arquitetura, seu sistema irá ficar obsoleto e se tornará um grande legado. Fazer refactoring é um dos pilares para mantermos a qualidade da base de código.

REFACTORING

Martin Fowler em seu livro Refactoring, define como sendo a prática de melhorar o código em busca de maior clareza, melhor estrutura para extensão, maior comunicação, etc … sem alterar o comportamento.

Refactoring é a técnica para manter o seu código atual, sem duplcidades (DRY), seguindo boas práticas e princípios como o SOLID).

Uma boa analogia é de sempre buscarmos a melhor forma de resolver o mesmo problema, tendo em vista a clareza, a boa comunicação, facilidade de extensão. Note aqui que não falei de perfomance.

PORQUE REFACTORING

Kent Back, possui uma citação interessante que explica bem o porque:

Programs have two kinds of value: what they can do for you today and what they can do for you tomorrow. Most times when we are programming, we are focused on what we want the program to do today. Whether we are fixing a bug or adding a feature, we are making today’s program more valuable by making it more capable. You can’t program long without realizing that what the system does today is only a part of the story. If you can get today’s work done today, but you do it in such a way that you can’t possibly get tomorrow’s work done tomorrow, then you lose. Notice, though, that you know what you need to do today, but you’re not quite sure about tomorrow. Maybe you’ll do this, maybe that, maybe something you haven’t imagined yet. I know enough to do today’s work. I don’t know enough to do tomorrow’s. But if I only work for today, I won’t be able to work tomorrow at all. Refactoring is one way out of the bind. When you find that yesterday’s decision doesn’t make sense today, you change the decision. Now you can do today’s work. Tomorrow, some of your understanding as of today will seem naive, so you’ll change that, too. What is it that makes programs hard to work with? Four things I can think of as I am typing this are as follows:

1. Programs that are hard to read are hard to modify.

2. Programs that have duplicated logic are hard to modify.

3. Programs that require additional behavior that requires you to change running code are hard to modify.

4. Programs with complex conditional logic are hard to modify.

So, we want programs that are easy to read, that have all logic specified in one and only one place, that do not allow changes to endanger existing behavior, and that allow conditional logic to be expressed as simply as possible. Refactoring is the process of taking a running program and adding to its value, not by changing its behavior but by giving it more of these qualities that enable us to continue developing at speed.

Transcrevendo, seria dizer que todos os sistemas possuem 2 valores: o que pode ser feito hoje e que pode ser feito amanhã. Na maioria dos casos, sempre pensamos no presente. Porém, sistemas evoluem e novas funcionalidades, correções de bugs, vão ocorrendo e o código sendo alterado. Nesses ciclos, acabamos duplicando código, adicionando responsabilidades a métodos, alterando as lógicas, etc. Com isso o código vai ficando confuso e complexo.

A técnica de Refactoring, é justamente olhar para esse sistema e buscar sempre um jeito melhor te atender os requisitos. Jeito esse que leva em conta coisas como comunicação, clareza, facilidade de extensão, e coisas simmilares.

Por isso, se quisermos manter um sistema com uma boa qualidade e simples de ser entendido e extendido, é muito importante sempre realizarmos refactorings.

REFACTORING, TESTES AUTOMATIZADOS e TDD

Não é meu objetivo entrar muito a fundo no assunto, entretanto, é importante dizer que é muito díficil fazer Refactoring em sistemas sem testes automatizados. Não é impossível. Mas extremamente difícil. Isso porque, ao final de um ciclo, você terá que testar se nenhum comportamento esperado foi alterado.

Por isso, de forma a simplificar, não fazemos refactoring sem testes. Caso o seu sistema não tenha testes, primeiro, faça o teste. Depois faça o Refactoring. Nisso podemos encaixar o TDD. O próprio trabalho de escrever os testes te ajudará a decidir o que mudar, a melhor forma, etc.

Reinstalando O Vim Na Sua Máquina Com Suporte a Python E Ruby

| Comments

Esse é um post para ajudar a me lembrar de uma procedimento e quem sabe ajudar alguém com o mesmo problema.

Eu uso como editor padrão o VIM (algumas vezes o MACVim). Além disso uso muito Python e Ruby como linguagens para desenvolver meus projetos. Para facilitar esse meu dia a dia, uso alguns plugins que me ajudam como por exemplo o python-mode e o jedi. O python-mode ajuda com as validações de pep8, pyflakes, etc. Já o jedi ajuda nos imports do python. Para ruby eu tenho o sintaxe highlight mesmo.

Tudo isso funciona perfeitamente no meu MACVim, porém no vim não estava funcionando. Ambos tinham sido instalados via homebrew. Buscando pelo Google, achei que a solução era compilar o vim manualmente. Isso realmente resolveu meu problema, e segue abaixo os passos que fiz. Primeiro certifique-se tem instalado o mercury no seu computador (hg).

hg clone https://vim.googlecode.com/hg/ vim_source cd vim_source ./configure —disable-nls —enable-multibyte —with-tlib=ncurses —enable-pythoninterp —enable-rubyinterp —with-features=huge make -j 3 && sudo make install

Com isso o sistema irá reinstalar todo o vim com os suportes e links corretos.

Espero que ajuda alguém.

Code Review

| Comments

TL; DR;

Embora toda experiência, conhecimento de processos e boas práticas, ninguém está imune a cometer erros, escrever código com BUG e/ou ruim. Todo ser humano é imperfeito e está fadado a cometer erros mesmo que sendo um gênio e tendo um profundo conhecimento. BUGS e códigos mal escritos não são somente fruto de desconhecimento e despreparo mas também, de condições e contextos no qual o desenvolvedor está inserido. Sendo assim, a questão não está em não cometer o erro (bugs, código mal escrito, etc) e sim procurar formas de detectá-lo o mas breve possível evitando assim que esse tenha um ciclo de vida longo.

O problema do código feio

“Escrever código para máquina é fácil.”

Nem sempre os problemas de um sistema estão em BUGs ou aderência aos requisitos. Muitas vezes, para não dizer a maioria, os maiores problema estão em códigos mal escritos, difícies de manter, duplicados, sem padrão, etc. Isso se agrava quando falamos em projetos onde temos mais de uma pessoa envolvida e com mudanças na equipes (entrada de pessoas novas por exemplo). Logo, é preciso buscar formas para que esse tipo de coisas não aconteça.

Escrever código também é uma forma de comunicação e é necessário dar a essa prática a mesma atenção de um texto. Embora, códigos sejam instruções para computadores realizar, é preciso pensar em quem irá ler esse código e ter em mente que essa pessoa tem que ser capaz de entender corretamente a mensagem e propósito da arquitetura e forma deste sitema. Outros além dos autores iniciais, muito provávelmente, irão dar manutenção, e com isso precisarão entender bem como as peças se encaixam para resolver o domínio.

Falhar em escrever um código legível, compreensível, com padrões perceptivos, é escrever código legado e fadado a morte.

Código bem feito leva a todos futuros autores a seguir um padrão e a entender sem grandes esforços como as relações se desenrolam. No oposto, código mal escrito, o efeito é inverso: têm-se um empilhamento de funcionalidades, duplicações, diversos padrões, formas, código obscuro, etc.

Estudos e estudiosos do assunto

Tendo como ponto de partida o fato de que código é uma forma de comunicação semelhante as demais e que é preciso buscar a excelência nisso, muitos estudiosos do assunto buscam formas, processos, ferramentas, para evitar que se produza código ruins (mal escritos). Linguagens como Python, Java, etc criam convensões de boas práticas, code styles (estilo de escrita de software). IDE’s criam validadores de sintaxe. Estudiosos de processo, procuram por práticas para ajudar o desenvolver a não escrever ou achar os defeitos o mais breve possível.

Existe um artigo interessante no site de developer da IBM que lista as 11 praticas provadas que realmente ajudam na revisão de código Leia o artigo.

A revisão de código é uma das práticas, juntamente com o Pair Programming (programação em pares) que vêem de encontro a resolver o problema de código ruim. A programação em par é a prática onde duas pessoas trabalham juntas na concepção e escrita da funcionalidade. Ela resolve em parte o problema pois são dois pares de olhos vendo. Porém, ainda é possível escrever coisas que não sejam “legíveis” a futuros programadores daquele sistema.

A revisão de código tem sido mais eficiente nesse sentido. Revisar um código não consiste apenas em outras pessoas lerem o código escrito antes de alguma determinada etapa. Consiste no uso de ferramentas e analisadores também. Inclusive uma boa prática é se algo pode ser analisado pelo computador é melhor que ele que faça e não outro, como por exemplo, complexidade ciclomática, code styles, duplicação, etc.

Como resolver, como fazer para implementar essa prática

Uma vez que se tenha optador pela revisão de código, o primeiro passo consiste em simplesmente fazer. Começar da forma que o time desejar. Os ajustes, como toda boa prática, vem com tempo, e na medida da maturidade e domínio do processo, vai se mudando e adaptando.

. Como já foi abordado acima, devem buscar ferramentas para analisar a base de código nos mais diversos aspectos. Linguagens como python tem analisadores de pep8(conjunto de boas práticas de escrita de código), analisadores estáticos (analisam variaveis, duplicidade, e outra coisas); já Java tem IDE’s que vem com suite grande de ferramentas nesse mesmo sentido. Já em Ruby e Javascript tais coisas são trabalhos em andamento.que vem com suite grande de ferramentas nesse mesmo sentido. Já em Ruby e Javascript tais coisas são trabalhos em andamento.

. todos tem seu código revisto. Não é só responsabilidade os engenheiros senior revisar. É de todos.

. Uma boa forma é que o código só seja enviado para o repositório (git, svn, etc) se foi revisado. Por isso, o desenvolvedor antes de comitar ou dar push chama outra pessoa e faz.

. Projetos com times grandes podem trabalhar, caso seja usem coisas semelhantes a git, usar patches. Assim, cada um tem seu “repositorio” e na hora de integrar criam e enviam um patch. Esse patch irá ser revisto por algum outro membro.

. Evite fazer com muito código. O ideal, segundo o artigo citado, é não passar de 200 a 400 linhas de código. Isso reforçar o conceito de fazer pequenos passos e ir enviando para o repositorio.

. Evite o efeito Big Brother… Faça reviews abertos e de forma clara. Deixe tudo muito aberto e simples.

. Torne a prática uma cultura do time e não mais um processo a seguir. A revisão de código deve ser desejada por todos e seguida. Pedida.

Concluindo

Independente da forma e de como irá realizar, é importante entender que código deve ser legível. Código deve ser compreensível a outros humanos também, não somente a máquina. Isso irá aumentar a vida do sistema, facilitar novos colaboradores (para os casos de open source), etc.

Code Review é uma boa forma de garantir isso.

Leia mais

Effective Code Review – Alex Gaynor

What Makes Peer Code Review an Agile Process? – Lyndsey Clevessy

Running an Effective Code Review – Esther Schindler

Criando Widgets Javascript

| Comments

TL;DR;

Nos projetos atuais nos quais trabalho, muitas vezes acabamos fazendo o que chamados de Widget. Esses widget são feitos para serem “inseridos” e usados outros portais e produtos. Na maioria dos casos, esses widgets são como apps escritas em javascript para consumir uma api e montar um dado dentro da página onde ele foi inserido.

O Leonardo Balter numa palestra que ele deu no Front in Rio 2012, abordou bem o assunto sobre como podemos escrever frontend apps sem inteferir no contexto da página onde está posta. Por isso pretendo apenas extender o conceito.

Contextualizando

Vamos lá, a grande maioria das pessoas, atualmente, que dizem conhecer e saber programar, apps front, faz uso de alguma biblioteca. Sem grandes pesquisas, creio que a maioria delas deva usar algo como JQuery, Mootools, BackBoneJs, AngularJS, ou similares.

Tais libs são “uma mão na roda” e realmente facilitam a codificar, testar, etc.

A pergunta que faço é: Precisamos de todos os recursos disponíveis nesses frameworks/bibliotecas? Acredito que na maioria dos casos, se escrevessemos somente em Javascript puro, usando HTML e CSS, e não mais do que isso, conseguiríamos entregar o desejado.

Entendendo o “Problema”

Ao analisar mais detalhadamente a situação, conversando com alguns colegas especialistas em front end e com outros nem tão especialista assim. Uma das coisas que notei é que muito deles não conhecia de fato Javascript: Sabiam detalhes de cada elemento HTML, funções e motivos de cada linha de CSS; entretando desconheciam recursos básicos da linguagem Javascript, como por exemplo, fazer um laço de for (muito usavam a, por exemplo, a função each do jquery).

Com isso, é possível concluir uma exagerada dependência de bibliotecas, para fazer coisas que são perfeitamente possíveis de serem feitas sem elas, usando apenas JS puro. O resultado disso, são widgets com megas de tamanho, sendo que a lógica deles mesmo são meros kilobytes, o restante são as bibliotecas que eles carregam junto (Jquery tem minificado 93kb, veja o site). Isso pode parecer um detalhe banal num mundo onde casas tem links de Mb… Porém uma nova variável se apresentou no horizonte que é o mundo do mobile.

Outro ponto interessante foi uma pesquisa recente (não consegui achar o link) onde afirma que, sites que são lentos para carregar tem menor taxa de conversão. Isso mesmo, tempo é dinheiro, literalmente. Se o seu site leva mais de 5 segundos para mostrar algo, já se foram quase 50% das pessoas aí (CHUTE!!!!).

Voltando para o mobile, ter sites grandes e pesados de carregar significa mais gasto de 3g e bateria. Maximiliano Firtman, fez numa edição do BrazilJS, uma ótima apresentação sobre o assunto, onde mostar números, dados mais concretos que meus chutes. E as pessoas tem pouca paciência – menos ainda no mobile, pode cre – para esperar seu site gigante carregar todas as libs e processá-las.

Mais aí você pode dizer, que usa a técnica de deixar o carregamento no final de página. Desculpa meu amigo, mas o seu site ainda é pesado de carregar, vai consumir bando e bateria no mobile e pode gerar alguma perda na entrega de conteúdo.

Ok. Dito isso, voltemos paras os widgets.

Se você está criando uma widget e esse tem dependências de centenas de kb de libs (template lib, dom lib, ajax lib, etc) você se encaixa na mesma análise. E pior. Você está fazendo isso com qualquer um que use seu código – as vezes sem saber da âncora que você é no site deles.

Outro aspecto de widget gordos (vou chamá-los assim para facilitar), é que eles também podem gerar conflitos com outras coisa na páginas dos outros: imagine a questão das versões como podem gerar um verdadeiro inferno.

Os conflitos

Para seguir adiante com a discussão é importante que fique claro que menos é mais: ou seja, quão menor for sua app/widget, melhor. Não se iluda, isso dá trabalho. Abrir mão de libs, significa você cuidar de vários detalhes antes abstraídos, porém, posso garantir que o resultado compensa.

Gosto sempre de usar exemplos. Acredito que eles sejam a melhor forma de mostrar um ponto de vista. No meu trabalho fizemos um widget. Esse widget vai em quase todos os produtos e portais e portanto é bem usado. Esse widget, no momento que foi feito, fizeram a escolha de implementá-lo usando libs. Pois bem.

Até aí foi uma escolha simples e até bem intencionada. Com o uso de libs e seus recursos muita complexidade seria resolvida e os desenvolvedores ganhariam tempo para lidar com os desafios do produto e não dos navegadores, etc.

O problema é que com isso, prendemos nossa solução a uma lib e sua versão. Obrigamos os produtos que queriam usar esse widget e ter essa versão, essa lib.

Os mais experientes já devem estar imaginando o cenário que isso nos levou… Hoje temos diversos produtos usando a implementação e reclamando do tamanho, do fato de termos uma versão muito antiga, conflito com implementações.

Nesse caso em específico, além do uso de libs, houve um sério problema de engenharia de software. Poderíamos ter componentizado melhor, separado melhor e essa mudança para versão mais nova seria mais simples. Entretanto, nos amarramos demais a biblioteca e agora teremos que reescrever tudo.

Para coroar nossa análise, se tivessemos usado simples JS puro – isso daria trabalho mais é totalmente possível – agora teríamos um produto bem mais fácil de evoluir e não atrapalharíamos a vida de nossos clientes/usuários.

No mesmo tempo que essa app foi feita, uma outra app foi feita por outro time. Também é usada por todos os portais. A diferença é que eles optaram por fazer com VanillaJS. Deu muito trabalho, problemas de cross-browser para resolver, ajax, etc. Mas no final eles conseguiram e tem sido um benchmark para nós todos. Eles provaram que a entrega foi bem melhor e com usuários felizes.

A conclusão

Vamos lá a formula de bolo para ajudar a:

  1. Tentar sempre usar somente javascript. Mais nada
  2. Lembre de isolar bem o seu contexto de váriaveis.
  3. Sempre que possível use de namespaces/
  4. Se não der para usar só js, procure por um micro framework para resolver o seu problema de forma bem específica. Embede o código dessa lib na sua.
  5. Menos código, menos bugs.
  6. Seja cuidadoso e sempre se coloque no lugar da pessoar que irá usar.

“Escreva como se a pessoa que fosse usar seja um psicopata e sabe onde mora”

VOCÊ NÃO É O TWITTER

| Comments

TL;DR

Surgiram atualmente diversos artigos onde grandes e famosos produtos (e players da internet) explicam como o time de engenharia mudou a tecnologia/ linguagens e conseguiu maravilhas em redução de máquina e aumento de carga em seus sistemas.

A grande maioria dos que li, usavam Ruby on Rails e passaram a usar Java (inclua aqui Scala, Groovy, Clojure) ou Go ou até Python em seu lugar, e com isso, reduziram drásticamente o custo de infra (energia, máquinas, resfriamente, etc) e/ou aumentaram sua capacidade carga (quantidade de requisições, conexões, etc). Enfim, foram além da simples troca de arquitetura.

Entretanto, antes que todos comecem a demonizar Ruby e/ou as ditas linguagens modernas é preciso analisar o contexto desses artigos e entender que nem de longe somos um Twitter para nos preocuparmos com esse tipo de coisa agora.

Um pouco sobre mim e porque posso falar sobre o assunto

Tenho em torno de 12 anos de profissão. Hoje, sou desenvolvedor senior da Globo.com, atuando no time de jornalismo – responsável por sites como G1, Ego, Cobertura de Eventos, etc.

A Globo.com é uma empresa onde se desenvolve os maiores portais de jornalismos, esportes e entretenimento do Brasil . Fora isso, temos plataformas de vídeos, imagens, música, em milhares de outras coisa.

Uma das coisas legais de se trabalhar lá é o fato de sempre procurarmos a melhor ferramenta para o trabalho. E com isso, sempre estamos experimentando as tecnologias, linguagens, plataformas, e tudo mais que nos permite sermos mais produtivos e eficientes.

Atualmente a grande maioria dos produtos que desenvolvemos são feitos usando Python e Ruby (e seus frameworks como Tornado, Django, Ruby on Rails, Sinatra, etc).

Nossos produtos tem acessos bem grandes: Portais com milhões de vísitas únicas por dia; streaming de vídeos na faixa de gigabytes por dia, terabytes de arquivos (imagens, html, css, javascripts) e por aí vai.

Diferenciando um pouco …

Diante do relato acima muitos poderiam pensar que Globo.com, deva ter as mesmas preocupações que um Facebook, Twitter ou SoundCloud.

Posso adiantar que, sobre determinados aspectos, sim: Nenhum de nossas aplicações e novas funcionalidades vão para “produção” (para uso do nossos usúarios) sem que antes façamos bons testes de carga, testes de segurança, entre outras coisas relacionadas. Ainda na fase de desenvolvimento, temos a preocupação de fazermos coisa que deverão aguentar milhões de acessos, milhares de conexões simultaneas, picos, etc, sem jamais deixar de atender uma requisição.

Porém se compararmos nosso volume de acesso e nosso tipo de produto, não somos parecidos com o pessoal do Twitter, Google, SoundCloud, entre outros.

Nossos produtos são em sua maioria estáticos: Um vez que são produzidos, nos geramos uma cópia estática e a servimos para os clientes. O Twitter, por exemplo, tem um natureza muito mais dinâmica: o conteúdo é servido por usuário (com toda certeza deve existir um cache no meio do caminho) a cada requisição.

Entendendo o problema e o contexto

Quando pensamos em Google, SoundCloud, logo pensamos em um datacenter gigantesco com milhares de máquinas. Tudo isso para atender a grande demanda de processamento que é gerada pelas milhões de requisições que os usuários fazem. São buscas, buscas por músicas, cadastros de novos usuários, posts, documentos, edição, envio de novo conteúdo, etc.

Para esse tipo de acesso, um pouco que se possa ganhar em desempenho, seja por uma escolha de arquitetura, seja pela troca de linguagem é algo muito significativo.

Lembre-se que estamos falando de parques com milhares máquinas.

Isso porque se conseguirmos, num cenários desses, reduzir em 10% a quantidade de máquinas e processamento, imaginem o quanto de dinheiro que isso representa na conta no final do mês. Muito né.

Por isso que empresas e aplicativos desse porte, precisam, constantemente, buscar por meios de reduzir processamento e atender mais requisições. Por que empresas como essas correm atrás de tecnologias, arquitetura, linguagens, etc que possam ajudá-las nessa missão, nem que sejam em 1%.

Onde eu entro nisso tudo? Porque eu não sou o twitter?

A grande maioria das pessoas, hoje em dia, está desenvolvendo sistemas que mal atenderão um milhar de pessoas. Existe uma infinidade de pessoas estão trabalhar em projetos de aplicações internas a empresas, os ditos corporativos.

Pouquíssimos são aqueles que estão desenvolvendo algo para uma quantidade superior a centenas de milhares. Nem vou falar naqueles que estão desenvolvendo para milhões.

Enfim, a grande maioria, está criando produtos para no máximo milhares de acessos.

Alguns podem dizer: eu tenho a minha startup e estou desenvolvendo um produto . E quero muito que ele atinja milhões de usuários como um Facebook. Entretando, novamente, a grande maioria em seu lançamento contará com centenas de acesso e terá um crescimento bem linear e vegetativo.

Mesmo que ocorra um boom no acesso, isso é bem pouco provável, não é preciso pensar nisso quando nem o produto existe ainda.

O que quero dizer é que antes que comecemos a fazer a guerra de dizer que agora todos nós devemos largar o Ruby on Rails, ou Django, ou PHP, etc e partir para desenvolver em Assembly, precisamos entender que isso ainda não é o nosso problema.

Nosso problema é ainda entregar valor para o cliente o mais rápido possível. Para grande maioria de nossas aplicações o custo de infra é infimo – quase desprezível – frente ao custo de desenvolvimento. Por isso usar de tecnologias de nos dê produtividade ainda é a melhor escolha.

Fazendo referência ao título do POST, não somos o Twitter, e por isso não devemos ainda nos perder nessas dicussões.

Um grande porém …

Porém, mesmo que a gente não esteja na equipe de desenvolvimento da engine de busca do Google, precisamos estar antenados com que acontece a nosso redor. É legal saber que mudanças de arquitetura e tecnologia podem ter um impacto em nosso produtos.

Mais importante é saber das opções existente e a experiência de missão crítica desses grandes players e quem sabe, quando precisarmos, seguir por um caminho menos obscuro.

Hoje na Globo.com já estamos discutindo usar outras coisa além de Python e Ruby. Não descatarmos por completo JVM e estamos já criando coisas com Go.

Esse era o recado que gostaria de deixar para vocês.

Sistemas Com Responsabilidades únicas

| Comments

Introdução

Muitos desenvolvedores já estão familiarizados com diversos princípios de engenharia de software, como por exemplo alguns enunciados pelo livro Clean Code . Tais princípios ficaram eternizados com a sigla SOLID, que é acronimo e significa:

Single Responsability Principle ( Principio de Responsabilidade Única);

Open Close Principle ( Principio do aberto para extensão e fechado para modificação);

Liskov Substitution Principle (A classe filha pode ser substituida pela classe pai);

Interface Segregation Principle (expor interfaces não objetos);

Dependency Inversion Principle ( Dependencias baseadas na abstração e não nas implementações concretas )

Para saber um pouco mais, siga clicando aqui*

Aplicando essa definições em nossos código, a idéia é ter um código mais limpo: código legível; fácil de compreender por outros desenvolvedores; simples de evoluir; simples de manutenciar; etc. A questão é que, mesmo usando toda essa engenharia, todos nossos sistemas atuais tendem a crescer e ganhar complexidade.

Todos os sistemas nascem simples: com responsabilidades únicas e bem definidas. Assim após a nossa primeira release, nosso sistemas evolui, ganhando novas funcionalidades, acertos, melhorias , ajustes para melhorar perfomance, refactorings, etc. Com o passar do tempo, nosso pequena e bem escrito aplicativo, torna-se um megazord de complexidade, duplicidade de código, e outras coisas que nenhum de nós gosta. Enfim, ele se torna um grande legado que ninguém quer mais mexer.

Tenho certeza que todos tem algum projeto que trabalhou que serve de exemplo para a situação descrita acima. Lembra daquele sistema que tinha, lá no início, algumas centenas de linha de código apenas e já de milhares (até milhões); ou/e daquele projeto super bem arquitetado e hoje é uma bagunça sem fim que até mesmo que trabalhou desde início se perde para entender como as chamadas trafegam para completar uma requisição.

Mesmo que esse ditos projetos estejam usando testes automatizados e tenha sidos feitos seguindo princípios como TDD. Mesmo que eles sofram refactorings constantes, o fato é que eles crescem e vão adquirindo novas responsabilidades antes não previstas. Com isso, vamos torcendo aquele modelo original e amontando código.

Diante disso, o que vejo e vivencio é que a medida que essas bases de código crescem, fica impossível de manter principios de reutilização, DRY, padrões de nomes, code style, e diversas outras coisas importantes. Enfm, acabamos um imenso legado que é caro demais de evoluir, muito caro de reescrever e muito importante para nosso cliente que não abra mão dele e tem novas necessidades a serem atendidas.

Nosso dilema atual

Como disse, os sistemas crescem. E com eles suas bases de código.

Poderíamos dizer que este problema já é conhecido e muito bem abordado pelo Michael Feathers em seu livro sobre código legado: podemos sim isolar e aplicar todas as técnicas sugeridas, mas bases de código grandes, são bases de código grandes e ponto final. Pdemos melhorar os métodos, encapsular melhor algumas, etc … a questão que ainda temos um modelo que não foi feito para aqueles novos casos, ainda temos situações novas que não estavam previstas e poucas possibilidades de interface do nosso sistema.

Se não existessem os problemas financeiros ou quaisquer outras constraints tenho certeza que a maioria dos desenvolvedores, diriam que está na hora de reescrever todo o sistema. Todos nós adoramos projetos Green Field (projetos que estão começando do zero).

Em novos projetos, temos as oportunidade de desenhar bem a nossa arquitetura, aplicar novos conceitos e utilizar novas tecnologias.

A questão é que fazer isso com sistemas de milhares de linhas de código é uma tarefa árdua e que custa bastante caro – nenhum gerente, cliente, PO… vai querer pagar por isso – até porque você não estará entregando nenhum valor novo (estará sim se pensarmos em infra, mais request, e outras coisas parecidas, mas poucos clientes percebem isso logo de cara)

Motivos para reescrever sistemas

  1. Tecnologias caducam, envelhecem:

Muitas tecnologias se tornam ao longo do tempo obsoletas e ultrapassadas. Sempre temos uma nova versão da linguagem, um novo servidor, um banco de dados mais moderno ou que utilize um outro paradigma que resolve melhor o seu problema… enfim a tecnologia evolui e traz novas soluções – e melhores – para os nosso problemas.

  1. Nós aprendemos:

Com o passar do tempo e com a experiência vemos que, nem sempre o caminho que adotamos foi o melhor. Também vemos que existem jeitos melhores de implementar determinada lógica.

Existe o fato também, que evoluímos como profissionais: com isso vemos que aquele sistema que fizemos a um tempo atrás, poderia ter sido feito de um jeito diferente. Infelizmente mudanças desse tipo não dá para fazer de forma gradual. Geralmente, eles são mudanças radicais e temos que fazer tudo de uma vez só.

  1. todo sistema tem prazo de validade:

Um outro bom motivo para reescrevermos nosso sistema é ligado ao negócio. Muitas vezes vemos que a forma de nosso negócio mudou e que o sistema atual com sua base de código infinita não nos atende mais. Mesmo que façamos diversos apendices, o sistema não é mais capaz de nos atender com proficiencia. Se tornam aqueles sistemas cheios de jeitinhos para fazer coisas. O usuário tem que fazer um cursinho para saber todos os “pulos do gato” para ele conseguir concretizar uma operação. Sistemas ERPs são os melhores exemplos disso. Você acaba torcendo o seu problema para caber dentro daquele sistema que é impossível de mudar ou reescrever.

Vamos ao que interessa

Fica um bom tempo falando sobre a questão de engenharia de software e do problema de sistemas com muitas linhas de código. Falei também dos motivos que podemo nos levar a querer reescrever um sitemas. Mas para que?

Escrevi sobre tudo isso para mostrar que precisamos dar o passo seguinte no desenvolvimentos de software. Precisamos pensar em sistemas como peças únicas de um conjunto para resolver problemas. Sendo assim, essas unidade deve ser responsavel por resolver um e somente um aspecto do problema e não todo ele. A solução se dá pela soma das partes que agindo em conjunto atendem ao nosso domínio.

Precisamos aplicar os conceitos de SRP (veja acima) na concepção de nosso sistemas. Ao invés de fazermos uma peça única e monolítica que aborde todo o nosso dominio, fazmemos pequenas partes que cuidam de cada aspecto.

Ganhamos com isso sistemas pequenos, e simples de manter. Num caso que li recentemente, cada peça ficou com poucas centenas de linhas. Isso facilita manter pois bases pequenas são mais simples. Bases pequenas são mais fácil de entender e manter seu padrões; bases pequenas são mais fácil de jogar fora e fazer de novo. No mesmo case que citei acima, eles reescrevem uma parte em uma semana e foi imperceptível para o cliente.

Outro aspecto é que se fizermos com pequenas partes e essas partes existirem independentes uma das outras, podemos ir além. Imagine que eu quebre o sistema em diversos serviços que se falem via REST: eu posso literalmente escrever cada serviço numa linguagem diferente que não vai causar nenhum problema. Com isso posso escolher a melhor tecnologia/linguagem para o meu problema. Além disso, mantendo as interfaces, eu posso refazer todo a parte interna sem afetar as outras peças do conjunto.

Isso é simplesmente o céu de todo desenvolvedor.

Em meu trabalho atual estamos caminhando para algo parecido. Ou seja, uma forma mais orientada a serviços, onde cada sistema tem uma responsabilidade e essa é simples. Manter essa coisa simples e com pouca coisa para resolver é a grande chave do sucesso.

Se olhar arquitetura de grandes portais, produtos web (como [Twitter][4], basecamp, SoundCloud, etc) verá um monte de pequenos sistemas conversando para atender a demanda do usuário.

Se uma parte se tornar o gargalo, podemos melhorar só aquela parte: colocando mais servidores, reescrevendo, etc.

Isso é aplicavel a qualquer contexto.

A alguns anos atrás trabalhei numa empresa que tinha diversos sistemas que eram integrados através de troca de mensagens (queue e brokers). Claro que nem chega perto do que estou propondo mais foi uma semente e vi que dava muito certo.

Cenas do próximos capítulos …

Mais a frente – estou terminando de organizar tudo – pretendo publicar um novo post explicando melhor como implementar essa questão de sistemas pequenos e com pouco responsabilidade.

Só para deixar curioso, existem formas de fazer sem necessáriamente escrever um monte de sistemas; como existem formas de fazer de forma bem desacoplada. Enfim fiquem ligados.

Design Pattern E Linguagens Dinamicas

| Comments

Logo na introdução do livro do GoF, na primeira frase que acredita ser da maior importância para quem deseja ser um desenvolvedor. É ela : “Projetar software orientado a objetos é difícil, mas projetar software reutilizável orientado a objetos é ainda mais complicado” .

Fazendo a ponte com um post anterior, escrever código de qualidade, sem saber algo sobre Padrões de Arquitetura (design patterns) é quase impossível. Brinco até que está difícil de estar trabalhando sem saber isso, pois quase toda entrevista o pessoal adora perguntar algo do assunto. Fora esse aspecto de seleção, saber patterns é uma boa forma de começar a escrever bons sistemas.

Patterns foram uma verdade absoluta, uma lei escrita em pedra até a muito pouco tempo atrás. Ouso dizer que para muitos é quase um axioma onde se um dia for quebrado alterará o equilíbrio da “vida no universo”. Entretanto, com o crescimento do uso de linguagens dinamicas e com paradigmas de classe aberta, parece que a coisa tem mudado um tanto.

Muitos fazem “piadas” com o livro do Gof (Gang of Four – Design Patterns, Eirc Gamma, Richard Helm, Ralph Johson e John Vlissides), dizendo que na verdade o título de livro deveria ser “Como tornar o C++/ Java menos ruim”, pois a maioria das soluções apresentadas giram em torno da deficiencias dessas linguagens (Tipagem estática, falta de closures, não ter funções como first class, não terem modelos de open class, etc) . Sendo, assim, quando temos uma linguagem que não tem essas tais limitações, usar patterns é algo desnecessário.

Concordo em parte com o parágrafo acima. Primeiro é preciso considerar que o livro foi escrito à mais de 14 anos ( primeira edição saiu em 1996 ou 1997) e pouco se conhecia de linguagens como Python, Ruby, Groovy, Scala, entre outras semelhantes (embora algumas já existissem). As duas linguagens que vinham sendo usadas em larga escala eram exatamente o Java e o C++.

Outro aspecto que devemos levar em consideração é que mesmo usando uma linguagem dita moderna, isso não invalida o uso ou conhecimento de padrões de arquitetura. Muito pelo contrário: é importante que conheçamos as motivações por trás de tudo, para que possamos adaptar a nova realidade as soluções catalogadas.

É praticamente impossível pensarmos em escrever uma aplicação, ela ser entregue e jamais ser tocada novamente. Na maioria dos casos ela evoluirá com ou sem o nosso consentimento ou participação. Sendo assim, escrever usando ou baseando-se em padrões facilita em muito o entendimento dos futuros donos deste sistema e além do mais. Quando falamos de equipe, até a comunicação do “como deve ser feito” fica facilitada: “Vamos fazer com um pattern de DTO, por iso temos que fazer os Value Objects, etc”.

Linguagens Dinamicas tem melhores ferramentas:

Tomando como base Python, Ruby e Groovy, linguagens dinamicas possuem um leque maior de recursos que facilitam em muito criarmos sistemas que evoluam facilmente. Recursos como closures, open class (classes abertas), blocos, generadores, decorators, etc, num primeiro momento chegam a negar a necessidade de se criar modelos complexos .

Para que criar um modelo complicado de interfaces, heranças, composições e etc quando podemos simplesmente passar um função como argumento, ou então, capturar e criarmos métodos que ainda nem existem ?

Todos esses recurso facilitam em muito a criarmos sistemas que são simples de evoluir e reutilizar.

Uma coisa não exclui a outra

Diante de tudo que foi dito acima, poderia simplesmente, sem muito medo de errar, dizer que Designs Patterns são obsoletos e desnecessários frente a novas ferramentas que possuímos hoje.

Como já disse, concordo em parte com tal afirmação. Muitas limitações deixam de existir e com isso a necessidade de contorná-las, porém, outros problemas persistem ou tantos outros surgiram.

Padrões não devem ser usados como verdades absolutas e sim como guias para a construção de um sistema bem feito. Conhêce-los é como uma receita: enquanto estamos aprendendo seguimos-as sem alterar nada, entretanto, a medida que ganhamos experiência sentimos confiante a mudar um pouco e inovar. Vale ressaltar que não saímos do nada. Não “reinventamos a roda”. Adaptamos algo que já se provou sucedido a nossa realidade e ferramentas.

Algumas referências sobre o assunto

Neal Ford tem uma excelente apresentação que fez na Oscon de 2009, onde mostra que algum patterns não fazem mais sentido, porém outros ainda se mostram atuais. Uncle Bob, em um vídeo e texto em seu blog faz uma afirmação parecida: Diz que design patterns ainda são tão atuais quanto antes e importantes. As bases que compões as soluções ainda são “sólidas” – preferir composição a herança.

Convido a quem está lendo a pelo menos conhecer algumas soluções para até mesmo ter do que falar mal. Verá que mudará a forma como pensa a solução.

Escrevendo Código Limpo

| Comments

Gostaria de começar este artigo com uma frase que está no início do primeiro capítulo do livro CleanCode do UncleBob: “You are reading this book for two reasons. First, you are a programmer. Second, you want to be a better programmer. Good, we need better programmers.”

Vivemos num momento interessante dentro da profissão de desenvolver sistemas: temos as metodologias ágeis, direcionamentos onde o foco é o ser humano (Peopleware), a busca pela qualidade e pelo desempenho ganham forma e embaseamento, a maturidade nos leva a uma busca constante de excelência, e outras coisas.

Um exemplo disso são os diversos processos e práticas que tem surgido – e solidificado – nos últimos tempos como TDD, BDD, SOLID (veja no livro do Clean Code – Robert Martin aka “Uncle Bob”), etc. Apesar de pessoalmente acreditar que tais iniciativas sejam importantes e determinantes para entregarmos sistemas de qualidade, penso que ainda precisamos de um “algo mais”.

Escrever “código”, ao contrário do que muitos pensam, não é uma atividade simples. Segundo Brian Kernigan – coautor de AWK programing language, “é quase o mais complicado dos empreendimentos humanos” . Todo sistema nasce simples e consciso. Todo sistema nasce bem feito, porém com o passar do tempo e de seu uso e constantes evoluções sua complexidade aumentam e sua “qualidade” provavelmente cai. Mesmo que ele tenha 100% de cobertura de testes (coisa que no mundo real é um grande feito) e seu time siga a risca todas as regras.

TDD e BDD importam

Antes de mais nada, gostaria de dizer que nada justifica um código sem testes. Testes são uma parte fundamental de um bom código. E eu disse testes. Não disse que fazer TDD ou BDD. Testes garantem um forma simples de manter a aderência as especificações e segurança para realizar futuras mudanças. Autores como Michael Feathers [Working Effectivily with Legacy Code], chegam afirmar que sem testes não existe a possibilidade da melhora contínua, disciplina essencial para termos bons bases de código.

TDD (Test Driven Development) e BDD(Behave Driven Development) são extrapolações de testes, onde os usamos para nos guiar na busca de uma melhor arquitetura. É possível termos testes automatizados sem seguir tais práticas, porém o contrário não.

TDD e BDD são ótimas ajudantes para termos sistemas robustos e bem feitos, para termos “códigos limpos”, mas como disse antes, não são o suficiente.

Design Patterns e princípios como SOLID importam

Acredito que a maioria das pessoas que leêm meu blog, são pessoas que se preocupam com a qualidade de seus sistemas. Isso deve se refletir em estudos e muita leitura. Sendo assim, creio que a maior parte já tiveram contato – ou até dominam – assuntos como padrões de projetos, refactoring, SOLID, etc.

Vou além, e digo que muitos usam tais conhecimentos em seus dias a dias quando estão a trabalhar em seus projetos.

Tais principio são a “pedra fundamental” sobre o qual o resto todo se apoia. São as tais regras de ouro. Por isso são de extrema importância. Conhecê-las faz um imenso diferencial no código que produzimos pois nos tornamos mais conscientes e preocupados.

Entretanto, somente isso não significa termos um sistema robusto e de qualidade. Já trabalhei em muitos projetos cujos os colegas dominavam e sabiam de “coeur” cada palavra do Design Pattern, mas produziam código sujos e com pouca qualidade.

O que é qualidade? Como é um código de qualidade?

Responder essa pergunta não é algo simples e estou longe de ter as credencias necessárias para me atrever a tamanha responsabilidade. Por isso, recorri aos grandes autores já citados para buscar o que seria a tal qualidade almejada tanto em nossos código.

Em sua grande maioria, os autores que li (Martin Fowler, Kent Beck, Michael Feather, Uncle Bob, Erich Gamma, Joshua Kerievsky, entre outros) concordam em alguns pontos que listo abaixo.

  • Código bom é aquele que sobrevive ao seu autor: código deve ser escrito não para compiladores e sim para pessoas. Código bom é aquele que é fácil de entender e compreender a sua forma. Comunica com clareza a sua função e razão de ser.

  • Código tem que ser simples: a complexidade se dá pela soma das partes. Código simples divide o problema em partes menores e as resolve. E no final chama essas pequenas partes para compor o todo da solução

  • Código bom é aquele “manutenciavel”: possui toda o ambiente necessário para que ele seja facil de evoluir: testes, documentação, etc.

  • Código que vai além da especificação funcional: um bom código vai além das especificações do cliente. Ele procura cobrir todos os cenários e estar preparado para as situações não previstas; ele é feito por “não otimistas” (explica mais a frente).

Com eu faço de qualidade? Além de TDD (BDD), Patterns, SOLID, o que mais precisa ser feito?

A resposta é mais simples do que você imagina:

DISCIPLINA

Saber tudo isso não significa e nem faz a mágica de tornar o seu código maravilhoso. Eu falo isso com propriedade. Por muitas vezes sou um feroz defensor de boas práticas e então, meus colegas acham código meu sem teste, mal escrito, com erros de implementação, etc.

Um outro aspecto é a constante verificação da complexidade, qualidade e cobertura de seu código. A disciplina não será nada se não houver um objetivo à atingir.

Outra coisa na qual acredito é que devemos ser menos otimistas ao escrever nossos sistemas. Citando dois amigos – Leonardo Balter e Alexandre Martins – precisamos de trocar o “boné de programador” e fazer mais “Testes de trollagem”. Precisamos tentar a todo custo testar os limites do que estamos fazendo. Precisamos ir além da especificação. Michael T. Nygard em seu livro, Release It, diz que sistemas que precisam pensar em suas possíveis falhas e serem capazes de suportar os cenários não previstos.

Inclusive, existe um excelente artigo do pessoal da NetFlix, sobre uma ferramenta chamada de Caos Monkey. Essas ferramenta derruba os servidores e analisa como o sistema se comporta para verificar se tudo é robusto. Isso é um aspecto muito esquecido nas aplicações e cada vez mais determinante na entrega.

Tenho um caso de um sistema muito bem feito, com testes, boa arquitetura, etc, que falhou vergonhasamente quando foi para produção pois esqueceram de configurar o cache corretamente. Pensar nisso é ter a visão holística de que tanto falam diversos autores.

Ferramentas para ajudar

Uma grande ferramenta sem dúvida são os testes automatizados. Outra tão boa quanto são aquelas que “medem” diversos parametros, com frequencia de sua base de código, como: dependência ciclomática; duplicidade de código; aderência a convenções de código (Pep8 para python, JSLint, CodeStyle para Java, etc); analise de perfomance; tolerância a falhas; etc.

Ter um servidor de CI (integração contínua) rodando essas ferramentas, testes, e outras coisas que sejam importantes para o time, é uma grande coisa a ser feita. Coloque alertas, encha a caixa de email do pessoal com mensagens de alerta e obriguem a todos terem carinho com o “build”. No time agradeço a presença do meu amigo Vinícius que me lembra e nos cobra coisa como essas.

No final …

No final o que mais importa é termos a disciplina e obstinação de sempre buscarmos a melhora contínua do que fazemos. Novas formas, padrões, teorias irão surgir, novas linguagens e ferramentas irão surgir. Porém sempre caberá a nós a busca por fazer nosso trabalhar melhor do que do dia anterior. Esse é o compromisso que quero assumir comigo e com meu trabalho.

Eu não sou um exemplo e nem desejo ser modelo, mas nem por isso devemos acreditar que só os melhores e somente em projetos de “empresas legais” que isso será possível. Faça aos poucos, se comprometa em fazer diferente. Faça e conquiste seu espaço, os resultados irão te ajudar a provar o valor de tais práticas.

Braziljs

| Comments

Gostaria de começar esse review do evento BrazilJS dizendo que ele superou em muito a minhas expectativas. Passado o tumulto inicial para a credenciais, que foi resolvido pelo pessoal da organização, o evento entrou numa crescente de qualidade e excelência.

Não quero fazer uma análise ou “crítica” ou resumo sobre cada palestra: isso seria injusto com quem está lendo e com o evento. Acredito, verdadeiramente, que houve uma mensagem maior trazida pela soma do todo e essa mensagem seria perdida se tratasse cada apresentação de forma isolada.

Por mais que, já claro até no nome, o evento fosse focado em Javascript, todo o conteúdo de frontend foi abordado e tratado de forma brilhante e, coroada, com a palestra do Bernard de Luna sobre performance no uso de CSS. Além disso, conseguiu, novamente com maestria na escolha dos temas, fugir do lugar comum, onde falar de frontend se limita a falar de páginas e portais. Falamos até de jogos e processamento de imagens.

Como citei acima, a grande linha guia, em minha opinião, foi sem dúvida a evolução e maturidade. É um fato, comprovado pelos participantes e palestrantes, que a comunidade evolui e amadureceu. Estamos mais conscientes de nosso papel na qualidade do que se tem feito nos projetos, estamos mais maduros quanto ao uso de boas práticas, estamos mais alertas quanto a questão – antes nem pensadas – de performance, estamos enxergando seu uso além de simples manipulações de DOM, etc. E a linguagem Ecmascript (nome “científico” do Javascript) parece refletir tudo isso, conforme apresentado brilhantemente pela seu criador.

Javascript não é mais “tecnologia” secundária. HTML e CSS não são mais maus necessários para entregarmos nossos webapps (que digo o JSF – trolei !!!!) . Javascript acencionou ao status de grande linguagem, se colocando lado a lado com JAVA, C#, Python, Ruby, entre outras. Busca a maturidade e resolver seus problemas. Busca o que há de melhor nas outras e dá seu “tempero”. Python me pareceu o grande irmão mais velho.

Seu uso vai além e se mostra uma excelente opção para automatização de tarefas – GruntJS, jogos, manipulação de imagens, tracking, testes, etc.

O frontend não quer e nem se limita mais ao browser e computadores. Busca as fronteiras onde estão os telefones, smartphones e até TVs. Não falo da TV Digital, e sim da TV como meio de consumo de webapps.

Enfim, o evento mostrou de existe um universo a ser explorado lá fora e muito trabalho a ser feito. Mostrou também que a comunidade está forte e capacitada para desbravá-lo.

Obrigado a todos.