↓ Arquivos ↓

Categorias → Uncategorized

Primeiros passos NoSQL com MongoDB: manipulando documentos

Continuando meu post anterior sobre o assunto, é hora de colocarmos a teoria em prática. Meu objetivo agora é expor o básico sobre o funcionamento e operação do MongoDB para que, em seguida, possamos aplicar este SGBD a alguma linguagem de programação (muito provávelmente usarei o Groovy, que cai como uma luva).

Instalando o Servidor

De todos os SGBDs não relacionais que experimentei, aquele com qual tive mais facilidade para trabalhar foi o MongoDB por duas razões: ele é realmente simples e a documentação é excelente. A facilidade do sistema se apresenta no primeiro contato que temos com a criatura: instalando-o.

Simples e rápido: baixe a versão que se adequa ao seu sistema operacional neste link. Descompacte-o em um diretório de sua escolha e o bicho está quase pronto para ser usado.

Para iniciar o servidor, você deverá executar o programa mongod, presente no diretório $MONGODB/bin (entenda $MONGODB como sendo o diretório aonde você descompactou a sua distribuição do programa). Você será saudado por uma nada simpática mensagem de erro na qual encontrará um texto similar ao abaixo:

Thu Apr 15 21:32:54 Assertion: 10296:dbpath (/data/db/) does not exist

Isto ocorre porque por default o MongoDB armazena seus bancos de dados no diretório /data/db (C:\data\db se estiver usando Windows). A solução é simples: ou você cria este diretório ou inicia o processo mongod com o parâmetro -dbpath como no exemplo abaixo:

$mongodb/bin/mongod -dbpath=/home/kicolobo/mongodb

Neste caso, estou instruindo o servidor a buscar pelos arquivos de banco de dados dentro do diretório /home/kicolobo/mongodb

Nota: é importante mencionar que se eu inicio o MongoDB usando a abreviação ~ para o meu diretório home (por exemplo: ~/mongodb) o processo mongod não identifica o diretório, retornando aquela mesma entediante mensagem de erro (ao menos no Mac OS X).

Observação importante: caso você esteja usando uma versão de 32 bits do MongoDB, esta possuirá o tamanho dos bancos de dados limitados a no máximo 2 Gb.

Conectando-se

O cliente nativo do MongoDB é o programa mongo, localizado no diretório $MONGODB/bin. Com o servidor em execução, caso você inicie este aplicativo automáticamente já estará logado no servidor default, que é o local usando a porta 27017. Não é necessário prover um usuário (posso falar mais sobre gerenciamento de usuários em um post futuro no entanto). Ao iniciar o shell você será saudado por um prompt similar ao exposto na imagem abaixo:

Neste podemos fazer basicamente tudo o que quisermos com o MongoDB. Por default, estamos conectados ao banco de dados test. Para mudar de banco de dados, basta usar o comando use seguido do nome do banco de dados. Por exemplo use kico;.

Manipulando dados

Inserindo

No MongoDB, cada banco de dados é composto por um conjunto de coleções. O código abaixo, apesar de muito simples nos diz muita coisa:


> use kico
switched to db kico
> a = {posicao:1, descricao:"Primeira letra do alfabeto"}
{ "posicao" : 1, "descricao" : "Primeira letra do alfabeto" }
> db.alfabeto.save(a)
> a
{
 "posicao" : 1,
 "descricao" : "Primeira letra do alfabeto",
 "_id" : ObjectId("4bc7b65da5ec5e132c1a53a1")
}

A primeira coisa que fiz foi selecionar o banco de dados kico usando o comando use. Se este banco de dados não existisse, o MongoDB o criaria automaticamente para nós.

Em seguida, criei uma variável chamada a, cujo valor é uma estrutura no formato JSON composta por dois atributos: posicao e descricao. Lembre-se que estamos lidando aqui com um SGBD schemaless: sendo assim posso criar documentos com o formato que eu sonhar.

(Por possuir um shell baseado em JavaScript, é possível escrever scripts e usá-los para tarefas de manutenção do banco. Trata-se de um recurso fantástico que, um dia, pretendo abordar com maiores detalhes neste blog.)

Para inserir o meu documento a em uma coleção, usei o objeto db, que aponta para o banco de dados atualmente selecionado. A sintaxe para inclusão de um registro é simples:

db.[nome da coleção].save( objeto a ser salvo )

No caso, estou incluindo o documento a dentro da coleção alfabeto. Assim como no caso do banco de dados, se esta coleção não existir no banco de dados atual, esta será criada automaticamente no momento em que o primeiro documento for inserido.

Claro, eu também poderia incluir um novo registro na coleção alfabeto tal como no exemplo abaixo:

db.alfabeto.save({posicao:5, letra:"e"})

Finalmente, expus o conteúdo do documento a após ter sido incluido na coleção. Observe a inclusão de um novo atributo neste objeto: o _id .Como o próprio nome já diz, um identificador interno usado pelo MongoDB para diferenciar os objetos armazenados em nossas coleções. É importante mencionar que este atributo só será criado pelo MongoDB caso ainda não exista na estrutura a ser armazenada. Sendo assim, você é livre para criar seus próprios identificadores se quiser.

Editando e excluindo

Editar um registro também é fácil. Novamente, vamos analisar um código bem simples que nos dirá bastante coisa:


documento = db.alfabeto.findOne({posicao:1})
documento.bobagem = "Veja, estou incluindo um novo atributo completamente inútil!"
db.alfabeto.save(documento)
db.alfabeto.remove(documento)

O primeiro passo foi usar o método findOne presente na nossa coleção alfabeto. Este recebe como parâmetro um fragmento de documento e, como o próprio nome já nos diz, retorna um único resultado para nós.

Dai pra frente é simples: adiciono um novo atributo ao nosso documento e em seguida o persisto novamente na coleção usando o mesmo método save() que vimos anteriormente. A diferença é que aqui será feita uma substituição, visto que o documento em questão já possui um atributo _id.

Nota importante: você pode dar o nome que sonhar para um atributo, porém duas regras devem ser satisfeitas: O nome do atributo não deve começar com o caractere $ e o caractere ‘.’ jamais poderá ser incluido.

Continuando

No próximo post (que pretendo publicar nesta semana) vou mostrar como fazer consultas no MongoDB. Não inclui este conteúdo agora porque tornaria este post gigantesco e não trataria com o detalhamento que desejo o assunto.

Sendo assim, aguardem pelo próximo post sobre o assunto. Até lá!

Uma experiência bem sucedida com o Memcached

Memcached é um sistema de cache em memória distribuido muito fácil de usar. Como recentemente tive uma experiência maravilhosa com esta ferramenta acredito que é interessante expô-la neste post (prometo que o próximo post será sobre MongoDB). A natureza do Memcached é extremamente genérica – trata-se de um serviço de rede – sendo assim, o que descreverei pode ser aplicado sem grandes mudanças a básicamente qualquer linguagem/ambiente de execução. Mas antes de falar sobre minha experiência, vou falar um pouco sobre o funcionamento da criatura e como usá-lo com Java (consequentemente, com Groovy também).

Idéia básica

