Archive for the ‘WebMediaAPI’ Category

Refatorando para Fluent Interface

Friday, September 21st, 2007

Ultimamente tenho passado boa parte do meu tempo trabalhando na WebMediaAPI. Para quem não conhece, a WebMediaAPI é uma… API que tem como objetivo padronizar, centralizar e facilitar o acesso à mídias e seu consumo na Globo.com.

Por exemplo, se você quer colocar vídeos no seu site, ao invés de dar vários SELECTs em tabelas que você não conhece e não entende, a idéia é que você possa usar um JAR na sua aplicação que encapsula várias funcionalidades oferecidas pela infraestrutura de WebMedia, simplificando o seu trabalho (pois não terá que descobrir como inventar a roda) e o nosso (centralizando e organizando o consumo de mídias).

No início do projeto um dos maiores desafios foi estabelecer como seria a fachada da WebMediaAPI. Nós tentamos alguns formatos e como precisávamos lançar logo a primeira versão acabamos optando por uma interface tradicional e simplificada. Para dar uma idéia melhor, vamos analisar o código para selecionar os últimos vídeos publicados de um programa:

int quantidade = 5;
long programaId = 456;
Set midias = new HashSet();

WebMediaServices webMediaServices = WebMediaFactory.getServices();
List idsMidias = webMediaServices
	.getIdsUltimasMidiasPublicadasPorPrograma(quantidade, programaId);

for (Iterator iter = idsMidias.iterator(); iter.hasNext();) {
   Long midiaId = (Long) iter.next();
   Midia midia = webMediaServices.getMidia(midiaId.longValue());
   midias.add(midia);
}

Não é muito difícil entender o funcionamento deste código. Só que ele poderia ser muito melhor… Esta interface pode até funcionar mas não é nem um pouco intuitiva. A classe WebMediaServices como pode-se imaginar ficou com dezenas de métodos e virou basicamente um grande saco de funcionalidades. Qualquer método simplesmente ficava nesta classe, o que não é nem um pouco elegante.

Depois de algum tempo tive a idéia de refatorar a API para uma Fluent Interface. A idéia é tentar fazer alguma coisa que se aproxime de uma DSL interna, que não é nada mais do que uma API com nomes interessantes. Ao invés de um saco de métodos a WebMediaAPI agora é acessada através de uma interface semânticamente organizada e seu design é pensado para ser legível e fluente.

Veja como ficou o mesmo serviço para selecionar os últimos vídeos publicados do programa “Altas Horas”:

Long altasHoras = new Long(456);
Set videos = WebMediaAPI.videos().recentes().doPrograma(altasHoras);

Bem mais elegante!

O lado negativo é que quanto mais fácil a API torna-se para o cliente, mais difícil torna-se sua implementação. Construir uma fluent interface muitas vezes me fez perder algumas horas pensando como certas coisas seriam feitas, mas eu gostei do resultado final e acho que para esse tipo de aplicação (WebMediaAPI) valeu a pena.

Para mostrar a diversidade e simplicidade da nova API, veja mais alguns exemplos (repare que eu não tenho que dizer o que eles fazem para você entendê-los):

// 1
Set programas = WebMediaAPI.programas().comTitulo("Fantastico");

// 2
Long redeGlobo = new Long(123);
Set videos = WebMediaAPI.videos().favoritos().doCanal(redeGlobo);

// 3
Long destaquePrincipalGloboVideos = new Long(123);
Integer quantidadeMaxima = new Integer(10);
Set videos = WebMediaAPI.videos().relacionados().aoCanal()
	.doVideo(destaquePrincipalGloboVideos, quantidadeMaxima);

Ainda temos um longo caminho pela frente e muita coisa ainda será melhorada. Já tenho várias idéias novas que na medida do possível serão incorporadas às próximas versões e compartilhadas aqui no blog.