Como o tal do SOLID pode melhorar seu projeto orientado a objetos
É chocante ver o quão subaproveitada a orientação a objetos é. Interessante é que só se percebe isto quando mudamos nossas leituras. No “Panteão Kiconiano de Heróis” há um chamado Robert C. Martin, que agrupou cinco princípios básicos do design orientado a objetos sob o acrônimo SOLID.
Quando tomei conhecimento deste acrônimo minha vida melhorou bastante e, acredito, a sua também a partir de agora caso este seja seu primeiro contato com o tema.
Mas antes de entrar no assunto, acredito que seja interessante fazer uma revisão do meu próprio desenrolar enquanto criador de objetos. Talvez nossa história seja similar e, nesta identificação eu lhe ajude de alguma maneira.
Meus primeiros objetos
Quando ouvi falar em orientação a objetos a primeira coisa que me veio à cabeça foi reutilização de código, mas não esta reutilização bonita que as pessoas estufam o peito pra falar. Meu raciocínio básico naquela época era:
“Hmm… bacana este negócio de orientação a objetos hein? Por que com isto eu posso pegar todo o meu código que fico repetindo em um monte de lugares, incluir em uma classe e, em seguida, simplesmente ir criando classes filhas desta. Assim, sempre que surgir alguma coisa que eu use em mais de um lugar, eu incluo apenas naquela classe e todas as outras terão acesso. Genial!”
Quando me lembro estufando o peito para falar isto naquela época não consigo conter as gargalhadas que dou de mim mesmo. Isto porque na minha cabeça sistemas deviam ser projetados tal como no diagrama abaixo:
Pra que uma classe Object básica se eu podia ter a minha própria classe “Global”? E o mais bacana é que eu podia instanciar a classe Global e usá-la em diversos pontos diferentes do sistema. Um design “lindo”!
Foi quando ouvi falar de um princípio de design chamado de responsabilidade única (Single Responsability em inglês).
Responsabilidade Única (Single Responsability (SRO))
Este princípio diz o seguinte: uma classe deve possuir uma, e apenas uma responsabilidade, ou seja, deve ser especializada de tal modo que execute apenas uma tarefa e, de preferência, de uma forma bem feita. Eu olhava pro meu design original e uma vergonha imensa me consumia porque ficava nítido que a minha classe “Global” era quase divina, pois fazia um pouco de tudo.
Este termo foi cunhado por Robert C. Martin (aka Uncle Bob) em um texto chamado “The Single Responsability Principle“. Por responsabilidade, entenda uma “razão para que o código seja modificado”. Imagine por exemplo um relatório. Em um design original, poderíamos implementar uma classe que fosse responsável pela extração dos dados, processamento dos mesmos e, pra finalizar, a exposição dos dados. Resumindo, poderíamos implementar este objeto como uma “classona“. Nesta classe há três responsabilidades:
- Extração dos dados
- Processamento dos dados
- Impressão dos resultados
Seguindo este princípio, poderíamos refatorar este monstrinho para que fosse composto por três classes, tal como no diagrama abaixo:
O ganho é imediato neste novo design, porque as consequências das mudanças está bem mais controlada. Se eu alterar a classe que extrai dados, apenas esta será afetada. O processador de dados pode até receber dados equivocados, mas como seu papel é processá-los, posso incluir um tratamento de erros que só diz respeito a si mesma. E também posso trocar a saída do meu relatório precisando fazer modificações em apenas uma classe.
E sabe o que é mais legal? Como o código fonte de cada classe é menor do que o daquela classona inicial, eu compreendo muito melhor o funcionamento de cada componente. E com isto os meus bugs diminuem bastante.
Fechado para modificações, aberto para expansão (Open Closed Principle (OCP))
Depois que aprendi o conceito de responsabilidade única minha vida melhorou bastante enquanto eu era um desenvolvedor solitário. Mas a partir do momento em que passei a trabalhar em equipes maiores, minha vida começou a se complicar pois nem sempre o meu código executava exatamente como eu queria. Era engraçado, meu processador de dados, por exemplo, muitas vezes me gerava resultados completamente malucos quando este deveria ser sempre o único.
Quando eu ia descobrir o resultado, descobria sempre que algum “engraçadinho” havia feito com meu sistema algo como o exposto no diagrama abaixo:
A culpa não era da equipe, mas minha. Projetei o sistema inicialmente de tal maneira que qualquer um poderia sobrescrever o método processe da classe Processador de Dados livremente. Como resultado, eu não tinha mais a uniformidade do conceito de processamento de dados neste sistema. Dependendo do contexto, isto pode ser ótimo, mas neste que estou aplicando é péssimo. O resultado em Java para este problema seria muito fácil de ser resolvido. Na primeira versão que liberei eu devia ter implementado o método processe na classe original como final. Voilá, ninguém mais o substituiria.
Mas por que na prática eu fecho para modificações uma classe? A razão é simples: porque assim eu posso desenvolver meu software como se fosse em camadas. Estando uma camada muito bem escrita e bem definida, eu tenho certeza de que todas as classes derivadas também funcionarão bem. As classes derivadas na prática poderíam apenas usar os métodos fechados e acrescentar novos comportamentos ao sistema conforme novas necessidades fossem surgindo.
Tio Bob tem um excelente artigo sobre isto neste link.
O princípio de substituição de Liskov (Liskov Substitution Principle)
O meu Processador de Dados semrpe envia os dados para o impressor de resultados e espera um valor inteiro como resposta que representa o sucesso ou falha da impressão. Normalmente este valor é positivo caso tudo ocorra bem e negativo caso contrário. Sendo assim, internamente na minha classe Processador de Dados há um método chamado imprima, chamado pelo método processe tal como no exemplo abaixo:
public final void processe() { // ah... aprendi com o princípio OCP
// bla bla bla
if (getImpressor().imprima(resultado) > 0) {
// execute uma saudação feliz
} else {
// avise ao presidente que estamos sofrendo um ataque nuclear
}
}
No caso, estamos lidando com uma convenção. Nosso processador de dados espera que nosso objeto impressor possua um comportamento bem definido. Se algum mal informado de nossa equipe resolver implementar uma classe de impressão que haja de maneira distinta, veremos um presidente tendo um ataque do coração.
Basicamente isto é o que chamamos de princípio de substituição de Liskov (só por curiosidade, Liskov é uma mulher, e se chama Barbara). No projeto de nossos sistemas, devemos proceder de tal maneira que, ao implementarmos nossas classes filhas, o façamos de tal maneira que as classes clientes não sofram surpresas desagradáveis como a que descrevi acima.
E adivinha? Uncle Bob explica este conceito muito melhor do que eu neste artigo.
Princípio de Segregação de Interfaces (Interface Segregation Principle (ISP))
Meu extrator de dados era muito bom. Tão bom que eu comecei a inserir em seu corpo uma série de outros métodos que eram usados por outras classes além do meu processador de dados. Terminei meu projeto com uma carinha similar à da imagem abaixo:
Conforme o extrator de dados foi crescendo, ficou nítido que sua interface também cresceu. E de repente meu Processador de Dados tinha de lidar com uma interface bem mais complexa do que a original. De repente esta classe tem conhecimento de outras que não devia sonhar com a existência, como por exemplo DadosMaravilhosos e DadosLindos. Lembra que um dos princípios básicos por trás da OO é o encapsulamento? Nosso processador só precisa conhecer o método extrairDados e a classe Dados.
O princípio de segregação de interface diz o seguinte: se uma interface começa a engordar, devemos parti-la em diversas novas interfaces de tal modo que cada cliente só conheça aquilo que de fato lhe diz respeito. Então modifiquei meu sistema para que ficasse como no diagrama abaixo:
Nesta segunda versão quebramos a interface original do Extrator de Dados em três: uma para cada cliente. Com isto tivemos uma série de ganhos interessantes:
- Cada cliente só conhece as classes e os métodos de que realmente precisa
- Temos um desenvolvimento realmente voltado para interfaces
- Temos um menor acoplamento no sistema (ei, mais sobre isto no próximo princípio)
É interessante observar como que, na prática, adicionando um número maior de elementos no nosso sistema, acabamos por diminuir o custo de manutenção. Isto porque podemos trabalhar nas classes cliente isoladamente de uma forma mais segura, visto que temos um acoplamento menor.
Ei, Robert Martin tem um texto sobre o assunto também!
Princípio de Inversão de Dependências (Dependency Inversion Principle (DIP))
Observe o diagrama abaixo que corresponde à primeira versão evoluída do nosso sistema. Além dos problemas apresentados nos últimos quatro princípios, consegue identificar mais alguma falha?
Suponha que um dia comercializemos nosso Processador de Dados, e que queiramos variar as formas de obtenção de dados ou de impressão de resultados. Como faríamos? Claro, poderíamos implementar alguma lógica dentro das classes relativas de tal modo que algum flag definisse qual a origem das informações e como gostaríamos de apresentar os resultados, certo?
Ou poderíamos também definir em tempo de execução qual classe instanciar, como fazemos por exemplo usando um container de injeção de dependências. São duas soluções, mas o problema persiste: nosso processador de dados conhece demais as suas dependências. O princípio de inversão de dependências diz o seguinte:
Um módulo de nível superior não deve depender diretamente de módulos de níveis inferiores, mas de abstrações (e módulos de níveis inferiores também devem depender de abstrações).
Abstrações não devem depender de detalhes de implementação, mas sim o contrário.
Este princípio é poderosíssimo, e é a base por trás do conceito de injeção de dependências. Primeiramente, o que é uma abstração? É a generalização de um comportamento excluindo todos os seus detalhes de implementação. No mundo da orientação a objetos, corresponde às interfaces ou classes abstratas/pai.
E o que é um módulo de nível superior? É aquele aonde normalmente se encontra encapsulada a lógica de negócio do nosso sistema. E de nível mais baixo? Aquele que não está diretamente ligado ao objetivo do sistema, como por exemplo nosso extrator de dados e o impressor de resultados.
Neste caso, você me pergunta: como eu arrumo este sistema? Simples, como no diagrama abaixo:
Repare: o Processador de Dados não precisa mais saber detalhes sobre a implementação do Impressor ou do Extrator. Ele só precisa lidar com as abstrações dos mesmos. Podemos agora substituir facilmente suas implementações sem o risco de obtermos comportamentos inesperados no nosso sistema. Resumindo: resolvemos o problema do alto acoplamento.
Um dos textos mais importantes da minha carreira é este: “The Dependency Inversion Principle” de você já sabe quem. Caso este meu post te leve a ler este artigo, me dou por realizado, porque foi um dos raros que literalmente mudou minha carreira. A propósito, eu tenho um artigo inteiro sobre isto neste link (e estou escrevendo um livro sobre o assunto).
E o que é o tal do SOLID hein?
São os cinco princípios que expus de uma maneira bem light acima:
Single Responsability Principle (Responsabilidade Única)
Open Closed Principle (Aberto para expansão, fechado para modificação)
Liskov Substitution Principle (Princípio de Substituição de Liskov)
Interface Segregation Principle (Princípio de Segregação de Interface)
Dependency Inversion Principle (Princípio de Inversão de Dependências)
Sugestão: leia cada um dos artigos que citei no corpo do texto e, semana a semana, dedique-se a pensar em apenas um destes. Eu te garanto: você se tornará um desenvolvedor muito, mas muito melhor.
Fica a dica ;)
Grails Brasil por dentro: sua arquitetura
Sem dúvidas meu projeto mais conhecido (além deste blog) é o Grails Brasil. Tenho muito orgulho deste trabalho porque diariamente vejo uma quantidade enorme de gente que ajudei com ele. Há um aspecto no Grails Brasil que chama a atenção de diversos visitantes: é um site extremamente rápido. Neste post vou expor alguns dos seus segredos que, espero, irão contribuir de uma vez por todas para acabar com o mito de que “Grails é lento” ou que “não serve para aplicações com grande número de acessos”. Mas primeiro um pouco de história.
Pequeno histórico
Em 2007 (final de 2006 pra ser exato) eu já acompanhava o projeto Grails e achava que era a promessa para o desenvolvimento de aplicações corporativas na plataforma Java EE. Se tudo desse certo eu poderia aproveitar todo o meu código fonte legado tendo os ganhos de produtividade que o pessoal do Ruby on Rails estava tendo. Uniria o melhor de dois mundos. Como podem ver, a promessa se cumpriu, mas naquela época havia um pequeno problema: quase ninguém no Brasil conhecia Grails.
Eu tinha duas opções: ficar sentado esperando que algo surgisse ou tomar uma atitude. Foi assim que no horário do almoço o Grails Brasil surgiu em sua primeira versão, baseada no phpBB. Usando o assistente da HostNet em 15 minutos eu tinha uma primeira versão do site pronta para uso. Muitos me criticaram por criar um fórum sobre Grails em php, mas minha resposta ainda é a mesma: até então eu não conhecia nenhum motor de fórums que superasse o phpBB (confesso que ainda não conheço). Sendo assim, por que eu deveria reinventar a roda? Uma das principais virtudes de uma arquitetura não é o bom reaproveitamento de código? Bom: este é assunto para outro post. O importante é que por um bom tempo o phpBB supriu todas as minhas necessidades.
Infelizmente com o passar do tempo comecei a ter diversos problemas com spam. Por mais que eu tunasse o phpBB com plugins de segurança, sempre ocorriam ondas de spam que tornavam a vida dos participantes do fórum um inferno. Os ataques eram tão intensos em um dado período que comecei a ter perda financeira, pois o site estourava muito seu limite de banda mensalmente sendo que 90% do tráfego eram bots. Havia chegado a uma encruzilhada: ou encontrava uma solução para o problema ou fechava o site.
A solução foi reescrevê-lo do zero tendo como meta dois objetivos:
- Acabar com o problema do spam
- Minimizar ao máximo os custos de hospedagem do Grails Brasil
Solução: reescrever do zero – a visão macro da arquitetura
Foi quando resolvi recriar o site em Grails com base em alguns princípios que expliquei neste post. Por um breve momento pensei em usar o JForum como solução, mas eu queria mais: meu desejo era tornar o Grails Brasil um experimento de software cujo objetivo fosse criar a aplicação mais leve possível feita com o framework (usei a versão 1.3.7).
O primeiro passo foi escolher o serviço de hospedagem. Optei pelo EC2 da Amazon no qual eu pagaria pelo processamento da minha aplicação. Esta escolha se mostrou uma vitória para o projeto pois me incentivou a escrever código altamente otimizado para que os custos ficassem mínimos. Como alta disponibilidade não era um dos requisitos do projeto, optei por inicialmente usar uma única instância de 600 Mb de memória RAM. Estas restrições aumentaram meu tesão pelo projeto, pois com isto escrevi cada linha do código fonte pensando em como minimizar ao máximo o uso de recursos computacionais (um exercício interessante que recomendo a qualquer um que se interesse por otimização de software).
Como a maior parte das consultas ao Grails Brasil é textual um novo elemento foi adicionado ao projeto: uso o Lucene como indexador de qualquer conteúdo adicionado no site. O diagrama abaixo mostra uma versão bem simplificada da arquitetura final.
Todo o conteúdo ainda é armazenado no MySQL e obrigatoriamente indexado pelo Lucene. Optei por não usar o plugin searchable, por duas razões: tive alguns problemas com ele em projetos passados e era também uma excelente oportunidade para que eu pudesse me aprofundar no Lucene. Reinventar a roda neste caso foi uma experiência “pedagógica” que se pagou bem no meu caso, pois minha compreensão desta ferramenta cresceu muito e, com isto, pude aplicá-la a outros projetos com bastante sucesso.
Como banco de dados, optei pelo meu favorito que é o MySQL. Naquela época a versão 5.5 ainda era recente. Como o projeto era meu, me dei o direito de experimentar o “brinquedo novo” e fiquei bastante feliz com os resultados. Comparado a versão 5.1 é um upgrade praticamente obrigatório.
Plugins usados
Code Coverage: apesar dos bugs existentes na versão atual, o Grails Brasil possui mais de 90% do seu código fonte coberto por seus testes automatizados. Os testes serviram dois propósitos, o óbvio e como profilamento do sistema. Com eles ficava fácil identificar todos os gargalos do sistema e, assim chegar mais próximo do objetivo principal do sistema.
FckEditor: posteriormente usei o FckEditor como editor básico dos fórums e dos casos de sucesso. Foi uma escolha acertada, pois o plugin me permitiu customizar seu comportamento até que chegasse no ponto que eu considerava “perfeito” para o site.
Feeds: tudo no Grails Brasil gera RSS graças a este plugin, que foi uma mão na roda. Primeiro fiquei com um pé atrás com ele, porém após uma análise minunciosa do seu código fonte vi que o bichinho era simplesmente lindo.
Quartz: diversas tarefas no Grails Brasil são executadas assíncronamente, o que propicia uma experiência de uso muito mais fluída para o usuário. Este plugin literalmente salvou a experiência de uso dos visitantes.
Ausência interessante: Spring Security. O leitor atento pode se perguntar a razão pela qual não inclui este plugin. Uma série de fatores contribuíram para isto. Pra começar, o Grails Brasil não possui uma área administrativa. Sendo assim, o controle de autenticação/autorização é bastante simples: usuário só tem acesso de escrita se é cadastrado e está autenticado no site (escrevi uma suite de testes imensa para garantir a segurança do sistema). Além disto, com as minhas restrições de memória, o overhead de inicialização do plugin é significativo. Sim: ele consome poucos recursos do sistema e seu custo sob a performance é mínimo, mas apenas depois que o sistema foi inicializado.
Princípios de implementação
O pai inconsequente
Aplico uma técnica que chamo de “pai inconsequente”. É bastante simples: o filho sabe quem é seu pai, mas jamais o contrário. Por exemplo: ao invés de escrever algo como o código abaixo:
class Pai {
static hasMany = [filhos:Filho]
}
class Filho {
static belongsTo = [pai:Pai]
}
Escrevo apenas o belongsTo na classe Filho. Com isto obtenho um ganho de performance bastante interessante na listagem dos registros pai (como por exemplo os posts na listagem do fórum ou a descrição dos cases na seção de cases). Sim, eu sei que estou lidando com uma classe do tipo proxy aqui, e que os filhos só são carregados se o atributo correspondente é invocado pela primeira vez. No entanto, isto me garante a geração de classes proxiadoras menores e, consequentemente, que consomem bem menos memória.
Outra vantagem é que as dependências entre minhas classes de domínio sempre terão a forma de uma árvore, ao invés de um ciclo. Com isto a modularização do código caso seja necessário por exemplo extrair um plugin da aplicação se torna muito mais fácil.
YSlow na veia
O Yahoo tem uma suite de testes de performance maravilhosa chamada YSlow. Tentei aplicar praticamente todos os princípios no Grails Brasil. Ainda não está nível A, mas caminhamos para isto :).
- Arquivos estáticos como imagens são carregados a partir de um outro servidor de conteúdo estático (o famigerado CDN: Content Delivery Network)
- Diversos recursos são minimizados quando aplicável (javascript por exemplo)
- As diretrizes básicas são seguidas religiosamente, como por exemplo inclusão de CSS no topo da página e Javascript no final
Tuning de banco de dados
Nem sempre o GORM irá criar todos os índices necessários em suas tabelas para obter performance máxima. Gastei um bom tempo analisando as consultas feitas pela aplicação contra o MySQL e criando os índices necessários. Os resultados, como já eram de se esperar, foram excelentes.
Programação dinâmica
Há um cacheamento físico de algumas partes do sistema. Por exemplo: o RSS de algumas partes do site não é gerado dinâmicamente, mas apenas na primeira vez em que é requerido. O resultado é persistido em disco (ou cacheado temporariamente em memória) e só é alterado quando há necessidade. Com isto reduzi significativamente o número de vezes que precisei acessar o banco de dados.
A regra é clara: se é caro de gerar, gere o mínimo de vezes possível.
Se pode ser feito depois, deixe pra mais tarde
Para garantir a experiência de usuário mais fluída possível, diversas das operações executadas pelo site são executadas apenas assíncronamente. Um bom exemplo é a integração com nosso servidor SMTP. Quando alguém posta uma resposta a uma pergunta, um e-mail é enviado para o autor do post e também para aqueles que se inscreveram nele, porém este e-mail não é enviado imediatamente.
Há uma série de pilhas no Grails Brasil para processamento assíncrono (implementadas como tabelas no banco de dados) de mensagens. Periodicamente um job lê as mensagens na pilha e as processa em lote. Com isto tenho a possibilidade de implementar mecanismos de retentativas em caso de erro e também um aproveitamento melhor de conexões com recursos externos.
Big Brother no Grails Brasil
No primeiro release da segunda versão do Grails Brasil observei que diversas das otimizações que havia implementado eram completamente desnecessárias. Sim, aquele papo de que “otimizar antes é furada” é real, BEM real. A solução que encontrei foi incluir um sistema de log no sistema que me fornece a medição de performance de cada método executado.
Com isto pude entender muito melhor o comportamento dos usuários do sistema. Consequentemente eu sabia exatamente aonde uma otimização podia ou não valer à pena. Os logs foram fundamentais para que eu descobrisse, por exemplo, o que valia à pena cachear ou não. Os algoritmos de cacheamento que implementei após o log se mostraram ordens de magnitude mais eficientes.
Em números e minha lista negra
O Grails Brasil tem hoje algo em torno de 4000 a 6000 acessos/dia válidos. Destes, menos de 5% são ativos, ou seja, ficou nítido que as pessoas usam o site muito mais como mecanismo de pesquisa do que de participação efetiva. O consumo de memória raríssimas vezes supera 300 Mb e temos em média 60 a 100 sessões concorrentes a qualquer momento do dia ou da noite.
Por acessos válidos eu quero dizer “não spam”. Via spam o acesso ainda é brutal: basicamente o triplo do que mencionei. Detecto o SPAM pelo país de origem. Dado que o site se chama Grails Brasil, dou prioridade aos IPs provenientes de países que possuam língua portuguesa ou que não estejam no meu blacklist (amigos chineses, agradeçam à ChongSoft por estarem na lista negra). Quando um IP está na lista negra, este possui tratamento diferenciado, minimizando o consumo de recursos do sistema.
Conclusões
Sei que alguns dos pontos que apontei neste blog são controversos (como a estratégia do “pai inconsequente” por exemplo), porém minha experiência demonstrou que funcionam muito bem. Claro: ainda há bugs no site que preciso arrumar e, lá no fundo, ainda acredito que dê pra melhorar ainda mais esta performance.
Mas o interessante é que o Grails Brasil serve como um excelente exemplo de que sim, é possível escrever uma aplicação Java EE consumindo o mínimo possível de recursos computacionais e, ainda por cima, apresentando uma performance excelente. Vale salientar também aqui o papel da pesquisa: só com muita sorte eu conseguiria os resultados que obtenho no Grails Brasil se não tivesse empenhado boa parte do meu tempo pesquisando soluções para os problemas que encontrava.
Outro ponto fundamental: otimização prematura normalmente gera retrabalho. Quando for lançar a primeira versão do seu projeto, certifique-se de possuir uma excelente cobertura de log. Somente com dados reais de produção é que podemos encontrar os gargalos de nossos sistemas. Caso contrário, você cometerá os mesmos erros que eu, desperdiçando boa parte do seu tempo.
E bom, é isto ai. Espero que as dicas que passei neste post sejam úteis a vocês que desejam tirar máximo proveito dos seus servidores sem pagar muito.
PS:
o mais gostoso. Gasto menos de US$ 1,00 mensal de hospedagem na Amazon com o Grails Brasil ;)
Fanboy: aquela criança que não devia trabalhar com TI
Fanboys: como vivem? De onde vêm? Como se reproduzem? Como evitá-los?
Quando interajo com um fanboy a sensação de riso costuam surgir. Convenhamos: é risível, mas sabe o que acho interessante? Temos apenas uma fina camada de comicidade ocultando uma realidade trágica. O nome deste padrão se chama pateticidade, e acredito que possa ser aplicado sem problemas a qualquer fanboy.
Antes de começar, vou primeiro definir o que chamo de fanboy.
É aquele que se apega a determinado objeto de consumo ou tecnologia apaixonadamente, e o defende cegamente de qualquer crítica muitas vezes ignorando as próprias limitações da coisa.
A palavra boy não está embutida em fanboy por acaso: imaturidade está na essencia destas criaturas. E neste momento eu me pergunto: por que este apego todo? Simples insegurança?
Vejo o fanboy como um ser infantilizado, irracional e inseguro que se apega a algum bem de consumo ou tecnologia e o defende cegamente sem perceber o mal que faz a si próprio. Resumindo: é um tolo.
Convenhamos: todos nós passamos por este estado de vez em quando. É natural quando descobrimos algo que achamos ser o máximo e nos empolgamos com isto. O sentimento de decepção é sempre muito triste: o problema do fanboy consiste na sua incapacidade de lidar com esta sensação.
(é aquela mesma sensação que as crianças sentem ao perceberem que seus pais não são perfeitos)
E sabe o que é pior? Estes caras transformam a TI em um inferno.
Por que estas crianças não deveriam brincar de TI
O “logia” de “tecnologia” vêm de logos, que em grego significa basicamente racionalidade. Trabalho racional não deve em hipótese alguma permitir a entrada de… adivinha! Irracionalidade. Sejamos pragmáticos: (fan)atismo não funciona nesta área.
Uma coisa é ser apaixonado pelo próprio ofício (eu sou). Outra completamente diferente é ser incapaz de perceber dois fatinhos muito basicos da vida adulta:
- Não existe uma solução única para todos os problemas (a famigerada bala de prata)
- Perfeição é uma meta inatingível (o que não quer dizer que você deva evitá-la)
É muito comum encontrarmos consultores que ao enviarem suas propostas de trabalho a um cliente normalmente incluem como única opção a substituição de sistemas legados (desenvolvidos em tecnologias diferentes do objeto de adoração) por algo inteiramente “novo, moderno, revolucionário e inovador” feito em hyperlang. A consequência é óbvia: o cliente fica maravilhado em um primeiro momento e normalmente ferrado pouco tempo depois (Joel Spoolsky tem um texto ótimo sobre isto, clique aqui). Esse pessoal é incrívelmente cretino: se esquecem de que código legado existe porque normlamente funciona (mas isto é papo para outro post).
(interessante observar que a palavra “revolucionário” também pode significar “retrocesso”)
Sempre vejo alguns comportamentos típicos em um fanboy:
- Aquele que não opta pelo seu time é visto como um pobre coitado incapaz de conseguir entender aquela “inteligência superior”
- Raiva surge (às vezes acompanhada de choro) quando questionados
- Maniqueismo total: não existe meio termo. Objeto de adoração, bom, objeto concorrente, mau, muito mau!
- Possuem uma atitude típicamente arrogante-cool. São pessoas “cool”, que simplesmente ignoram e tratam como infantis todos os discordantes (o bacana é que normalmente a arrogância é fruto da ignorância). “Não perca tempo discutindo… eles não sabem o que é bom…”
Como nascem estes monstrinhos?
Fantoches de corporações
Já assistiu a uma daquelas apresentações da Apple em que se o CEO arrotar a platéia aplaude? Yeap: boa parte dos fanboys são meros fantoches de corporações, que tentam criar a idéia de que seus clientes são mais inteligentes, bacanas, fodásticos e tudo mais.
Claro, os fanáticos retribuem com suas oferendas verdes a estas empresas crentes de que estão sendo tratados com respeito e como seres superiores que acreditam ser.
O desejo de ser como Fulaninho Cool
As pessoas são carentes. Muitas vezes ao escolhermos um modelo e não possuirmos uma boa auto estima acabamos por segui-los cegamente. “Se fulano programa em Kronks, e ele é tão bacana, é lógico que este é O único caminho a ser seguido”.
Simples incompetência
Não raro o fanboy defende cegamente sua ferramenta de trabalho porque só sabe obter o resultado X (por exemplo, desenvolver pra web) com ela, que foi a única que conseguiu aprender a usar. “Não consigo fazer X com nada que não seja Y. Logo, tudo o que não é Y fede!”
Como morre um fanboy?
A única maneira de aniquilar a praga é torcendo para que ele cresça. O amadurecimento fica nítido quando percebemos que quando o nosso objeto de adoração sai de cena isto normalmente ocorre não porque existe uma corporação cruel que a destruiu por pura maldade mas sim porque uma alternativa mais eficiente entrou em seu lugar.
Há casos em que nosso objeto de idolatria se torna obsoleto devido a crueldade dos concorrentes? Claro, mas olhando friamente fica nítido que são situações raríssimas. Convém lembrar que é preciso mais que um ataque corporativo nuclear para destruir algo: é necessário o mercado atuar.
Os que não amadurecem, bem: Darwin os executa. Terminam extintos porque não conseguiram se adaptar.
Agora, sabe qual a grande sacanagem? É que normalmente quem paga pela imbecilidade dos fanáticos é quem não tem nada a ver com isto: o cliente.
Experimento: hackeando o Kinect pra jogar Half Life
Um experimento bem bobo feito alguns meses atrás. No caso, eu hackeando o Kinect para que eu pudesse jogar Half-Life. Foi a minha primeira tentativa de brincar com o Kinect SDK. Nos próximos meses pretendo publicar aqui alguns outros vídeos com resultados BEM mais interessantes. Aguardem!
Livro bacana: Groovy for Domain Specific Languages
No final de 2010 o tema DSLs ganhou bastante popularidade com a publicação do livro “Domain Specific Languages” do Martin Fowler. Para quem não sabe o que são, trata-se de pequenas linguagens de programação voltadas para contextos bem específicos, como por exemplo definições de regras de negócio de uma empresa ou consulta e manipulação de bases de dados proprietárias. O principal objetivo por trás destas linguagens é transferir parte da responsabilidade da implementação das regras de negócio para o usuário final do sistema.
Apesar da popularização recente do termo, lidamos com DSL’s já há algumas décadas muitas vezes sem nos darmos conta disto. Lembra dos scripts do mirc? No UNIX/Linux usamos algumas DSL’s também sem nos darmos conta, como por exemplo o awk e o grep.
Lembrando destes exemplos, você pode pensar que se trata de uma tarefa árdua. Ledo engano: linguagens como Groovy ou Lisp nos permitem implementar estas pequenas linguagens de uma forma bastante prática, realizando assim aquele nosso sonho nerd de escrever nossa própria linguagem de programação. :D
O livro “Groovy for Domain-Specific Languages”, de Fergal Dearle, publicado pela PACKT Publishing tem por objetivo abordar o tema usando a linguagem Groovy. Terminada a sua leitura, no entanto, a conclusão que cheguei foi a seguinte: como um livro sobre DSL’s em Groovy, é na realidade um excelente aprofundamento a alguns detalhes da linguagem.
Groovy nos oferece os seguintes recursos que facilitam a criação de DSLs:
- O fato de podermos escrever nossos programas na forma de scripts
- Closures
- Builders
- A opcionalidade de alguns elementos de sintaxe como parênteses e ponto e vírgula
- MOP (Meta Object Protocol)
- AST Transformations, que nos permitem alterar parte da sintaxe do Groovy (e que pode refletir na criação das DSLs).
Com excessão das transformações AST (falha grave), todos estes aspectos são tratados em detalhe no livro, o que o torna ideal para todos aqueles que trabalham com Groovy mas raras vezes tiveram a oportunidade de aprender de fato como funcionam.
O mais engraçado é que, terminada a leitura deste livro, percebo que o autor acidentalmente (acredito) obteve um resultado inesperado. Não é um livro voltado apenas para a criação de DSL’s: é uma excelente introdução para aqueles que quiserem aprender Groovy.
Sendo assim, como avaliação final deste livro, posso dizer que como uma abordagem às DSL’s, é um excelente guia para quem quiser aprender Groovy.
Fica a dica, e espero que gostem.
Minhas boas leituras de 2011
Este ano foi excelente! Boa parte do crédito é devida a alguns livros maravilhosos que me acompanharam. Vou compartilhar com vocês parte desta experiência citando algumas leituras que literalmente mudaram minha vida.
Morro dos Ventos Uivantes – Emily Bronte
UOU! Como pude passar tanto tempo sem ler este? Resposta rápida: preconceito. Acreditava ser mais um romance meloso que me entediaria até a morte. Nada disto! Este é sem sombra de dúvidas um dos melhores romances que já li. Fantástico!
É chocante quanta maldade a “simpática Emily” conseguiu enfiar em seu único livro. E sabem o que é mais legal? É um livro ultra barato e de domínio público.
Com este livro você vai aprender que sim: a coisa sempre pode piorar!
A Conquista da América – Tzvetan Todorov
Em determinado momento decidi que queria conhecer melhor minha história como latino-americano. Foi uma ótima idéia porque com ela adquiri uma compreensão melhor do mercado de trabalho e das razões pelas quais somos desta forma hoje.
Aliás, dois posts muito comentados neste blog: “Armadilhas para Desenvolvedores: os Exploradores” e “Hernán Cortés e o Software Livre” são diretamente influenciados por esta leitura.
O ponto de partida do livro é a questão do outro, ou seja, como é formada a imagem do índigena sob o ponto de vista europeu e vice-versa. Me ajudou bastante a compreender melhor como lidar com minha auto imagem e também a entender como a percepção que tenho dos outros é formada.
Resumindo: pra quem queria apenas entender melhor a história da colonização latino-americana, sai no lucro compreendendo melhor as formas de exploração adotadas pelo mercado e como nossa percepção do outro é formada.
Anti Patterns: Identification, Refactoring and Management – Phillip A. Laplante e Collin J. Neil
Uma das minhas buscas foi a de um ambiente de trabalho melhor. Como estou trabalhando com mais gente achei que seria importante aprender a lidar melhor com meus colegas de trabalho. E este livro foi uma descoberta maravilhosa.
Em Anti Patterns, o foco são exemplos que jamais devemos deixar acontecer em um ambiente de trabalho. É uma leitura bem mais interessante do que mais um daqueles livros de gerenciamento que sempre me causam a impressão de estar vendo um mundo no qual as condições de temperatura e pressão são ideais. Longe disto!
Foi interessantíssimo porque durante a leitura percebi que devo ter passado por uns 70% dos terríveis exemplos citados (“sortudo”), o que me causou uma sensação confusa de orgulho (sobrevivi!) e tristeza. Uma tristeza produtiva que me fez executar uma série de melhorias em minha vida cujos resultados estão sendo muito bons.
Racing the Beam – The Atari Video Computer System – Nick Montfort e Ian Bogost
Foi o livro que me revolucionou tecnicamente: simples assim. O objetivo dos autores é mostrar como a arquitetura do Atari influenciou a criação de todos aqueles jogos que salvaram minha infância de um desastre total.
Virou minha leitura obrigatória que tento empurrar a todos aqueles que, assim como eu, não programam apenas para pagar as contas, mas sim porque AMAM a coisa. Não consigo negar a inveja que senti de programadores como David Crane (criador do Pitfall).
É aquele tipo de leitura que te faz repensar o modo como desenvolvemos software hoje. A pergunta que mantive após a leitura é a seguinte: temos hoje temos um ambiente de desenvolvimento fantástico, mas será que o nosso produto final faz justiça a todo o nosso poder de fogo, ou será que não nos tornamos no final das contas um bando de mimados?
Só por curiosidade: Pitfall tem 255 telas. Quanto elas ocupam de memória? 8 bits. :)
Mal-Estar no Trabalho: Redefinindo o Assédio Moral – Marie-France Hirigoyen
O livro acidental do final de ano. Nanna o tinha em mãos e eu por curiosidade resolvi levá-lo para o banheiro e, bem: ela ainda o está esperando. :)
Ta ai um assunto que nunca imaginei ser interessante. Fui fisgado logo nas primeiras páginas. Finalmente consegui entender o que vêm a ser o tal do “assédio moral” e, sabe de uma coisa? Percebi que acidentalmente posso já ter cometido e sofrido assédios também.
Através de uma série de exemplos a autora vai mostrando ao leitor situações que normalmente ignoramos mas que consistem em assédios. Pra aumentar a culpa de nós, assediadores acidentais (ou não), a autora ainda mostra os efeitos físicos do assédio em suas vítimas.
Leitura fantástica: está me fazendo rever de cabo a rabo a maneira como lido com meus colegas de trabalho. Recomendo a leitura para todos aqueles que não tem como objetivo de vida profissional a vida em isolamento ou que desejam um armamento teórico melhor pra lidar com o problema.
Alguns livros técnicos
Houve também alguns livros técnicos que me ajudaram bastante este ano. Abaixo está uma pequena lista daqueles que mais valeram à pena:
- Enterprise Integration Patterns – Gregor Hohpe e Bobby Woolf – leitura obrigatória pra qualquer um que desenvolva sistemas corporativos complexos (de fato complexos)
- Java Concurrency in Practice – Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, Doug Lea – após ler este livro você percebe que não sabia nada sobre concorrência :)
- Camel in Practice – Klaus Ibsen e Jonathan Anstey – Tive uma experiência maravilhosa com Camel na Squadra, e este livro me ajudou bastante (dica: se for ler este livro, leia o EIP antes)
- Programming Clojure – Stuart Halloway – Neste ano comecei a realizar um sonho antigo: criar algo útil com alguma variante do Lisp. Este livro têm me ajudado bastante.
- Scheduling Algorithms – Peter Bruker – Quer se sentir muito burro? Leia este livro. Este ano tive de lidar com problemas envolvendo escalonadores (num falei que foi um ano massa?) e desconfio que após sofrer horrores com este livro fiquei um pouquinho mais esperto viu? :)
- Java Reflection in Action – Ira R. Forman e Nate Forman - Ta ai um assunto que pouco javeiro entende bem. Foi um dos assuntos que mais me divertiu em 2011.
- PHP in Action: Object, Design, Agility – Dragfinn Reiersol, Markus Baker e Chris Shiflett – quem diria? Em 2011 voltei a brincar com PHP. E sabe o que percebi? Nós do Java temos muito o que aprender com este povo ai.
Compra do ano: um tablet meia boca
Se há um aspecto negativo em 2011 pra mim este se chama trânsito. Como eu ficava em média umas 3 ou 4 horas por dia preso neste inferno, comprei um tablet bem vagabundo. No caso, um Coby Kyros 7015, que me serviu muito bem por uns 6 a 8 meses até que seu carregador foi pro saco. Se você assim como eu ama ler e fica muito tempo no trânsito, é algo que vale à pena comprar.
Concluindo
Estes foram alguns dos livros que li neste ano e fizeram toda a diferença pra mim. Espero que estas dicas sejam úteis a alguém que por algum acaso tope com problemas similares.
Agora é esperar pelas leituras de 2012, que também prometem. E você? Que livros fizeram seu 2011?
PS:
e sim, já estou trabalhando no próximo vídeo da série sobre Groovy/Grails. Aguardem! :)
Groovy e seus mutantes: terceira parte do Guia Groovy/Grails em vídeo
Continuando a minha série sobre vídeos, é hora de nos aprofundarmos nos aspectos mutantes do Groovy. Ao menos os mais fundamentais para que a sua compreensão do Grails seja a melhor possível.
Os seguintes tópicos foram abordados:
- Closures: que droga é esta?
- Executando funções e acessando propriedades de forma dinâmica
- Como modificar nossas classes em tempo de execução
- E pra finalizar, como fazer um mexidão de classes usando mixins
Espero que gostem deste vídeo o mesmo tanto que eu gostei de fazê-lo. Ele marca uma mudança radical no material que pretendo publicar daqui pra frente.
Para acessar os vídeos restantes, use este link.
Guia Grails em Vídeo > Groovy: o “Java” que sempre quis – Aula 02
Como prometido, o vídeo da semana, entitulado “Groovy: o ‘Java’ que sempre quis’. Este e os próxmos vídeos serão focados não no Grails, mas no componente que o torna tão produtivo: a linguagem de programação Groovy.
AVISO
Um dos maiores equívocos cometidos por iniciantes em Grails (erro este que costuma inclusive destruir projetos) é programar em Groovy exatamente como seria feito com Java tradicional. Funciona? Sim, mas você cairá nos seguintes problemas:
- Sua performance pode ser inferior – afinal de contas, você não está programando “à moda Groovy” e, consequentemente, o compilador pode deixar de executar uma série de otimizações no seu código.
- Sua compreensão do framework será menor: Grails tira proveito de cada aspecto imaginável do Groovy. Muitas vezes, o “pensamento Java” irá te impedir de compreender o quê de fato está acontecendo por trás dos panos.
- Sua produtividade vai ser bem menor: só pra lembrar, o objetivo por trás do Groovy é justamente prover maior produtividade aos desenvolvedores Java.
Neste vídeo, os seguintes assuntos foram tratados
- O que é Groovy – (99% de chance de você já saber :) )
- Como instalar – (opcional se você só vai trabalhar com Grails)
- Principais diferenças sintáticas em relação ao Java
- Melhorias no tratamento de strings e números
- O que vêm a ser a tal tipagem dinâmica?
Segue o vídeo: espero que gostem :)
Curso itexto de Grails: Aula 1
Acabo de publicar o segundo vídeo da série sobre Grails que pretendo publicar nos próximos meses. A idéia do primeiro vídeo é mostrar a construção do ambiente de desenvolvimento que será usado no transcorrer do curso. Para quem já viu o vídeo anterior, não há muita novidade, mas há algumas bastante importantes:
- Foi inaugurada a página “Grails: um guia em vídeo“, aonde pretendo postar todos os vídeos que eu venha a publicar sobre o assunto. Vai ser massa, porque assim fica mais fácil assisti-los em sequência.
- Todo o material do curso é publicado no GitHub neste repositório.
Neste vídeo os seguintes assuntos foram tratados:
- Instalação do Grails: executo o processo no Windows 7 (mas no repositório há um texto explicando como proceder caso você seja um usuário Linux ou Mac)
- É apresentada a aplicação base: um gerenciador de estoque. É um exemplo suficientemente complexo para que eu possa em aulas posteriores me aprofundar (e BEM) nas entranhas do Grails
- Inicio o desenvolvimento básico do projeto implementando as classes de domínio e criando o CRUD básico via scaffolding dinâmico. Neste processo, daremos uma pincelada em cima dos seguintes tópicos:
- A estrutura básica de diretórios
- Classes de domínio: definição de atributos e constraints
- Scaffolding dinâmico
- Configuração do acesso a dados
- Finalmente, é gerado o pacote que pode ser instalado em praticamente todos os servidores de aplicação Java EE do mercado.
Sem mais demora, segue o vídeo:
O assunto do próximo vídeo será a linguagem Groovy e as principais diferenças desta em relação ao Java. Meu objetivo é mostrar uma série de armadilhas que podem ser evitadas pelos iniciantes e mais algumas técnicas que ajudam demais a incrementar nossa produtividade.
Espero que gostem. :)
Video: Grails: o que e porquê?
Olá, estou aqui divulgando o meu último video, chamado “Grails: o que e porquê?” que foi feito para o evento “Semana Grails no Rio”. Meu objetivo é mostrar as principais razões pelas quais Grails vale à pena e como o seu modo de trabalhar difere daquele com o qual estamos acostumados no “Java tradicional”.
É também o primeiro de uma série, visto que estou planejando regravar meu antigo curso de Groovy/Grails que fiz pela DevMedia. Espero que gostem!
Grails: o que e porquê? from Henrique Lobo Weissmann (Kico) on Vimeo.