Para muitos, o conceito de cache é algo novo. Sendo assim, convém fazer uma introdução ao conceito. Imagine que você possua um conjunto de informações que repetidas vezes precise ser buscado na sua base de dados. A cada consulta, você precisa:

  • Enviar a consulta (por exemplo: SQL)
  • Esperar o processamento do SGBD
  • Receber o resultado obtido
  • Transformá-lo, tornando-o útil para sua aplicação

O objetivo do cache é evitar temporáriamente os três últimos passos do procedimento que descrevi acima, retornando para o usuário o resultado do processamento dos dados em estado cru. Se 2 + 2 são 4, por que calcular este valor toda vez que você receber esta pergunta se é possível armazenar apenas o resultado e reaproveitá-lo quando necessário?

O Servidor Memcached

O Memcached é um serviço de rede. No site oficial (http://www.memcached.org) é possível baixar a última versão, que vêm como código fonte (veja este link para maiores detalhes sobre como proceder com a instalação). Se estiver usando Linux, instalá-lo é ainda mais fácil, visto que muito provávelmente a criatura já estará disponível nos repositórios de sua distribuição.

Instalado, basta executar o comando memcached para iniciar o serviço. É importante conhecer alguns parâmetros, cuja listagem segue abaixo:

-m : quanta memória (em Mbs) o Memcached irá usar. Caso omitido, o valor default é 64 Mb.

-p : qual a porta TCP a ser usada. Caso omitido, o valor default é 11211

-u : qual a porta UDP a ser usada. Como a porta TCP, o valor default é 11211 caso omitido.

-v : Modo verboso: o Memcached irá expor na tela o que está executando. É bacana quando estamos aprendendo a usar o bichinho. Interessante mencionar que há duas outras opções: -vv (mais verboso) e -vvv (ainda mais verboso)

Sendo assim, se eu executar o comando memcached -m 540 -v -p 11000 -u 11000 iniciará o serviço  com 540 Mb de memória no modo verboso definindo como portas UDP e TCP a 11000.

Como mencionei, o Memcached é um servidor distribuido, mas como minha experiência até o momento envolveu apenas uma instância ainda não tenho conhecimento suficiente para compartilhar.

O que é e como é armazenado

Pense no Memcached como uma tabela de hash gigante. Toda informação individual armazenada possui basicamente 3 elementos:

Identificador: um texto com tamanho máximo de 250 caracteres que identifica um corpo de informação. Equivale à chave primária com a qual já estamos acostumados a trabalhar no modelo relacional. Não há regras com relação ao seu valor: sendo assim, você é livre para identificar suas informações como quiser.

Tempo de duração: o tempo (em segundos) que o Memcached manterá esta informação na memória. O tempo máximo suportado é 30 dias.

Corpo: a informação em si. No caso do Memcached, esta possui tamanho máximo de 1 Mb. Se for pouco pra você, sempre é possível dividir a sua informação em mais de um bloco, compactá-la ou, se preferir, alterar o código fonte do Memcached (eu o li inteiro, e é BEM fácil de entender (se você souber C)).

Lembre-se: não se trata de um banco de dados. Tudo no Memcached, assim como na vida (sôou poético!) é passageiro. A idéia é evitar que tenhamos de acessar o SGBD, que é um processo MUITO mais caro computacionalmente, e não substitui-lo!

O cliente Memcached

O primeiro passo é escolher qual biblioteca cliente usar para acessar o Memcached. Há diversas, implementadas em tudo o que você imaginar: C, C++, PHP, MySQL, Python, Perl, Ruby… No nosso caso, vou falar do SpyMemcached, que é um cliente para Java. Uma lista com “alguns” dos clientes disponíveis atualmente pode ser acessada neste link.

O SpyMemcached é composto por  um único arquivo Jar, o que torna seu deploy muito simples. Basicamente o único pacote que você vai precisar é do net.spy.memcached.

Obtendo uma conexão com o Memcached

Basta criar uma nova instância da classe MemcachedClient, tal como no exemplo abaixo:


MemcachedClient client =new MemcachedClient(AddrUtil.getAddresses("0.0.0.0:11211 10.10.10.69:11211"));

Repare que passei dois servidores distintos. Usando este construtor você poderá adicionar um ou mais servidores aonde serão feitas as suas buscas.

Buscando e inserindo informações

Buscar e inserir informações com o SpyMemcached é simples. O código abaixo é quase que auto-explicativo.


MemcachedClient client =new  MemcachedClient(AddrUtil.getAddresses("localhost:11211"));

// O que irei armazenar no Memcached
Pessoa pessoa = new Pessoa();
pessoa.setNome("Kico");
pessoa.setCidade("BH");

// Incluindo informações

client.add("chave_pessoa", 120, pessoa);

// Buscando a informação

Pessoa noCache = (Pessoa) client.get("chave_pessoa");

Quando incluimos uma informação no Memcached, devemos passar 3 parâmetros: a chave de identificação, o tempo em segundos e o que queremos armazenar. No caso de um objeto, este obrigatóriamente deverá implementar a interface java.io.Serializable. Caso contrário será disparada uma excessão.

Já para obter a informação, basta passar a chave que a identifica e em seguida fazer o type casting para o tipo desejado.

Ah: e como fechar a conexão com o servidor? Simples: execute o método shutdown() da classe MemcachedClient.

Conhecendo os métodos abaixo da classe MemcachedClient você já pode começar a trabalhar (e bem) com o Memcached:

void MemcachedClient.add(String chave, int segundos, Object valor): insere uma informação no servidor Memcached. Se já existir um valor definido para esta chave no servidor, este será mantido pelo Memcached.

Object MemcachedClient.get(String chave): retorna um valor armazenado no Memcached

void MemcachedClient.shutdown(): fecha a conexão com o Memcached

void MemcachedClient.remove(String chave): remove uma informação armazenada no servidor

void MemcachedClient.replace(String chave, int segundos, Object valor): substitui um valor armazenado no servidor.

Dica: aproveite ao máximo suas conexões com o Memcached buscando o maior número possível de registros, mas nunca se esqueça de fechá-las, pois o serviço começa a apresentar problemas quando o número de conexões simultâneas é muito alto.

Minha experiência

Eis a situação: possuimos uma aplicação feita em Grails cuja base é uma biblioteca escrita em Java. Esta biblioteca é também usada por diversas aplicações executadas no ambiente desktop dentro da empresa.  Fiz uma imagem que, espero, ilustre a situação.

Em nosso servidor físico aonde já se encontrava instalado o Tomcat aproveitei para colocar em execução o servidor do Memcached.

Como sou o pai da biblioteca legada que mencionei acima, a refatorei para que ao invés de usar a biblioteca de cache anterior, passasse a usar o Memcached.

Em seguida, atualizei tanto a nossa aplicação Grails quanto os clientes desktop (nestas horas você começa a AMAR o Java Webstart) e voilá: resultado imediato.

Como todos acessam o mesmo servidor Memcached, no momento em que uma aplicação desktop ou  web alimentam o servidor de cache, automáticamente todas as demais instâncias se beneficiam. Resultado? Nossa performance global aumentou no mínimo 3 vezes, e o número de chamadas ao nosso SGBD diminuiu em aproximadamente 40%.

É importante mencionar  que em nosso ambiente é muito comum mais de um usuário concorrentemente necessitar do mesmo conjunto de informações. Isto é fundamental, pois caso contrário não teriamos um ganho de performance, mas sim  perda, pois antes de executar uma consulta no SGBD, sempre seria feita uma busca no Memcached.

É fundamental lembrar o seguinte aqui: não temos um cache local, mas remoto. O ganho da performance é obtido em grande parte porque não precisamos popular objetos, visto os mesmos já virem “prontos” do servidor para nós.

Antes do Memcached haviamos pensado sériamente em usar o Terracota. Mas como nosso ambiente é heterogêneo, e há programas escritos em .net, C/C++, VB6 e PHP, o Memcached caiu como uma luva, pois assim podemos aproveitar a mesma estrutura (e dados!) entre estas diferentes plataformas de execução/desenvolvimento (claro, com os devidos cuidados para evitar a bagunça).

Recomendadíssimo portanto o seu uso. Espero que este post seja útil aos que estejam interessados em usar a ferramenta.

Melhorando seus layouts com 960 Grid System (para não designers como eu)

Em um post anterior expliquei como usar SiteMesh com Grails. Agora é hora de expor uma descoberta recente que fiz: o 960 Grid System (960gs), criado por Nathan Smith. Para aqueles que não conhecem, o 960gs é um framework CSS. Como não sou designer (apesar de tentar com toda a minha teimosia), o termo framework CSS é novidade pra mim também.

A definição do termo na Wikipédia é a seguinte: “trata-se de uma biblioteca pré-configurada cujo objetivo é facilitar a criação de layouts o mais próximo possível dos padrões web”. A definição Kiconiana é mais simples: “arquivos CSS prontos para que você possa criar layouts bacanas e dentro dos padrões web de forma rápida”.

Um sistema de grade (grid system) é uma técnica adotada em layouts para se organizar o conteúdo de uma página impressa. Por sorte, a técnica também é adotada com sucesso em aplicações web!

Idéia central

A idéia básica do sistema é fornecer uma grade aonde possamos organizar o conteúdo de forma consistente. No caso do 960gs, esta grade encontra-se sobreposta a uma área de 960 píxels de largura. Por que 960 pixels? Por que é a resolução mais comum dos navegadores atualmente, sendo assim resolveram adotar esta convenção. No caso do 960gs, ele já vêm pré-configurado com 3 possibilidades: 12,16 ou 24 colunas. Na imagem abaixo está um exemplo de layout usando 12 colunas:

Como pode ser observado, há 12 colunas de cor rosa, com um espaço entre elas. No padrão 960gs, cada coluna possui 10 pixels de margem tanto esquerda quanto direita.

Abaixo está um site que acabei de terminar usando o layout. Como você pode perceber, as áreas em vermelho encontram-se exatamente dentro do espaço delimitado pelas colunas.

Preparando o terreno

O primeiro passo para usar o 960gs é fazer o download no site oficial: http://960.gs. Trata-se de um arquivo zipado que, ao ser descompactado, irá apresentar a seguinte estrutura de diretórios:

code: o que nos interessa: são os arquvos .css
templates: arquivos de imagem para quem quiser fazer mockups usando algum editor gráfico como Gimp ou Photoshop
sketch_sheets: um arquivo no formato PDF que você pode imprimir e desenhar em cima
licenses: bla bla bla jurídico

Copie os arquivos 960.css, reset.css e text.css para o diretório da sua aplicação (seja ela feita em PHP, Grails, HTML puro ou qualquer outra coisa). Em seguida, dentro da tag <head> da sua página, inclua o código abaixo:

<link rel="stylesheet" href="css/reset.css" />
<link rel="stylesheet" href="css/text.css" />
<link rel="stylesheet" href="css/960.css" />

Lembre-se de referenciar os arquivos css de acordo com a sua localização dentro da aplicação.

Entendendo a lógica

A regra é a seguinte: o layout da sua aplicação será organizado em linhas e colunas. Cada linha deverá possuir n colunas, aonde n representa o padrão que você adotou ao usar o 960gs. É desnecessário, mas se você quiser saber a largura de uma coluna, use a fórmula abaixo:

largura da coluna = (960 / (número de colunas)) – (margem da coluna * 2)

Como mencionei acima, cada coluna possui duas margens (direita e esquerda), cada uma com 10 pixels de lado. Sendo assim, no nosso exemplo cada coluna terá 60 pixels de largura.

Pondo em prática

O 960gs é aplicado em um container. Sendo assim, escolha uma div dentro da sua página que conterá todas as demais e altere-a para que fique tal como no exemplo abaixo:


<div class="container_12">
 ...
 </div>

A classe container_12 define que aquele elemento está adotando uma grade de 960 pixels com 12 colunas. Se quisesse usar uma grade com 16 colunas, bastaria usar a classe container_16.

A melhor maneira de explicar o funcionamento da técnica é visualmente. Sendo assim, observe a imagem abaixo, que é o exemplo fornecido com o framework:

Repare que é um layout composto por duas linhas. A primeira ocupa todas as 12 colunas, enquanto o segundo é dividido em dois grupos: um contendo uma coluna e outro contendo as 11 restantes. Para obter este resultado, escreve-se o código abaixo:


<div class="container_12">
   // Primeira linha
   <div class="grid_12"></div>
   // Segunda linha
   <div class="grid_1"></div>
   <div class="grid_11"></div>
</div>

A classe grid_[número de colunas] representa o número de colunas que o elemento deverá ocupar. Sendo assim, na primeira linha usamos a tag grid_12, pois queriamos que toda a largura fosse ocupada.

Já na segunda linha, como queriamos dividir a largura em dois blocos, definimos para o primeiro elemento a tag grid_1 (uma coluna) e grid_11 para o seguinte (11 colunas).
A regra se manteve: cada linha deve possuir 12 colunas.

Aumentando a flexibilidade

Agora, vamos aumentar a flexibilidade dos nossos layouts. E se quiséssemos apenas um componente que não ocupasse a página inteira, mas que ao mesmo tempo não estivesse próximo às margens da página, tal como no exemplo abaixo?

Agora entra em prática mais duas classes: prefix[colunas] e suffix[colunas] que representam respectivamente quantas colunas deverão vir antes do nosso componente e quantas depois. Reparou? Mantivemos aqui a regra de manter o número de colunas fixo!

Obteriamos o resultado acima portanto com o código abaixo:


<div class="grid_1 suffix_2 prefix_9"></div>

Duas colunas como sufixo e 9 como prefixo e uma coluna no meio. 2 + 9 + 1 = 12!

Aproveitando as margens laterais das colunas

É possível também aproveitar as margens direita e esquerda da coluna. Se quiser que seu componente ocupe a largura da margem esquerda, adicione a ele a classe alfa. Quer aproveitar a coluna da direita? Adicione a classe omega!

Simples assim!

Considerações finais: não interfira no trabalho do 960gs

No meu aprendizado observei o seguinte: como o objetivo do 960gs é dispor os elementos da sua página pra você, em momento algum o designer deverá definir em seus arquivos CSS o tamanho dos seus componentes. Isto irá interferir com o estilo definido pelo 960gs e, consequentemente, as coisas não sairão tão bacanas quanto gostaríamos.

Lembre-se: o objetivo do 960gs é resolver o problema da largura e disposição dos elementos da página. Tentar interferir neste processo é a mesma coisa que ir a um médico e começar a dar pitaco em seus diagnósticos, resumindo: não da certo (a não ser que você também seja um médico).

Você também deverá ignorar o atributo float: o 960gs já faz isto pra vocë. Defini-lo nestes componentes só irá anular o framework.

Indo além

E se você quiser um layout com menos ou mais de 960 pixels, ou mesmo um número de colunas diferente de 12, 16 ou 24? Como fazer? Neste caso você precisa de um sistema de grade variável. A SprySoft tem um gerador de grades customizados online e gratuito para você. Basta acessar este endereço: http://www.spry-soft.com/grids/

Grails: entendendo o SiteMesh

Ao aprender Grails um dos componentes que mais me confundiu foi o SiteMesh. Intuitivamente eu sabia o que estava acontecendo, mas toda vez que buscava escrever a respeito acabava me enrolando.

E acredite: você só conhece de fato algo se consegue descrevê-lo em palavras, por escrito. Trabalhando na última parte da minha série “Grails: do Groovy à Web” que está sendo publicada na Java Magazine tive a certeza de finalmente compreender de fato o que é o SiteMesh e como funciona. E a razão pela qual tinha tanta dificuldade é simples: estava viciado no Tiles.

Enquanto o Tiles é baseado no padrão composição (composite), o SiteMesh é baseado no padrão decorador (decorator).  A diferença entre os dois  é: no composite temos um layout central que contém uma série de espaços a serem preenchidos por  templates.

Já o padrão decorator possui um layout central que também possui espaços a serem preenchidos: a diferença é que apenas os elementos ausentes serão preenchidos. Eu não preciso adicionar todos os componentes tal como estava acostumado na época do Struts 1/Tiles.

Bla bla bla demais, é hora de irmos à prática. No Grails, todos os layouts do SiteMesh ficam armazenados no diretório grails-app/views/layouts. Por padrão já há um layout pré-definido, cujo nome é main.gsp armazenado neste diretório. É importante lembrar que se trata de um arquivo GSP convencional, cujo código exponho abaixo:

<html>
<head>
<title><strong><g:layoutTitle default="Grails" /></strong></title>
<link rel="stylesheet" href="${resource(dir:’css’,file:’main.css’)}" />
<link rel="shortcut icon" href="${resource(dir:’images’,file:’favicon.ico’)}" type="image/x-icon" />
<strong><g:layoutHead /></strong>
<g:javascript library="application" />
</head>
<body>
<div id="spinner" style="display:none;">
<img src="${resource(dir:’images’,file:’spinner.gif’)}" alt="Spinner" />
</div>
<div id="grailsLogo"><a href="http://grails.org"><img src="${resource(dir:’images’,file:’grails_logo.png’)}" alt="Grails" border="0" /></a></div>
<strong><g:layoutBody /></strong>
</body>
</html>

A única diferença entre o arquvo GSP e uma view convencional é a presença de três tags: g:layoutTitle, g:layoutHead, g:layoutBody. Falarei delas logo a seguir, porém antes de continuar, vou expor a view mais idiota possível: algo que não exponha basicamente nada, e cujo código fonte é o seguinte:


<html>
 <head>
 <meta name="layout" content="main"/>
 </head>
 <body>

 </body>
</html>

Colocando a aplicação para executar, e acessando-a, no entanto, é renderizado algo inicialmente inexperado:

De onde saiu este logotipo do Grails? Do layout main que defini anteriormente. No caso, eu instrui o Grails a usar o SiteMesh ao inserir a seguinte tag na minha view:


<meta name="layout" content="main"/>

Esta tag basicamente diz: “aplique o layout definido no arquivo grails-app/views/layouts/main.gsp a esta view”. E aqui entra a jusitificativa do mesh no nome SiteMesh: ao invés de incluir o conteúdo de um arquivo em outro, o que é feito na realidade é a fusão do conteúdo da view no corpo do layout!

Isto fica claro com a descrição das 3 tags que descrevi acima (consulte a primeira listagem para que fique claro):

g:layoutTitle – define qual será o conteúdo da tag title embutido na tag head. Repare qeu esta tag possui um atributo chamado “default”. Caso na view a tag title já esteja preenchida, será incluido no arquivo HTML final o conteúdo da tag title da view. Caso contrário, o conteúdo será aquele especificado no parâmetro default

g:layoutHead – o conteúdo da tag <head> da view será inserido no local do layout aonde a tag g:layoutHead se encontra.

g:layoutBody – o conteúdo da tag <body> da view será inserido no local do layout aonde a tag se encontra.

Resumindo: no SiteMesh não temos inclusão, mas sim fusão.

Espero que com esta descrição o recurso fique tão claro para vocês quanto pra mim.

Grande abraço e até a próxima!

Grails: lista de recursos

De tempos em tempos alguém me pergunta aonde é possível aprender mais sobre Grails. Como basicamente sempre envio a mesma resposta – e o número destes e-mails tem crescido considerávelmente – acho que é uma boa idéia postar aqui uma pequena lista de sites/autores relacionados ao assunto para que vocês possam se aprofundar mais no assunto.

Inspiracional

O que me despertou para Grails foi uma palestra de Scott Davis (que produz MUITO material sobre o assunto, basta ver a lista abaixo) de 2007 entitulada “Groovy and Grails Intro”. Se você não sabe o que é Grails e quer ter uma idéia, sugiro que assista os dois vídeos abaixo:

Fontes básicas

Alguns recursos são fundamentais na minha opinião: se você está aprendendo Grails sem conhecê-los, é muito provável que esteja perdendo muito tempo.

Grails User Guidehttp://grails.org/doc/latest – O guia do usuário oficial do framework é uma das peças de documentação mais bem escritas que conheço. Por si só já é mais do que suficiente para que qualquer um possa aprender – e bem – a trabalhar com Grails.

Getting Started With Grails (segunda edição) – eBook em formato PDF que pode ser baixado gratuitamente neste link – A primeira edição deste livro foi escrita por Jason Rudolph, e a segunda conta com a participação do Scott Davis. Faz juz ao nome, pois após sua leitura o leitor já está apto a começar (o livro não se aprofunda) a trabalhar com Grails. Leitura obrigatória.

Série Mastering Grails, de Scott Davis – IBM DeveloperWorks – link – Série de artigos publicados na DeveloperWorks por Scott Davis desde antes da versão 1.0 do Grails que foca em detalhes do funcionamento do framework que vão desde o básico do GORM até criação de plugins.

Série Pracitally Groovy, também de Scott Davis – IBM DeveloperWorks – link – Nesta série de artigos são abordados temas diretamente ligados ao dia a dia de quem trabalha com a linguagem Groovy, como por exemplo procesamento de arquvios XML, metaprogramação, etc. É interessante salientar a importância histórica desta série, que existe desde 2004, ficou parada por um tempo e foi em seguida retomada em 2009. É um excelente ponto de partida para quem deseja se aprofundar na linguagem.

Livro Groovy in Action – Traduzido para o português pela editora Alta Books como “Groovy em Ação” – Dierk König – Aprender Groovy é fundamental. Sim, é muito parecido com Java mas não implica que seja igual. Conhecer as nuancias da linguagem é de extrema importância. Esta edição é de 2007 (a tradução não é tão terrível como as demais da mesma editora) mas fornece uma excelente base para a compreensão da linguagem (e uma brevíssima introdução ao Grails pré 1.0)

Vídeo aulas: Grails do Início ao Fimhttp://aulas.itexto.com.br – Publiquei em 2008/2009 um curso introdutório sobre Grails para a editora DevMedia que fez um certo sucesso e, acredito, pode ser de grande valia a quem esteja iniciando.

Aonde encontrar ajuda

Passada a teoria entra a prática. No seu dia a dia é fundamental que você troque idéias com outros profissionais que estejam trabalhando com a ferramenta. Minhas sugestões neste caso são as seguintes:

Grails Brasilhttp://www.grailsbrasil.com.br – Iniciei o Grails Brasil em 2008 e atualmente contamos com mais de 600 membros. Acredito que uns 80% dos problemas que iniciantes enfrentem no seu aprendizado já se encontre em nosso banco de dados. Sendo assim, é sempre conveniente ao encontrar problemas pesquisar neste site.

Stack Overflow – http://www.stackoverflow.com – Não só problemas relacionados a Grails, mas com basicamente todas as linguagens de programação, frameworks, bibliotecas ou qualquer problema de programação que você sonhar. De todos os fórums que conheço, é sem dúvidas o melhor (em inglês).

Listas de discussão por e-maillink – Você também pode encontrar ajuda nas listas de discussão por e-mail oficiais do Grails, que são excelentes e são um excelente modo de se conhecer usuários mais experientes também.

Blogs

Blogs são fundamentais para o aprendizado e atualização, porque neles podemos ver o que os reais usuários do Grails estão fazendo com a ferramenta. Como são vários – e não quero correr o risco de desmerecer alguém devido a um lapso de minha memória –  acredito que o ideal seja que você mesmo escolha a partir de um dos agregadores de blogs abaixo:

GroovyBlogshttp://www.groovyblogs.org – É um agregador de blogs que, como este, são voltados para assuntos relacionados a Groovy e Grails

DZonehttp://www.dzone.com – Outro agregador de blogs sobre desenvolvimento de sistemas muito interessante, e que possui uma seção voltada para Groovy/Grails

InfoBlogshttp://www.infoblogs.com.br – Agregador de blogs nacional que possui uma seção também dedicada a Groovy e Grails – link (nota: no caso do InfoBlogs, já vi diversos posts meus sobre Grails não aparecerem nesta seção, mas apenas na página principal)

Grails Brasil {Blogs}http://blogs.grailsbrasil.com.br – Agregador de blogs nacionais relacionados a Grails mantido pela comunidade Grails Brasil.

Finalmente

Claro que não é necessário que você leia todas estas fontes, apenas o Grails User Guide já é mais do que o suficiente, porém é importante lembrar que na nossa área não existem fórmulas prontas. Grails só parece simples em um primeiro momento porque banaliza algumas tarefas repetitivas. O que diferencia um bom profissional do mediocre (ou abaixo disto) é o conhecimento adquirido.

Sendo assim, fica ai a lista de recursos básicos. Bom proveito!

Por que resolvi largar o HTML e partir pro Flash (Flex na realidade)

No decorrer de 2009 iniciei um projeto cujo principal objetivo técnico consistiu em levar ao extremo o que consigo fazer atualmente usando Grails na camada de controle e domínio e a dobradinha HTML/CSS/Javascript na camada de visualização (atualmente, só de ver uma interface 100% baseada em campos textuais e caixas de seleção já começo a bocejar).

Na camada de visualização quis ver o quão próximo do desktop eu conseguiria chegar usando HTML, CSS e Javascript (muito JQuery neste caso). Nos primeiros momentos, fiquei bastante surpreso com o que estava conseguido: muito drag and drop e uma interface bem diferente do feijão com arroz que estava habituado a produzir. Porém, conforme o projeto progredia, algo ficava nítido pra mim: na camada de visualização estava usando ferramentas erradas. Sendo assim, parei de me auto enganar e resolvi aceitar um fato: HTML não foi feito para se criar aplicações ricas.

É importante que nos lembremos das raízes históricas da web: sua estrutura foi construída ao redor do que se intencionava ser um mecanismo de distribuição de documentos, e não para se criar aplicações (só pra lembrar, é Hypertext Transfer Protocol). Resumindo: faz muito sentido usar HTML para se expor conteúdo textual, mas muito pouco para se criar aplicações com interfaces ricas (o que é o meu caso).

O pesadelo do HTML (os tais “web standards”)

A verdade é: usar HTML para criar aplicações com interfaces ricas ainda é (e vai continuar sendo por um bom tempo) um pesadelo.

Sim, é verdade que as coisas estão melhorando, e temos alguns bons indícios disto:

  • Google tá puxando o HTML 5 no Chrome, e o Firefox e Internet Explorer já estão começando a oferecer algum suporte
  • O maldito Internet Explorer 6 está começando a desaparecer
  • Bibliotecas como jQuery conseguem minimizar a discrepancia entre as diferentes implementações do JavaScript presente nos navegadores
  • Aplicações como Google Maps expõe que de fato é possível criar aplicações ricas usando “apenas” HTML, CSS e muito JavaScript

Yeap: mundo lindo né? Só que tem alguns “pequenos” problemas.

Microsoft Internet Explorer ainda domina

Ainda não sairam as estatísticas do quarto trimestre de 2009, mas é fato: até o terceiro trimestrede 2009 quase 70% das pessoas ainda usam o maledeto IE. (fontes: NetApplications, W3Counter, StatCounter). O IE8 é mais próximo dos padrões do W3C, é verdade, porém sabendo um pouco de história, fica nítido que será temporário, e em pouco tempo a Microsoft irá incluir novas “features” no seu navegador. (pior: IE6 ainda é o browser mais usado (fonte: NetApplications).

Os browsers ainda não são todos 100% compatíveis com os padrões web

Se você quer criar uma aplicação rica usando apenas web standards, ou seja, HTML, CSS e Javascript, no mínimo os navegadores devem ser compatíveis com o padrão, certo? Atualmente apenas o Chrome 2 e o Safari 4 conseguem passar no Acid3 (fonte). Juntos correspondem atualmente a algo em torno de no máximo uns 9% do mercado. (só pra “animar”, o IE8 conseguiu passar com nota 10/100).

HTML 5 ainda está longe de se tornar realidade

O HTML 5 cuja especificação começou em 2004 vai ter a sua primeira versão candidata publicada (talvez) em 2012 E vai ser recomendado pelo W3C a partir de 2022 (fonte). Ok: então se o mundo não acabar em 2012, teremos de esperar “apenas” mais 10 anos.

Claro, nada impede que os navegadores comecem a implementar o padrão, certo? De novo, não é lá muito animador, basta ver o que temos hoje (fonte (yeap: Wikipédia mesmo, porém as fontes indicam ser um post confiável)). Seu cliente topa esperar todo este tempo?

Nada contra os web standards (muito a favor!), desde que sejam usados no lugar certo

Se o seu trabalho não exige uma interface rica (com drag and drop, multimídia de fato e interação que vá além de meros campos textuais e caixa de seleção), e serve apenas para expor conteúdo, web standards é o canal (aliás, o único que conheço), pois apresenta diversas vantagens:

  • Maior compatibilidade entre navegadores (sempre relativa)
  • Carregamento mais rápido
  • Facilidade de indexação por motores de busca
  • Código limpo

Quer usar apenas web standards para criar aplicações ricas? Ok! Faça um jogo que valha à pena usando apenas Javascript, HTML/CSS compatível com todos os navegadores e depois ma apresente. :)

Como acabei optando pela plataforma Flash

O caminho natural para o meu caso, que sou especializado de fato na plataforma Java seria o JavaFX. No entanto, alguns fatores pesaram muito a favor da solução da Adobe:

  • Flash é uma tecnologia madura
  • 98% dos computadores possuem o Flash Player instalado (fonte)
    (multiplataforma e PADRÃO é ISTO)
  • É lingua franca entre designers (com os quais a cada dia que se passa, tenho tido de interar mais e mais), pois é completamente integrado às ferramentas gráficas da Adobe (que são as melhores)
  • ActionScript é uma linguagem que se mostrou surpreendentemente poderosa para mim, que até então a esnobava com a maior tranquilidade (bem feito pra mim!)
  • Foco na parte visual
  • Flex é agora completamente open source (se não o fosse, estaria usando JavaFX agora)
  • Flex e Air

O que me fez realmente me apaixonar de fato, confesso, foi o Flex. Conforme ia estudando a tecnologia, fiquei fascinado com a riqueza que ela me oferece. Basicamente, é o Flash, porém com uma roupagem mais próxima da que desenvolvedores de aplicações como eu estamos acostumados. O projeto que mencionei no início deste blog está sendo atualmente refeito em Flex: e o resultado está sendo maravilhoso.

Com Flex consigo acessar via HTTP (e também por WebServices, bancos de dados, etc) de uma forma MUITO simples tudo o que preciso, ou seja, é fácililimo de integrar com meu código legado. Existe inclusive um plugin para Grails bastante interessante (fonte). Ou seja, continuo trabalhando no backend com as mesmas ferramentas que usava antes: a única diferença é que agora uso Flex na camada de visualização quando preciso de algo mais elaborado.

Além disto, outro fator importantíssimo foi o Air, que nos permite transformar a nossa aplicação web em uma aplicação desktop de uma forma incrívelmente simples.

Conclusões

A conclusão que chego é a seguinte: se sua interface será simples, e não requer nada que vá além do que o HTML 4 de hoje com JavaScript e CSS podem te oferecer, fique com os padrões web de hoje. Eles te atenderão perfeitamente. Abrace-os e defenda-os com unhas e dentes.

No entanto, se sua aplicação requer uma interface rica, que vá além dos controles HTML, e não é algo cujo principal propósito seja expor informação textual ou pictórica, opte por alguma tecnologia RIA (Silverlight, JavaFX e Chrome Frame (considero o Frame uma plataforma RIA, visto que é um plugin assim como os demais) são MUITO interessantes também), pois irá lhe poupar MUITO tempo e, querendo ou não, é a ferramenta certa para este tipo de trabalho.

Acredito em um meio termo: nada impede misturar web standards com algum framework RIA, pois no caso do projeto que mencionei, é exatamente o que estou fazendo neste momento.

Neste ano estou apostando no Flex. Aguardem por vários posts a respeito conforme me aprofundo na ferramenta e, mais importante: Feliz 2010!

PS: agora, por caridade: não empolgue e faça seu blog ou página corporativa usando apenas algum framework RIA ok? Assim você quebra a bicicleta! :)

