Fork me on GitHub

Viagens, opiniões e afins

by Andre Fonseca


Bilbiotecas, frameworks, etc para MVC no Javascript

Escrevi um tempo atrás um artigo onde falava sobre MVC no javascript. Só para recapitular, MVC é um pattern que visa a separação da lógica de apresentação, controle e modelo de um sistema. Como uso cada vez maior de javascript em nossas páginas (front ends) fica evidente que precisamos buscar melhorar a estrutura de nossos códigos para que fica fácil evoluir, entender e manutenciar.

No artigo passado apresentei o conceito e mostrei, bem superficialmente, o que é e como fazer isso. A idéia é aprofundar mais no assunto e mostrar bibliotecas que vão facilitar nossa missão.

Primeira coisa que gostaria de abordar é Orientação a Objeto. A maioria dos desenvolvedores que conheço – de javascript (alguns só de jquery) – parecem desconhecer que a linguagem tem esse recurso e quão ele é poderoso. Tudo bem que o mecanismo não é dos mais simples de entender e implementar (prototype) mas existe e funciona.

Eu, pessoalmente, gosto muito de colocar a minhas lógicas em classes. Isso me ajuda muito a definir as relações e as interações entre as camadas, atores, modelos, etc.

A primeira dica que fica, para a questão de classes em Javascript, e que existem algumas bibliotecas que facilitam (bastante) a tarefa de criar classes e definir seus métodos. Um catálogo delas é o MicroJS.

Existem outras opções mais extensas ( Prototype, Mootools, etc) mas acredito que elas tenham mais do que precisa.

Um pequena brecha para falar uma coisa: hoje penso que tem gente baixando um monte de JS e só usando 10% que é a parte que realmente precisa. Isso vou deixar para falar em outro post.

Agora imagina que você irá implementar uma interface toda estática, cuja o conteúdo será populado e gerenciado através do Javascript. Se acha que isso é só um exemplo, veja o tempo Real de futebol ou cobertura do Rock in Rio (cobertura de eventos da globo.com). Imagina como seria a complexidade do código para implementar tal cenário.

Você tem diversos elementos e interações na página, ciclos de vida, paginações, animações, requisições, eventos, etc. Se você fizer isso, só com funções, sem separar nada, o código se tornará um inferno – mal escrito, e impossível de dar manutenção.

Se resolver isso com classes, mesmo assim terá um monte de código que com o tempo se tornará inviável. Embora seja um caminho.

Por fim, você pode optar por algum framework que permita separar tudo e promova suas interações de forma simples. Um bom exemplo disso é a BackBone.js . Ele permite que você separe, já disse isso, muito bem as responsabilidades e torna fácil as interações.

Num próximo artigo vamos entrar em mais detalhe sobre o backbone.

Referências:

[1] http://pt.wikipedia.org/wiki/MVC – Model-view-controller (MVC)
[2] http://microjs.com/ – Catálogo de MicroJS.
[3] http://mootools.net/ – Página do Mootools
[4] http://www.prototypejs.org/ – Biblioteca Prototype
[5] http://www.slideshare.net/leobalter/javascript-sexy-com-jquery-underscore-e-backbone – Apresentação do BackBone.js
[6] http://documentcloud.github.com/backbone/ – Pagina do BackBone.js

Published by Andre, on outubro 27th, 2011 at 9:10 am. Filled under: tutoriais Tags: , , , No Comments

Python Decorators

A um bom tempo atrás (dezembro de 2009) escrevi um artigo sobre “decorators” em Python. O texto foi inspirado num post no blog do pessoal da Artima( mais precisamente do Bruce Eckel) que falava sobre o assunto.

De lá para cá, apareceram mais artigos e o uso de decorators ganhou bastante força em bibliotecas, frameworks, etc. Diante disso, e de diversos pedidos que recebo, resolvi re-visitar o assunto.

No wiki do Python, a definição de decorator, é de uma forma que temos para alterar um comportamento de um função ou métodos dentro de um código. Seria como se pudéssemos adicionar ou até alterar a lógica sem sermos muitos intrusivos.

Um bom exemplo seria o decorator classmethod. Veja abaixo:

class OlaMundo(object):

    def metodo1(self):
        print "Ola Mundo"

Na classe acima, para usarmos o método “metodo1″, precisamos de uma instância de OlaMundo.

olaMundo = OlaMundo()
olaMundo.metodo1()
OlaMundo.metodo1(olaMundo)

