Lei de Demeter e Ruby

December 8, 2009

Na semana passada tivemos uma discussão bem interessante na Globo.com sobre Lei de Demeter e ruby. Basicamente a questão era: faz sentido se aplicar a Lei de Demeter quando se está usando uma linguagem dinâmica como ruby?

(Para entender o que é a Lei de Demeter, vale a leitura do artigo na Wikipedia).

Ao seguir a lei de Demeter o código escrito tende a ter um acoplamento mais baixo e, portanto, é mais fácil de manter e evoluir. Por outro lado, quando a lei é violada, o acoplamento aumenta. Isso independe se a linguagem utilizada é dinâmica ou não. Ao enviar uma mensagem para um colaborador do colaborador você está aumentando o acomplamento.

Na minha opinião, a questão correta para se discutir é somente: faz sentido aplicar a Lei de Demeter? E, nesse caso, a resposta é a já manjada “depende”.

Assim, sem nenhum contexto, aplicar Demeter faz sentido. Acoplamento baixo é algo desejável. Mas, dependendo do caso, o custo de aplicar a lei pode não compensar. Por exemplo, se o modelo de domínio é muito simples, com pouquíssimas regras de negócio, podemos ser mais pragmáticos, não aplicando a lei, sem que isso tenha maiores consequências.

Como quase tudo que fazemos no nosso dia a dia, trata-se de uma questão de entender o conceito e pesar seus prós e contras dentro de um contexto para então decidir o que fazer.


Mockando funções do PHP

July 2, 2008

O phpunit é um framework para testes unitários em PHP. Esse framework inclui funcionalidades para utilização de mocks. No entanto, temos uma limitação pois não é possível mockar funções do PHP. Nesse post vou mostrar um possível workaround para esta situação.

Vamos supor o código abaixo:

public function get($params) {

    // A partir dos $params passados, montamos uma $url

    return file_get_contents($url);
}

O código acima recebe um array de parâmetros. A partir dele, monta a url de um webservice REST. Por fim, faz um HTTP GET nessa url e retorna o xml recebido. A responsabilidade deste método é montar a url corretamente a partir dos parâmetros recebidos. Este é o comportamento que deve ser testado. O GET é feito pela função file_get_contents.

Idealmente queremos mockar a função file_get_contents. Mocks são usados com diversas finalidades. Neste exemplo, as duas principais motivações são: isolar o código de forma a só testar uma pequena unidade (montagem da url corretamente); e não fazer chamadas a um webservice real (por exemplo para não sobrecarregar um ambiente de produção ou porque o webservice não existe no ambiente de desenvolvimento.).

Já que não é possível mockar funções do PHP, como podemos mockar file_get_contents? Uma possível solução é criarmos uma classe cuja única responsabilidade é chamar esta função:

class FileGetContents {

    function file_get_contents($url) {
    	return file_get_contents($url);
    }

}

O código que queremos testar fica como abaixo. Note que uma instância de FileGetContents é injetada via construtor:

function ClienteHttp($fileGetContents) {
    $this->fileGetContents = $fileGetContents;
}

public function get($params) {
    // A partir dos $params passados, montamos uma $url

    return $this->fileGetContents->file_get_contents($url);
}

E podemos mockar a classe FileGetContents no nosso teste:

/**
 * @test
 */
public function deveria_chamar_webservice_com_url_correta() {
    $urlEsperada = "http://url.esperada";
    $fileGetContents = $this->getMock('FileGetContentsMock',array('file_get_contents'));
    $fileGetContents->expects($this->once())
    ->method('file_get_contents')->with($this->equalTo($urlEsperada))

    $clienteHttp = new ClienteHttp($fileGetContents);
    $parametros; // array de parâmetros que devem resultar na $urlEsperada
    $clienteHttp->get($parametros);
}

Alguns podem argumentar – corretamente – que a classe FileGetContents não é testada. Mas se levarmos em conta que ela simplesmente delega para uma outra função, a desvantagem não é tão significativa assim. Vale enfatizar a importância de que essa classe não tenha nenhum outro comportamento. Caso contrário, a falta de testes já não seria mais aceitável.


Falando em Java 2008

May 20, 2008

No último domingo estive no Falando em Java 2008. Foi um evento excelente, muito bem organizado pelo pessoal da Caelum. Na minha opinião os destaques foram:

  • A apresentação sobre Domain-Driven Design (DDD) do Sérgio Lopes. No dia anterior eu tinha participado de um workshop sobre DDD bastante interessante. Mas essa apresentação foi simplesmente show. No pouco tempo disponível – apenas 40 minutos – o Sérgio conseguiu passar o que é a essência de DDD: foco no domínio para resolver o problema; resgate da Orientação a Objetos; utilização da Linguagem Ubíqua, onde os mesmos termos utilizados na conversa com o cliente apareciam no modelo expresso em código. Fez isso usando um exemplo prático, onde a partir de uma conversa com o cliente implementava o sistema que este queria. Excelente!
  • A palestra do Fabio Kung sobre JRuby on Rails. O Kung deu uma aula sobre Ruby, JRuby e Rails. O mais interessante foi o final, onde ele mostrou que, apesar de JRuby on Rails (assim como Ruby MRI on Rails) ser lento e ter seus problemas para deploy em produção, a versão 3 do GUJ (feita em JRuby on Rails) consegue atender diversas vezes mais requisições por segundo do que a versão atual, em java.
  • A presença do Emmanuel Bernard, líder de diversos projetos do Hibernate. O Emmanuel fez duas apresentações. A primeira foi sobre a versão 2.0 do Java Persistence API (JPA). Basicamente eles estão incluindo nesta nova versão diversas funcionalidades que já existem no Hibernate e em outras ferramentas de ORM. A segunda foi sobre o Hibernate Search, uma ferramenta que utiliza o Apache Lucene e possibilita full text search de modelos de domínio persistentes. Muito interessante!

