Posts Tagged ‘DSL’

Livro promissor sobre mock objects

Wednesday, July 16th, 2008

Steve Freeman e Nat Pryce do JMock, um dos meus projetos favoritos, estão escrevendo um livro entitulado “Growing Object-Oriented Software, Guided by Tests”. O assunto é muito bom e conhecendo os caras e os materiais que eles já publicaram (especialmente o artigo que fala sobre a experiência deles evoluindo uma DSL, baseando-se no desenvolvimento do JMock – “Evolving an Embedded Domain-Specific Language in Java”), acho que o livro promete.

O primeiro capítulo já está disponível no blog do JMock e chama-se “What’s the point of Test-Driven Development?”. A leitura é obrigatória e já dá uma pista do que está por vir.

Um exemplo prático de Fluent Interface

Monday, March 3rd, 2008

Há alguns meses escreví um post sobre Fluent Interfaces, mostrando um trabalho que fizemos aqui na empresa para tornar nossa API interna mais fácil de se utilizar. Depois disso, algumas pessoas me pediram códigos e exemplos de uso da WebMediaAPI, mas o código é da empresa e não posso compartilhá-lo.

Fiquei então com a idéia de criar uma demonstração de uso de Fluent Interfaces na cabeça, mas eu queria usar um domínio fácil para que as pessoas pudessem entender melhor. A WebMediaAPI pode ser até legal, mas o fato é que ninguém conhece o modelo de mídias da Globo.com e fica difícil de explicar ou discutir o que está sendo feito.

Há duas semanas, conversando com o Evandro sobre uma apresentação que faremos mês que vem no evento de tecnologia da Globo.com, ele deu uma idéia super simples e bem legal. Todas as pessoas já trabalharam com e-mail, seja enviando mensagens para outras pessoas ou então escrevendo código para enviar e-mails em diversas linguagens. Esse é um domínio extramanete fácil para todo mundo, e também, é pequeno o suficiente para ser implementado rapidamente em um dia.

Então, nasceu a Fluent Mail API. A Fluent Mail API é uma API simples que utiliza a JavaMail API da Sun para enviar e-mails. Meu objetivo não é criar mais uma ferramenta para envio de e-mails, é apenas demonstrar o uso de Fluent Interfaces como wrapper de um framework maior, simplificando seu uso. A idéia é fazer com que enviar um e-mail seja tão fácil quanto isso:

new EmailMessage()
    .from("demo@guilhermechapiewski.com")
    .to("destination@address.com")
    .withSubject("Fluent Mail API")
    .withBody("Demo message")
    .send();

Você pode ver os códigos-fonte e uma descrição mais detalhada no site do “projeto”. Se alguém quiser discutir, opinar, tirar dúvidas ou qualquer outra coisa, é só comentar.

[QCon 2007] Neal Ford: Building DSLs in Static and Dynamic Languages

Tuesday, November 13th, 2007

QCon 2007 - Neal FordNeal Ford da ThoughtWorks fez mais uma apresentação sobre Domain Specific Languages, desta vez mostrando alguns aspectos do desenvolvimento de DSLs em linguagens com tipagem estática e dinâmica.

Ele evoluiu sobre a idéia de que uma DSL é um estilo declarativo de programação ao invés de imperativo. Um exemplo é a linguagem SQL. Em SQL você não diz como você quer alocar memória ou como organizar ponteiros e listas, você só diz o que quer e o banco de dados “descobre” como atender seu pedido.

DSLs podem ser usadas como uma camada de abstração sobre APIs, assim como Java poderia ser considerado uma camada de abstração sobre C, por exemplo. Veja os dois códigos a seguir que exemplificam esta diferença. O primeiro código é um código típico de API e o segundo código seria uma DSL wrapper para esta API:

// API
Car car = new CarImpl();
MarketingDescription desc = new MarketingDescriptionImpl();
desc.setType("Box");
desc.setSubType("Insulated");
desc.setAttribute("length", "50.5");
desc.setAttribute("ladder", "yes");
desc.setAttribute("lining type", "cork");
car.setDescription(desc);
 
// Fluent Interface
Car car = new Car.describedAs()
		.box()
		.length(12)
		.includes(Equipment.LADDER)
		.has(Lining.CORK);