Para transformar o metodo1 ou escrever um metodo2 que pertença a classe e não a uma instância, você tem que fazer:

class OlaMundo(object):

    def metodo1(self):
        print "Ola Mundo"

metodo1 = classmethod(metodo1)

Já o decorator, como uma macro em C, tornar o código mais legível e faz essa “mágica” para a gente:

class OlaMundo(object):
    @classmethod
    def metodo1(self):
        print "Ola Mundo"

O que são os Decorators e como funciona:

Os decorators do Python são como macros ( já disse isso) que quanto o interpretador os encontra os substitui por um estrutura que foi definida. No caso do classmethod ele “substitui” pela a chamada original.

Claro que a definição acima é simplista, mas ajuda a entender.

Nos aprofundando mais, ele é semelhante ao with do Python. Ele é uma classe que no seu init recebe o objeto a qual foi associado e um método call (ele é um Callable). Esse método call é chamado e ai você pode fazer algo.

class MeuDecorador(object):
   
    def __init__(self, function):
        self.f = function
   
    def __call__(self):
        print "Ola Mundo"
@MeuDecorador
def funcao():
    print "algo assim"

funcao()

O código acima mostra bem (execute-o) como funciona um decorator. No meu caso, eu simplesmente coloquei um print. Mas no método eu posso abrir um conexão, colocar um log, medir tempo, colocar numa, fila, emitir um sinal, adicionar o método como callback numa evento, etc.

Para que servem e por que usar:

Decorators não trazem nenhum grande novidade a linguagem (está desde a versão 2.2 se não me engano), mas alteram e melhoram a sintaxe de nossos códigos facilitando a compreensão do que está acontecendo ali.

Referência.
[1] http://wiki.python.org/moin/PythonDecorators
[2] http://www.tocadoelfo.com.br/2009/10/python-decorators-uma-introducao.html
[3] http://devlog.waltercruz.com/python_decorators
[4] http://www.ibm.com/developerworks/linux/library/l-cpdecor/index.html
[5] http://wiki.python.org/moin/PythonDecoratorLibrary

Published by Andre, on outubro 25th, 2011 at 8:38 am. Filled under: atualidades,django,python Tags: , , , No Comments

Usando growl com python e ferramenta de autotest

A um certo tempo atrás trabalhava com Ruby, mais precisamente, desenvolvia utilizando o framework Rails. Dentro desse eco-sistema, existia uma “ferramenta” que sou apaixonado: Autotest (zentest).

Essa ferramenta fica monitorando seus arquivos ruby e caso faça qualquer alteração ele executa os testes (spec) do projeto. Isso é realmente uma “mão na roda” pois, para quem curte TDD, você fica o tempo todo monitorando as alterações no seu código e vai evoluindo bem.

Atualmente mudei de time e passei a trabalhar em projetos com django/python. Logo, comecei a procurar dentro desse novo ambiente, uma ferramenta similar que me permitisse fazer a mesma coisa. Vi que o pessoal do Dojo usa uma ferramente desenvolvido pelo Flávio Amieiro. O tempo foi passando e não encontrei nenhuma que me agradasse ao ponto do autotest (facilidade de uso e instalação).

Foi quando encontrei o Peon, desenvolvido pelo Bernardo Heynemann. O Peon é uma ferramenta que é fácil de instalar (pip install ou baixa e executa make install) e fácil de usar basta:

peon make test -d tests

O comando acima é para quando alguém alterar algum arquivo .py no diretório tests ele irá executar o comando make test. Se você apenas chamar o peon, ele irá executar o nosetests para toda mudança em qualquer arquivo python do projeto.

Além disso, ele tem uma integração com a notificação do linux, permitindo em caso de falhar algum teste – por exemplo, ele te avisar. Entretanto, como eu uso o Mac OS, queria poder ter esse mesmos avisos com o Growl.

Pesquisando encontrei uma forma de fazer isso.

Existe uma biblioteca python (py-Growl) que faz essa integração ( semelhante ao pynotify da libnotify do linux). Abaixo um código mostrando como fazer. A explicação é bem simples:

try:
    import Growl
except ImportError:
     return

path_image = abspath(join(dirname(__file__), image))
icon = {'applicationIcon': Growl.Image.imageFromPath(path_image)}

growl = Growl.GrowlNotifier(app_name, [app_name], **icon)
growl.register()
growl.notify(app_name, title, message)

Primeiro você cria um notifier, informando o nome da app (ela será usada para identificar quem está mandando algo para o Growl. Isso é importante), lista de tipos de mensagem que serão enviadas e um dicionário com ícones.