Groovy Dinâmico

Fato: mais da metade das pessoas que conheço e programam em Groovy nunca usaram invocação dinâmica de métodos simplesmente por não saber o que é ou simplesmente como funciona. Sendo assim, sem mais delongas, vamos por a mão na massa:

Vamos supor que exista a classe PatoLouco implementada em Java tal como no código abaixo:


class PatoLouco {

public void digaQua() {

System.out.println("Qua!");

}

public void digaQuaQua() {

System.out.println("Qua Qua!");

}

}

Em Java, se quisermos invocar um dos métodos presentes na classe, temos de satisfazer um requisito básico: ele deve estar implementado, pois isto é verificado em tempo de compilação pela linguaem. De acordo com este ponto de vista, temos duas alternativas: ou a própria classe já implementa estes métodos OU a classe implementa uma interface como a descrita abaixo:


public interface Pato {

public void digaQua();

public void digaQuaQua();

}

/*

E seguindo esta lógica, poderemos ter zilhões de tipos diferentes de patos, tal como a classe abaixo.

*/

public class PatoNaoTaoLouco implements Pato {

public void digaQua() {

System.out.println("um qua não tão louco assim");

}

public void digaQuaQua() {

System.out.println("Qual a razão de ter de dizer dois 'quas'?");

}

}