Workshop de Modelagem Ágil e DDD

May 20, 2008

Nos dias 16 e 17/05 estive em São Paulo para um workshop de Modelagem Ágil e DDD, organizado pela Fratech.

A parte de Modelagem Ágil começou com uma explicação mais teórica: modelos ágeis servem para facilitar a comunicação e não substituir a comunicação face a face; modelos devem ser criados e mantidos somente quando trouxerem valor real para o cliente; modelo não é a mesma coisa que documentação. Depois foram apresentados os conceitos de UML em Cores e Mind Map Modeling (M3). Minha impressão é que esses conceitos vão contra o que a modelagem ágil sugere. Estão mais para documentação do que modelagem. Não acredito que eles favorecem a utilização de abordagens ágeis na modelagem. O único conceito apresentado que, para mim, tem a ver com modelagem ágil é o AgileDraw, que nada mais é do que uma formalização dos rabiscos e rascunhos que fazemos nos quadros brancos, como bem disse o Bruno Carvalho.

Já a apresentação sobre Domain-Driven Design (DDD) foi bem mais interessante. O nível técnico em geral foi bem elevado assim como o nível das discussões. Alguns participantes já tinham um bom conhecimento sobre o assunto e a troca de experiências foi bastante produtiva.

Além disso, tive a oportunidade de conhecer diversas pessoas interessantes. Pena não termos conseguido marcar um chope. Na próxima não pode faltar!


“Modelagem Ágil e DDD” e “Falando em Java 2008”

May 12, 2008

Nesse próximo final de semana estarei em São Paulo para 2 eventos, junto com Vitor Pellegrino e Bruno Carvalho. O primeiro é um workshop de Modelagem Ágil e Domain-Driven Design que vai acontecer na sexta e sábado (dias 16 e 17). O segundo é o Falando em Java 2008 da Caelum, que acontece no domingo (dia 18). Neste evento, vamos estar acompanhados também do Guilherme Chapiewski.

Depois vou postar aqui as minhas impressões desses 2 eventos que prometem!


POJOs

March 4, 2008

Ultimamente tenho notado em listas de discussão, blogs, etc., pequenas confusões em relação ao termo POJO.

Algumas pessoas acham que POJO é sinônimo de JavaBean. Não é. JavaBean é uma especificação de um modelo de componentes. Os beans são componentes de software reutilizáveis que podem ser manipulados por ferramentas visuais para a criação de componentes compostos, applets, aplicações, etc.

Como um construtor público sem parâmetros e gets/sets públicos para os atributos são requisitos necessários (mas não suficientes) para um objeto atender à especificação JavaBean, alguns acham que POJO é sinônimo de objetos com construtores públicos e gets/sets para os atributos. Não é.

O termo foi criado por Martin Fowler, Rebecca Parsons e Josh MacKenzie e significa Plain Old Java Object ou Simples e Velho Objeto Java. Segundo o próprio Fowler, o termo foi criado ao preparem uma palestra para uma conferência em setembro de 2000. Nessa palestra eles mostravam diversos benefícios de se utilizar objetos comuns, simples, no lugar de algo mais pesado como EJBs, para implementar lógica de negócios. Eles não entendiam porque as pessoas tinham resistência em utilizar tais objetos comuns para lógica de negócios e chegaram a conclusão de que isso acontecia pois estes objetos não tinham uma denominação de efeito, que causa impacto. Então, criaram POJO.

Ou seja, um POJO nada mais é que um objeto simples, que não depende de implementar interfaces ou herdar de classes de algum framework externo. Não é, necessariamente, um JavaBean (mas pode ser). Não é, necessariamente, um objeto que tem getters e setters públicos para todos os seus atributos (mas pode ser).


Qi4j

November 27, 2007

Hoje estava lendo sobre o Qi4j que, como informado na página inicial do mesmo, trata-se de um framework para desenvolvimento de aplicações centrados no domínio, utilizando conceitos evoluídos de AOP, DI e DDD. Trata-se de uma implementação em Java de algo conhecido como Composite Oriented Programming.

O objetivo desse framework parece com o de vários outros: deixar o desenvolvedor se concentrar no modelo de domínio do sistema – que é onde está o valor do software – sem se preocupar com o resto, como detalhes técnicos de infra-estrutura.  Para isso ele utiliza o tal do Composite Oriented Programming, um paradigma radicalmente diferente. Vale a pena dar uma olhada no site para entender melhor do que se trata.

A implementação ainda se encontra num estado instável mas parece bastante promissor. Eu certamente vou acompanhar de perto sua evolução.