A partir daí o Neal mostrou algumas técnicas para construir DSLs como aninhamento e encadeamento de métodos, finalizar/salvar “transações” e outras coisas mais. Também falou sobre as vantagens de se utilizar linguagens dinâmicas como Groovy e Ruby para tirar proveitos de features como closures, classes abertas, tipagem dinâmica e sintaxe menos rigorosa que a do Java.

Mais uma vez a questao dos testes foi enfatizada. Muito provavelmente as DSLs vão evoluir ao longo da vida do sistema e é necessário ter uma suite de testes verificando cada pequena parte e garantindo que os incrementos nela não trarão efeitos colaterais. Trabalhar com DSLs sem testes é um pesadelo!

Algumas coisas que você precisa ter em mente ao criar DSLs:

  • Pense sempre na DSL perfeita. Mesmo que você não consiga chegar na perfeição, pensar no melhor caso possível vai te ajudar a te guiar pelo melhor caminho. Neste caso utilizar uma técnica como TDD pode ajudar bastante pois você irá determinar onde quer chegar antes mesmo de começar a codificar.
  • Utilize um contexto pequeno. Não tente criar uma DSL super genérica, escreva um domínio especializado.

Download

[QCon 2007] Martin Fowler e Neal Ford: Domain Specific Languages

Wednesday, November 7th, 2007

Segundo dia de QCon e hoje foi a vez de Martin Fowler e Neal Ford falarem sobre Domain Specific Languages.

QCon 2007 - Martin Fowler - Domain Specific LanguagesCom dois profissionais desse nível dá pra imaginar como o tutorial foi espetacular! O Fowler é sem sombra de dúvidas o melhor palestrante que já tive a oportunidade de ver. O ritmo que ele impõe é sensacional e a paixão com que ele fala do assunto é contagiante!

Para melhorar ainda mais o dia começou com uma ótima notícia: o Fowler está escrevendo neste momento um novo livro sobre DSLs. O livro já está no forno há um ano e já tem muita coisa escrita. Toda a apresentação de hoje foi baseada no seu novo livro e inclusive tivemos acesso a todo o material da sua pesquisa e o primeiro draft do livro! Está sensacional! O Neal também está escrevendo um livro sobre Ruby e DSLs, porém pelo que eu entendí está num estágio bem menos avançado.

Como o material da apresentação fará parte desse novo livro a distribuição foi proibida. Já que não dá para colocar o material aqui vou falar resumidamente sobre os assuntos abordados durante o dia, que foi dividido em três grandes partes.

Na primeira parte os dois apresentaram um introdução sobre o que são DSLs e como elas podem ser úteis. Eles criaram um framework imaginário (uma máquina de estados) e começaram a mostrar todos os problemas de quando este framework é desenvolvido como uma API. Em seguida eles criaram uma “casca” em torno dessa API (uma Fluent Interface) para facilitar o uso da mesma.

A partir daí eles definiram os conceitos de DSL interna e externa. DSLs internas são como as Fluent Interfaces, que são escritas na linguagem do sistema (Java, por exemplo). DSLs externas são escritas em qualquer outra linguagem separada da linguagem do sistema e precisam de um compilador ou interpretador para serem executadas.

Os benefícios mais notáveis de construir DSLs são a melhoria na produtividade do desenvolvimento (porque o código da lógica de negócio é mais limpo e mais fácil de ser evoluído) e a melhoria na comunicação com os especialistas do domínio (porque as regras de negócio são escritas numa linguagem conhecida pelo especialista, facilitando o entendimento do código).

QCon 2007 - Neal Ford - Domain Specific LanguagesNo entanto também existem uma série de problemas. É necessário ter muito cuidado para criar um design bom que possa ser evoluído ao longo do tempo. DSLs algumas vezes são extremamente complicadas de serem implementadas mas o impacto é muito positivo. Um exemplo real pode ser visto em um post que fiz há algumas semanas sobre uma Fluent Interface que implementei em um projeto, que trouxe vários benefícios interessantes.