A presença das interfaces nos garante que os métodos serão implementados pelas nossas classes do tipo Pato. Se em um futuro não tão distante quanto parece formos preguiçosos em nossa modelagem e quisermos lidar com galinhas e outros tipos de aves, iriamos criando nossas interfaces, até chegar a um ponto no qual teriamos uma classe tal como a abaixo:


public class AveOrnitorrinca implements Pato, Galinha, Avestruz, Ganso, Aguia, Marreco {

// zilhões de métodos implementados de acordo com as interfaces

}

Linguagens dinâmicas como Groovy resolvem este problema aplicando o “princípio do pato”: se anda como um pato, corre como um pato e ‘fala’ como um pato, é porque é um pato.  Sendo assim, vou apresentar um dos exemplos mais batidos deste principio no código Groovy abaixo:


class Cachorro {

def incomode() {println "Lato sem parar. Au au auuuuu!"}

}

class Gato {

def incomode() {println "Te arranho sem parar. Grite!"}

}

// repare que não há aplicação de herança ou interfaces.
// o código abaixo executará normalmente

instancias = [new Gato(), new Cachorro()]

for (instancia in instancias) {

instancia.incomode()

}

A saída que teremos será:


Lato sem parar. Au au auuuuu!
Te arranho sem parar. Grite!