Depois você registra seu notifier e usa o método notify, passando o nome da app que você informou na criação do objeto, um título (um dos tipos que você informou) e a mensagem. E pronto!

Esse código já está no fork que eu fiz do Peon e vou fazer um pull request em breve. Fica a dica de usar o Peon e o Growl. Fica muito maneiro.

Published by Andre, on outubro 20th, 2011 at 1:43 pm. Filled under: atualidades,python Tags: , , , , No Comments

MVC no javascript

No artigo anterior que escrevi sobre Jasmine, recebi um comentário de um amigo no qual ele me perguntava como fazer para testar códigos Javascript que interagem com o DOM ou que tenham uma certa dependência dele.

O primeiro impulso foi de responder para usar um recurso de Fixtures ( ou similiar), onde ele pode “criar” elementos no DOM durante um cenário de teste e depois removê-los para não atrapalhar os demais. Embora isso resolva o problema dele – de testar funções que precisem de elementos HTML, a pergunta dele suscita uma discussão bem mais ampla e interessante.

Hoje é um fato que nossos front-end ( client side ou interface web ou como queira chamar) são cada vez mais ricos … Tem muito ( mas muito mesmo) código Javascript para criar uma experiência para o usuário boa. Se acha que estou exagerando, abrar seus próprios arquivos ou então converse com um desenvolver front-end mais experiente.

Com uso maior do javascript, o cuidado com seu uso também tem que ser maior. Não é mais aquela função de duas linhas que abre um alert ou aquelas validações simples do seu form. Acredito que em muitas páginas a quantidade de linhas de Javascript é maior que a de html e css. Tudo depende da riqueza da experiência ( veja que não estou considerando CSS3 que “substitui” bastante algumas coisas).

Mas chega de enrolação e vamos ao que interessa: como a gente organiza melhor o nosso código.
Primeira dica é separá-lo em um arquivo. Nada de script na página, por favor. Deixe para fazer isso em última instância. Acredite, sempre existe um jeito de desacoplar.

Caso você já tenha programado alguma coisa no SERVER-SIDE(adoro esse nome, parece que é outra dimensão), sabe que existem diversos padrões de designs( boas práticas). Um deles, e mais famoso, é o MVC – model view controller. Esse pattern ajuda a gente manter bem separado a lógicas de apresentação da lógica de negócio. Assim ao mexer num, não necessariamente precisará mexer noutro.

Seguindo essa filosofia, procuro desenvolver minhas lógicas de forma que eu separe bem oque é apresentação/animação da lógica de “negócio” da minha página. Por exemplo, imaginemos que agora temos que validar alguns dados e mostrar um aviso com os erros. O que faria seria quebrar isso em diversas funções. Uma para cada camada, no mínimo:

function validaCampo(dados){
...
}

function avisaErro(mensagem){
...
}

Erros = {
  "nome_obrigatorio": "Campo nome deve ser obrigatorio"
}

Sei que o exemplo acima pode ser muito simples. Mas ele facilita testar e ainda por cima facilita alterar qualquer coisa na lógica de cada parte sem ter que mexer em um monte de lugar ou ter um método de 40 linhas para fazer uma validação.

Outro exemplo, mais próximo do real, imagina que recebe dados de um form, posta-os via ajax, atualiza uma listagem abaixo e mostra mensagem de sucesso ou erro:

function Requisicao(){
}

Requisicao.prototype.envia = function(url,dados){ //faz algo aqui};

function ItemLista(){}

ItemLista.prototype.renderizaHtml = function(){ //aqui voce pode colocar a logica e escrever o item no html};

function submit(){
  var form = document.getElementByTag("form");
  ...
  var requisicao = new Requisicao();
  var item;
  try {
    requisicao.envia(form.url);
    item  = new Item(requisicao);
  catch {
    avisaErro("Ocorreu um envio no envia de dados");
  }

  item.renderizaHtml();
}

O exemplo acima é apenas conceitual e está faltando coisa para caramba. Mostra bem, como separar bem as coisas e garantir uma boa legibilidade. Para testar isso você pode fazer sem precisar de acessar o DOM, fazendo mock das chamadas onde isso ocorre.

Bom num próximo artigo avançamos mais no assunto e mostro algumas bibliotecas e frameworks para ajudar nesse sentido.

Published by Andre, on outubro 18th, 2011 at 5:11 pm. Filled under: agil,TDD Tags: , , , 1 Comment