Uma das formas mais comuns de se criar DSLs é o padrão que eles chamaram de “Framework Out-Language In”, onde você começa com a construção de um framework e em seguida define uma DSL em volta dele (como um Façade). Utilizar técnicas de Domain-Driven Design pode ajudar bastante pois evoluindo a Ubiquitous Language você enriquece a comunicação/vocabulário do sistema, que fatalmente irá colaborar para a criação de DSLs mais ricas e que refletem melhor ainda o domínio.

Não é nem preciso dizer que eles bateram muito forte na questão dos testes. Como a programação de DSLs é complexa, é essencial testar muito bem cada pequena parte e variação possível! Além disso técnicas de Test-Driven Development certamente ajudarão a criar DSLs mais fáceis de serem usadas (porque se não for fácil de usar você fez alguma coisa errada).

Na segunda parte da apresentação o Neal Ford apresentou um tutorial prático de como criar DSLs internas em Java, Groovy e Ruby.

Essa apresentação foi bem mão-na-massa e ensinou várias técnicas para criação de DSLs internas. Ele mostrou vários exemplos utilizando encadeamento e aninhamento de métodos fazendo wrappers em coisas conhecidas como Log4J e java.util.Calendar.

Na terceira e última parte o Fowler apresentou um tutorial sobre como projetar e quais ferramentas podem ser utilizadas para a criação de DSLs externas. Essa apresentação foi bem mais teórica que a do Neal.

Ele mostrou como fazer para criar um parser de sintaxe, que consiste em um “lexer” (um tokenizador de texto), um parser (analisador sintático que organiza os tokens em uma árvore), um analisador semântico (que checa as regras de construção das frases) e a produção de alguma saída (que significa produzir qualquer coisa útil, como popular certos objetos e fazer certas operações).

Qcon 2007 - DSLDomain Specific Languages é uma técnica muito antiga. Muito antes do próprio Fowler começar a escrever e estudar sobre o assunto várias DSLs já existiam por aí (o melhor e mais clássico exemplo é a linguagem SQL utilizada em bancos de dados).

A opinião dos dois é que DSLs realmente prometem trazer várias melhorias no desenvolvimento de software, especiamente no que diz respeito a programação das regras de negócio e interação com os especialistas de domínio. No entanto eles acham que não existirá um dia em que os programadores serão desnecessários e que tudo será feito a base de DSLs, tampouco que este seja um assunto que terá um boom enorme e que mudará a vida de todo mundo. Eles acham que trata-se simplesmente de mais uma técnica útil para desenvolver software de qualidade.

[QCon 2007] Eric Evans: Domanin-Driven Design

Tuesday, November 6th, 2007

Qcon 2007 - Eric Evans - Domain-Driven DesignA apresentação do Eric Evans hoje sobre Domain-Driven Design foi excelente! A abertura do evento não poderia ter sido melhor!

Grande parte do que ele apresentou faz parte do seu livro sobre DDD, incluindo alguns dos exemplos usados no tutorial. Mas isso não fez com que as coisas ficassem menos interessantes. Muito pelo contrário, as discussões foram excelentes.

Falamos inicialmente sobre as características de um bom design de domínio. Na opinião do Eric um bom design é aquele que você consegue explicar para uma pessoa qualquer e ela entende mesmo não sendo especialista no negócio/domínio. Sobre codificação, o Eric falou que se interessa bastante pela clareza trazida por Fluent Interfaces, e DSLs internas e tenta usá-las sempre que possível pois aumenta muito a legibilidade do código. Além disso ele acredita que o uso de Behaviour-Driven Development é interessante no processo exploratório de um domínio e pode te ajudar a identificar e corrigir problemas de design.

Uma das frases que o Eric falou me lembrou a discussão que rolou na semana passada no GUJ sobre testes, TDD e etc: “Estamos no ano do Test-Driven Development e criar designs testáveis é essencial!”. Não quero acender novamente a discussão mas não posso deixar de dar a minha opinião nessa história. Realmente é inaceitável um software nos dias de hoje não ter uma suite de testes decente, não só pelos testes em sí mas por toda a influência positiva que isso traz no design do código, pela segurança que te dá para incluir novas funcionalidades e modificar existentes, segurança para corrigir bugs e tudo mais. Para mim é simplesmente impossível programar sem testes!