Uma solução muito mais limpa do que em Java não é mesmo? Isto porque a verificação dos métodos é feita em tempo de execução. Na realidade, é possível ir além. Observe o código abaixo:


class CachorroLouco {

def lata() {println "Au!"}

def deite() {println "Deitado"}

def role() {println "Rolando!"}

def digaIsto(isto) {println isto}

}

/* Criei uma matriz de strings contendo os nomes dos métodos acima*/
nomeDosMetodos = ["lata", "deite", "role"]

/* E agora, um pouco de "mágica" */

cao = new CachorroLouco()

for (metodo in nomeDosMetodos) {

cao."${metodo}"()

}

// Claro, o código abaixo também é válido

cao."lata"()

// E com parâmetros, seria a mesma coisa:

cao."digaIsto"("Isto!")

Não é legal? Passando uma string para a minha instância, em tempo de execução eu posso invocar métodos dinâmicamente, o que abre uma gama imensa de possibilidades.

O que acontece se o método não existir?


new CachorroLouco()."faca_algo_impensado"()

// Groovy me dará esta saida:

No signature of method: CachorroLouco.faca_algo_impensado() is applicable for argument types (...)

Uma excessão do tipo groovy.lang.MissingMethodException será disparada. No entanto, podemos resolver este problema sobrescrevendo o métodomethodMissing em nossa classe, tal como no exemplo abaixo:


public class CachorroLouco {

def methodMissing(String name, args) {
println "O método ${name} não foi implementado seu perdido!"
}

//  restante da classe abaixo

}

Quando um método não é encontrado em uma classe, Groovy irá executar este método que, se for sobrescrito, poderá lidar com o seu caso específico. E neste momento você me pergunta: e se for uma classe implementada em outra linguagem, como Java, por exemplo: como lidar com esta situação?

Ai entra a nosso amigo (ou seria amiga?) ExpandoMetaClass

Groovy nos permite incluir novos comportamentos em classes já existentes. Fazemos isto usando a meta classe ExpandoMetaClass, que nos permite adicionar novos métodos, construtores e propriedades usando a sintaxe da closure que já conhecemos.

Sendo assim, o código abaixo é perfeitamente válido:


String.<strong>metaClass</strong>.sempreImprimaIsto = { ->

println "Sempre imprimirei isto"

}

"sou uma nova string".sempreImprimaIsto() //método incluido na hora.

// Lembra dos codecs de string do Grails? Funcionam exatamente assim.

Em nosso caso, bastaria injetar o método methodMissing em nossa classe CachorroLouco, exatamente como no exemplo abaixo:


CachorroLouco.metaClass.methodMissing = {String methodName, args ->
println "O método não existe"
}

