Domain Specific Languages em ação
Postado em 21. set, 2007 por Paulo Silveira em Arquitetura
Em diversos momentos sentimos a necessidade de utilizar uma linguagem para atacar um problema mais específico. Utilizar Java ou C# nesse tipo de problema pode gerar uma enorme quantidade desnecessária de código. Veja um exemplo que passamos na Caelum:
Set<Strategy> strategies = new HashSet<Strategy>();
Indicator<Double> close = new ClosePriceIndicator(timeSeries);
for (int i = 1; i <= 50; i++) {
Indicator<Double> tracker = new EMAIndicator(close, i);
Strategy strategy = new
IndicatorCrossedIndicatorStrategy(close, tracker);
strategies.add(strategy);
}
No nosso caso, esse trecho de código deve ser compreensível para analistas de negócio, que não são necessariamente programadores, muito menos possuem conhecimento de Java.
Domain Specific Languages é o nome dado a prática de se criar pequenas linguagens para resolver um problemas bem específicos. Elas existem em dois sabores: as externas, que criam uma linguagem própria, e as internas, que na verdade utilizam um subconjunto de instruções de um linguagem já existente e utilizada no sistema.
Entre alguns clássicos exemplos de DSLs internas temos o uso da Criteria do hibernate, o uso do ruby nos arquivos de build do rake. Entre as DSL externas, temos as macros do excel e o xml do ant.
Utilizando a api de scripting do java 6, passamos a usar ruby (através da JRuby) para escrever essa parte da lógica de negócios, e nosso código em java ficou assim:
(1..50).collect{|x|
Tail::IndicatorCrossedIndicatorStrategy.new(close,
Tail::EMAIndicator.new(close, x))
}
Criando algumas factories, conseguimos chegar a um código muito mais simples:
(1..50).collect{|x|
cross(close, ema(x))
}
Logo, estamos próximos de chegar a algo parecido com uma linguagem natural:
x de 1 a 50
quando cruzar (fechamento, ema(x))
Para tal, uma das possibilidades seria usar um dos compiladores de compiladores existentes para Java, porém isso daria muito trabalho.
O Rodrigo Kumpera sugeriu escrever o próprio parser, como fez o Gilad Bracha no Small Talk. Tanto o Rodrigo quanto o Renato Lucindo citaram o spirit++, que faz isso para C++. Uma pena não existir algo equivalente para o Java.
Phillip Calçado recomendou fazer um teste para saber se devemos ou não melhorar ainda mais essa DSL. O teste consiste em colocar a linguagem natural ao lado da DSL ruby e ver se o especialista consegue fazer a ponte entre uma e outra. Exemplo:
(1..50).collect{|x|
cross(close, ema(x))
}
x de 1 a 50
quando cruzar (fechamento, ema(x))
Se o especialista no domínio não entender a semelhança entre os dois códigos, é necessário aprimorar a DSL em questão.
Paulo Silveira (Google+)
Mais sobre o autor
6 Respostas para “Domain Specific Languages em ação”
Trackbacks/Pingbacks
-
-
fevereiro 13, 2012
[...] nomes significativos para torná-lo mais limpo. Outra opção é buscar por bibliotecas ou criar suas próprias [...]
ASSINE NOSSO RSS
Phillip Calçado "Shoes"
21. set, 2007
Um problema é a barreira idiomática. DSLs em Ruby funcionam muito bem quando são em inglês (domínio e código).
Diego Pires Plentz
21. set, 2007
Ou trocar o analista
Tiago Albineli Motta
25. set, 2007
Concordo com o Phillip, muitas vezes o analista de negócios pode não fazer facilmente essa ponte exatamente por falta de conhecimentos no idioma.
Paulo Silveira
25. set, 2007
Tiago, Phillip, basta abrir a classe Range do ruby e adicionar um método
pegaque delega paracollect! Voces se esquecem que não é java!Max Mustang
28. jan, 2011
3 anos depois e esse post ainda me diverte, com certeza é um dos melhores do Paulo