Guilherme Chapiewski e Eric EvansInfelizmente não consegui todo o material do curso porque o Eric utiliza esses materiais nos seus treinamentos e por isso não os disponibiliza publicamente. Mas eu consegui o Domain-Driven Design Pattern Summaries, que é um resumo de 39 páginas do livro dele com algumas coisas a mais. Achei bem interessante para se usar como referência. Esse resumo contém informações bem objetivas sobre todos os padrões apresentados no livro de DDD.

Além desse material o InfoQ disponibilizou a palestra Putting The Model To Work que foi uma das que o Eric apresentou para nós. Essa não foi exatamente a apresentação que tivemos mas foi bem parecida.

Para os leitores assíduos de blog, aí vai uma boa notícia: num dos intervalos eu perguntei para o Eric porque que ele não tinha um blog. Ele disse que ultimamente muitas pessoas têm feito essa pergunta e disse que está preparando alguma coisa nesse sentido. Perguntei sobre quando ele planeja lançar isso e ele disse que seria em breve! Com certeza será mais uma ótima fonte para leituras.

E para terminar, a gafe do dia: na hora do intervalo subitamente começamos a ouvir na sala vários barulhos estranhos de mictório e pia de banheiro… O Eric deu bobeira e foi no banheiro com o microfone sem fio ligado! Ao menos constatamos que o microfone era de boa qualidade porque o banheiro era meio longe, haha!

QCon 2007, aí vou eu!

Friday, November 2nd, 2007

Estou arrumando minhas malas e partindo daqui a pouco para a QCon 2007!

No último mês eu tenho me preparado bastante pra esse evento e justamente por isso que não tenho postado com tanta frequência. Não é todo dia que se pode ter aulas de Domain-Drinven Design com o próprio Eric Evans, de XP com o próprio Kent Beck ou de Domain Specific Languages com Martin Fowler e Neal Ford, por isso aproveitei esses dias pra refrescar algumas coisas na cabeça para poder aproveitar tudo o máximo possível!

Nos dois primeiros dias eu pretendo justamente assistir os cursos de DDD do Evans e de DSLs do Fowler. Esses tutoriais duram um dia inteiro e são hands-on, aplicados num laboratório. Acho que vai ser muito legal!

Além deles vários outros apresentadores como Ted Neward, Cedric Beust, Jeff Sutherland, Obie Fernandez, Jay Fields e Rod Johnson farão uma semana inteira de apresentações sobre desenvolvimento ágil, arquitetura de software e tudo mais que alguém poderia querer para ter uma semana mais que divertida.

Vou tentar conseguir o máximo de material possível nas apresentações que eu for e ao longo da semana vou postando por aqui!

Refatorando para Fluent Interface

Tuesday, September 25th, 2007

Ultimamente tenho passado boa parte do meu tempo trabalhando numa aplicação chamada WebMediaAPI. Trata-se de uma… ahm… API de uso interno que tem como objetivo padronizar, centralizar e facilitar o acesso à mídias e seu consumo em sites da Globo.com.

Por exemplo, quando o pessoal do G1 quiser colocar vídeos no seu site, ao invés de dar vários SELECTs em tabelas que eles não entendem e não conhecem, a idéia é que eles possam usar um JAR na aplicação deles que encapsula várias funcionalidades oferecidas pela nossa infraestrutura de WebMedia, simplificando o trabalho deles (pois não terão que descobrir como inventar a roda) e o nosso (centralizando e organizando o consumo de mídias na empresa).

No início do projeto um dos maiores desafios foi estabelecer como seria a fachada desta API. 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 ter uma idéia melhor, veja o código para selecionar os últimos vídeos publicados do programa “Altas Horas”:

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 algo que se assemelha a 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 novo código para selecionar os últimos vídeos publicados do programa “Altas Horas” (exatamente a mesma coisa que o código anterior faz):

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 valeu a pena.

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

// exemplo 1
Set programas = WebMediaAPI.programas().comTitulo("Fantastico");
 
// exemplo 2
Long multishow = new Long(123);
Set videos = WebMediaAPI.videos().favoritos().doCanal(multishow);
 
// exemplo 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, mas já dá para perceber uma difirença significativa entre as duas versões.