É ou não é MUITO legal?

Armadilhas: o desenvolvedor interface

No dicionário kiconiano acabo de incluir um novo termo: desenvolvedor interface, cuja definição é:

“desenvolvedor que acidentalmente acaba se tornando a interface dos seus sistemas”

Esta é uma situação comum em empresas nas quais TI é um meio e não um fim: ocorre quando os realmente interessados pelo resultado final de um sistema (normalmente relatórios) não o utilizam diretamente, mas sim através daquele que o desenvolveu.

Você sabe quando esta situação ocorre ao ouvir frases como “ei Fulano: será que você pode enviar para o meu e-mail o relatório X?” e este não é um novo tipo de relatório, mas sim aquele que o usuário precisa esporádicamente já faz algum tempo.

No frigir dos ovos, o que ocorre é a inclusão de uma nova camada no sistema: o desenvolvedor, tal como no esquema abaixo:

O desenvolvedor deixa de ser o profissional responsável por desenvolver e criar soluções e passa a ser mais uma camada do sistema: a sua interface. É fato: o cliente sempre quer o resultado final, porém ao cair neste tipo de situação, o que obtém é muito mais caro que o inicialmente proposto (afinal de contas, o “tal do sistema” não funciona sem a presença do “desenvolvedor”).

Já passei por uma situação similar (e vejo alguns companheiros passando pela mesma) e, após me concentrar nas questões abaixo, fica nítido que ao menos em 90% dos casos a culpa é nossa.

Pergunte-se:

Você tem certeza de que seu software é fácil de usar?

Muitas vezes o produto gerado é tão complexo que o usuário final fica com medo de se aproximar. Lembre-se: o que é fácil para você não necessáriamente o é para o resto do mundo.

Fórmula kiconiana: software difícil = atividade tediosa = mais um desenvolvedor que vira interface.

Seu usuário sabe usar o sistema?

Resolvida a primeira possibilidade, segue a segunda: será que você treinou o seu usuário corretamente? A documentação do seu sistema é legível para seres humanos comuns (leia-se: que não trabalham na área de TI)?

Seu sistema é de fato confiável?

Ponha-se na situação do seu usuário. Ele sabe usar o seu software, que considera até agradável. Porém, ao tentar executar determinada tarefa, se depara com uma mensagem de erro (claro: sempre no pior momento possível). O primeiro pau do seu software após ter sido homologado destrói 70,837373% da confiança inicial.

Caso o problema não seja resolvido efetivamente e rápido, o usuário se sentirá mais confortável pedindo a você utilize o software em seu lugar (e neste caso, é inclusive sua obrigação).

Pior: imagine que os resultados obtidos estejam errados. Neste caso, além  de gerar os resultados para seu cliente, terá também de comprovar a validade dos mesmos! E acredite: não será uma única vez.

Foi criado um sistema ou uma gambiarra?

Eis a pergunta desagradável. Normalmente o “sistema” é na realidade aquela “rotina” ou “macro” feita para suprir uma necessidade de momento que se tornou periódica. De fato: seu usuário não é obrigado a saber como executar scripts ou macros do Excel. E a solução é simples: transforme a gambiarra em sistema.

Além do questionamento

Acredito que um fato simples normalmente é ignorado por muitos desenvolvedores interface: quanto mais independente um sistema for do seu criador, maior o grau de satisfação do seu cliente. Sei que parece incrível pra muitos, mas já ouvi diversas vezes de alguns pilantras desenvolvedores que se o cliente não estiver preso, não há como garantir o próprio sustento. Eita falácia! Software bem feito requer menos manutenção, que torna seu cliente mais feliz, que o indicará para outros trabalhos. Simples assim.

O desenvolvedor é uma interface sim: entre a idéia do cliente e a geração de uma solução para a mesma. Uma coisa é criar soluções, outra se tornar um botão.

Dicas de busca na web para desenvolvedores

É inacreditável o que irei contar: mais de 90% das perguntas que recebo de desenvolvedores é fruto dos mesmos não saberem encontrar informações na Internet. Sendo assim, resolvi escrever este pequeno guia que, espero, lhes seja útil no futuro.

Usando o Google de maneira eficiente

De todos os motores de busca, o mais eficiente sem sombra de dúvidas é este bichinho. No entanto, é fato que nem todos sabem usá-lo de maneira realmente produtiva por não conhecerem alguns operadores básicos (dica: os mesmos operadores podem ser usados na maior parte dos demais motores).

Operador + : coloque o caractere ‘+’ na frente dos termos que você deseja que obrigatóriamente estejam presentes em seu resultado, tal como no exemplo abaixo:

+Java +jdbd

Neste exemplo, você irá buscar todos os sites que possuam em seu corpo as palavras “Java” e “jdbc” (o caso do texto é indiferente, sendo assim os textos “JDBC”, “Jdbc”, “JdBc” também aparecerão no seu resultado)

Operador -: é o oposto do operador +. Se aquele obriga a presença de determinada palavra, este obriga a sua ausência. Sendo assim, poderiamos incrementar o exemplo anterior para que ficasse tal como

+Java +jdbc -firebird

Nosso resultado incluiria todas as páginas que contenham as palavras “java” e “jdbc”, e que não possuam a palavra “firebird” em seu corpo.

Áspas duplas: se você quiser que uma sequência completa seja encontrada em seus resultados, utilize áspas duplas. Para exemplificar, vamos incrementar ainda mais o nosso exemplo.

+java +jdbc +"SQL Server"

Tudo que possu ao texto “SQL Server” deverá estar incluido no seu resultado. Repare, se eu simplesmente digitasse

+java +jdbc sql server

as palavras sql e server poderiam estar presentes em nossa página, mas não compondo o termo “SQL Server” que estamos buscando, diminuindo assim a precisão de nossa consulta.

Usando alternância: suponhamos que eu queira todas as páginas que possuam as palavras “jdbc” e “java”, mas relacionadas tanto ao SQL Server quanto ao MySQL. Voltando à nossa consulta, eu poderia fazê-la tal como

+java +jdbc +("SQL Server" | MySQL)

O operador | significa “ou”. Nossa consulta incluiria todos os resultados que obrigatóriamente possuam os termos “SQL Server” ou “MySQL”, além de obrigatóriamente conter os termos “java” e “jdbc”.

E, acreditem, isto é o mínimo que você precisa conhecer do funcionamento do Google para torná-lo uma ferramenta eficiente de fato. Se quiser usar apenas um site, Google com certeza será a sua melhor escolha.




Outras fontes de informação

Óbviamente, o Google não irá conter TUDO o que você precisa. Lembre-se: trata-se de um motor de busca de uso geral. Em nosso caso, profundidade é fundamental. Sendo assim, recomendo os sites abaixo que, apesar de não serem motores de busca própriamente ditos, podem ser usados como tal e, acreditem, com resultado MUITO superior.





Koders.com (inglês): trata-se de um motor de busca que, ao invés de indexar sites, indexa mais de 2 bilhões de linhas de código presentes em projetos open source.

Sendo assim, se você algum dia tiver dúvidas com relação à utilização de algum componente, ou mesmo como se faz alguma coisa, este é O seu site de busca.





StackOverflow.com (inglês): trata-se de um site do tipo perguntas e respostas 100% dedicado a assuntos de programação. Se você possui alguma dúvida, há 99,999999999% de chance de já ter sido feita neste site. Caso contrário, basta que você envie a sua (não precisa sequer se registrar) para receberzilhões de respostas em retorno.





W3C.org (inglês): todos os padrões da web (HTML, CSS, Javascript, etc.) encontram-se explicados em detalhes neste site, que é o da organização responsável por mantê-los.





DZone.com (inglês): o melhor agregador de blogs para desenvolvedores que conheço. Aliás, se existe uma fonte de informações fantástica para desenvolvedores, esta fonte são os blogs. Na minha opinião, todo bom desenvolvedor deveria possuir pelo menos uns 20 blogs listados em seu leitor RSS para se manter atualizado





ACM (Association for Computing Machinery) (inglês): os US$20,00 anuais mais bem pagos que você terá. Por apenas este valor, o estudante tem acesso a centenas de livros na íntegra, e por um adicional de mais US$20,00, a milhares de artigos acadêmicos. Isto sem mencionar acesso à edição digital da “Communications of the ACM”, que na minha opinião, é a melhor revista da nossa área existente atualmente. Se você acha assinar revistas de programação um bom negócio, sinto muito por tirar-lhe esta ilusão. :)




Afunilando o conteúdo – Plataforma Java

Visto que 90% do meu tempo é gasto nesta plataforma, seguem abaixo alguns pontos de partida para a plataforma.





java.sun.com (inglês): se existe um endereço que deve ser memorizado por TODO programador Java é este. Isto porquê a documentação que a Sun oferece sobre a plataforma Java é simplesmente excelente. Toda a API encontra-se disponível para ser consultada de forma muito simples e, um detalhe que muitos se esquecem: o melhor livro sobre Java existente atualmente é gratuito, e encontra-se disponível neste link.

Por mais incrível que possa parecer a muitos, diversas pessoas que conheço e trabalham com Java JAMAIS entraram neste site (!!! (medo)).





GUJ.com.br (português): o melhor fórum sobre Java que conheço. A comundiade é super ativa e, apesar de um ou outro pentelho que de vez em quando aparece no fórum, há a probabilidade de 99% da sua dúvida já ter sido respondida por alguém ou de ser atendida pelos participantes do fórum. Se você fala português e programa em Java (ou Ruby), este é O site que não pode faltar nos seus bookmarks.





GrailsBrasil.com.br (português): atualmente, em número de usuários registrados e posts, é o maior do mundo (claro, a lista de e-mails é BEM maior). E, por possuir uma quantidade imensa de posts, é grande a possibilidade de sua dúvida ser sanada rapidamente (se não for, há 80% de chance de ser respondida por mim :) ).




E o mais importante: sem inglês, você não anda

O leitor atento terá percebido que a esmagadora maioria das minhas recomendações de sites é em inglês (aliás, os resultados do Google em inglês também são superiores). Isto porque infelizmente as melhores fontes de informação ainda estão neste idioma. Sendo assim, mais uma vez volto a este ponto: se você quer se virar sozinho em nossa profissão, sem inglês difícilmente sairá do lugar.

Palestra interessante: como iniciar sua carreira de consultor

Escutei uma palestra muito interessante de John Carter, que é um consultor da área de TI de bastante sucesso nos EUA (não o conhecia até ouvir esta palestra) no site IT Conversations. O título da palestra é “Fire Your Boss and Start Consulting”, e pode ser acessada em http://itc.conversationsnetwork.org/shows/detail4179.html

(aliás, recomendo o site IT Conversations (http://www.itconversations.com), que possui algumas palestras e conversas muito legais. Costumo acessar este site para acompanhar as do StackOverflow, que sempre são muito divertidas)

Recomendo esta palestra porque, basicamente, contém diversos conselhos interessantes para aqueles que, assim como eu, trabalham na área de TI como pessoa jurídica. Segue alguns dos pontos que achei interessantes:

  • Por que as pessoas procuram um consultor
  • Como cobrar (é apresentada uma fórmula muito interessante: pegue quanto você ganha por ano e divida por 1000. este será o valor de sua hora)
  • Os principais problemas enfrentados pelos consultores
  • A questão dos benefícios (no caso dos EUA, porém é possível perceber paralelos com o Brasil)
  • Como angariar clientes
  • A importância dos sistemas de gerenciamento/apropriação de horas
    (este ponto achei interessante, porque sempre tive um certo preconceito contra este tipo de software, porém os argumentos apresentados são bem interessantes)
  • A importância vital das métricas de negócio

Bom, espero que gostem. Assim poderemos discutir mais a respeito depois. Fica a dica.

Get Adobe Flash playerPlugin by wpburn.com wordpress themes