Trabalhar com Orienta√ß√£o a Objetos em aplica√ß√Ķes comerciais √© trabalhoso porque envolve necessariamente outros paradigmas (como bancos de dados relacionais), al√©m de requisitos n√£o funcionais da sua arquitetura (como seguran√ßa, concorr√™ncia, etc) impedindo uma modelagem pura. Em aplica√ß√Ķes que realmente existem l√≥gica de neg√≥cios e n√£o apenas um conjunto de cadastros e relat√≥rios, a utiliza√ß√£o de uma abordagem com “Domain Driven Design” se faz necess√°ria para a redu√ß√£o da complexidade no cora√ß√£o do software, ou seja, na camada respons√°vel pelo modelo do neg√≥cio.

A abordagem de Domain Model proposta por Eric Evans, consegue isolar o n√ļcleo do sistema (respons√°vel pela l√≥gica de manipula√ß√£o das informa√ß√Ķes e processos de neg√≥cios) abstraindo das particularidades da arquitetura por meio de suas t√©cnicas modernas e maduras. Mesmo assim o esfor√ßo de isolamento n√£o √© t√£o claro mesmo para coisas triviais como seguran√ßa, onde existe uma linha t√™nue entre o que √© requisito funcional ou n√£o.

Na constru√ß√£o do seu modelo, a profus√£o de abordagens como Fluent Interfaces e DSL ajudam a maximizar o entendimento do neg√≥cio, mas ainda assim restam d√ļvidas de como e onde aplicar adequadamente.

Confus√£o

Tenho visto muitos bons desenvolvedores ca√≠rem na onda do Hype e se tornarem fanboys “*-tards” e sa√≠rem por a√≠ alegando que a linguagem X ou outra coisa qualquer √© evolu√ß√£o do Java/C# ou coisas desse tipo, comparando linguagens de abordagens t√£o distintas entre si e at√© de paradigmas diferentes. Esse pessoal esquece “o porqu√™” de existirem tipos est√°ticos e din√Ęmicos, fortes e fracos. Uma linguagem funcional n√£o √© evolu√ß√£o de uma linguagem orientada a objetos, se bem que o vice-versa √© contradit√≥rio porque alguns autores alegam que o object calculi seria evolu√ß√£o do lambda-calculi. Linguagens de tipos din√Ęmicos n√£o s√£o evolu√ß√£o de tipos est√°ticos, j√° existiam e servem para prop√≥sitos diferentes. Da mesma forma existem JAVAtards que esquecem que existem outras funcionalidades que Java n√£o implementa (lembre-se que voc√™ n√£o cria um MapReduce sem conhecimentos profundos de programa√ß√£o funcional).

O ponto principal √© que os tipos est√°ticos s√£o importantes em linguagens imperativas e s√£o importantes na defini√ß√£o da camada de neg√≥cio, mas linguagens din√Ęmicas tamb√©m o s√£o, pela agilidade nas mudan√ßas e na complexidade da arquitetura. Imagine o custo de um deploy para cada refactoring e mudan√ßa em uma arquitetura JEE e compare com o mesmo n√≠vel de complexidade de mudan√ßa em PHP ou Ruby.

O mais comum ultimamente √© a divis√£o da camada de neg√≥cios em duas zonas distintas: uma est√°tica, implementada com uma linguagem est√°tica e fortemente tipada como Java; e uma din√Ęmica, implementada com o sabor de script que voc√™ goste, como ruby, javascript ou python.

Camada est√°tica

Existem princípios em qualquer negócio que por mais ágil que esse negócio seja e mude constantemente, esses princípios nunca mudam, são aquelas funcionalidades facilmente detectadas na modelagem tradicional, onde se detecta o caminho principal de um ator pelo caso de uso e podemos prever os caminhos alternativos.

Alguns pseudoanalistas imaginam que todas as funcionalidades se revelam na modelagem tradicional e se n√£o cobriu todas as possibilidades √© porque falhou o processo de desenvolvimento. Essas funcionalidades facilmente detect√°veis e control√°veis fazem parte da camada est√°tica do seu modelo, n√£o devem mudar nunca ou muito pouco em rela√ß√£o √† vida √ļtil do software.

Imagine um sistema cont√°bil, os princ√≠pios de cr√©dito e d√©bito, plano de contas, livros cont√°beis, a pr√≥pria opera√ß√£o de contabiliza√ß√£o a partir de documentos entre outros aspectos s√£o os mesmos h√° uns 200 anos e mudaram muito pouco nesse tempo todo. Falo sobretudo da contabilidade fiscal. Uma modelagem desses princ√≠pios vai sofrer pouca altera√ß√£o durante toda a vida √ļtil do software.

Imagine o sistema jurídico, é praticamente o mesmo dos romanos. Imagine um sistema de vendas, desde a troca de sal por um carneiro, surgimento da moeda ao cartão de crédito, os princípios são os mesmos.

Para implementar essa camada, uma linguagem de tipos fortes e estáticos é o mais indicado.

Camada din√Ęmica

Agora imagine toda a contabilidade gerencial que √© realizada com base na contabilidade fiscal. Imagine todas as opera√ß√Ķes poss√≠veis e combina√ß√Ķes imagin√°rias de vendas. Todos os c√°lculos de impostos que os governos mudam todo ano. A an√°lise e modelagem total dos casos de usos √© praticamente imposs√≠vel e se mostrou invi√°vel ao longo do tempo.

Alguém pode sugerir a utilização de métodos ágeis para solucionar esse problema em linguagens estáticas mas não é o bastante. Os métodos ágeis surgiram para prepararem as equipes para as mudanças, suavizar o impacto que refactoring causam no código. Observem que estamos falando apenas de negócio, puro negócio. Os métodos ágeis não dizem como fazer o seu código, eles te auxiliam.

A abordagem de utilizar uma linguagem din√Ęmica para esses requisitos mut√°veis e tardiamente diagnostic√°veis se mostrou eficient√≠ssima. Isolamos parte do Domain Model para ser provido de uma linguagem din√Ęmica (de script de prefer√™ncia), e concentramos na facilidade de montar um idioma comum para a equipe sem o custo de build ou deploy de linguagens est√°ticas.

Segmentação

Dividimos ent√£o essa camada din√Ęmica em duas camadas interiores: uma da pr√≥pria linguagem din√Ęmica que facilita as modifica√ß√Ķes √°geis (aconselhavelmente com Fluent Interfaces); e outra mais rebuscada, criada para a cria√ß√£o de regras (DSL com ou sem Fluent Interfaces) e uma linguagem comum entre a equipe e os operadores do sistema que s√£o geralmente n√£o t√©cnicos mas treinados para isso.

Implementação

Trabalhemos com esse pequeno exemplo, tenho uma operação fecharVenda de uma hipotetica classe Venda que entre suas responsabilidades, existe a geração de comissão do vendedor.

1
2
3
4
5
6
7
public void fecharVenda() {
 ...
	//pre-execução
 	this.vendedor.setComissao(this.valorTotal * (5/100) );
	//pos-execução
...
}

Agora imagine que surgiu uma modificação no sistema, existem dois percentuais diferentes. Isso é moleza, você refatora a operação com a modificação:

1
2
3
4
5
6
7
8
9
10
11
12
13
public void fecharVenda() {
 ...
 
	//pre-execução
	if(this.tipo.equals("VendaTipo1"))
		this.vendedor.setComissao(this.valorTotal * (5/100) );
	}
	if(this.tipo.equals("VendaTipo2"))
		this.vendedor.setComissao(this.valorTotal * (8/100) );
	}
	//pos-execução
...
}

Ah! Mas eu sou esperto, criei uma propriedade l√° que amarro o tipo de documento com o percentual apropriado:

1
2
3
4
5
6
7
8
public void fecharVenda() {
 ...
	//pre-execução
	this.vendedor.setComissao(this.valorTotal 
                   * this.vendedor.getPercentualApropriado() );
	//pos-execução
...
}

Daí chega o seu cliente todo fogoso e diz que a regra mudou, agora não é mais no total da nota e sim nos ítens, cada item pode ter um percentual diferente. O caminho mais usual é você refatorar o item e copiar a propriedade para lá, percorrer todos os produtos no método fecharVenda e calcular a comissão, claro, deixando a abordagem atual comentada caso o cliente deseje voltar como era antes.

Usando uma linguagem de Script

Observe no comentário //pre e //pos execução, que acha de injetar uma chamada a um script no método?

Voc√™ faria essa √ļltima modifica√ß√£o assim em javascript (com Rhino):

Chamada ao Script que ser√° injetado no modelo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
try {
	engine.put("lista", this.itens);
	engine.put("vendedor", this.vendedor);
	engine.put("nf", this);
	engine.put("total", this.total);
	engine.put("totalDescontos", this.totalDescontos);
	String path = NotaFiscal.class.getResource("script.js").getPath();
	engine.eval(new FileReader(path));
	this.total = (Double) engine.get("total");
	this.totalDescontos = (Double) engine.get("totalDescontos");
} catch (ScriptException e) {
	e.printStackTrace();
} catch (FileNotFoundException e) {
	e.printStackTrace();
}

Código no script.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
(function() {
	var _$ = function(els) {
		this.elements = [];
		var iterator = els.iterator();
		while(iterator.hasNext()) {
			this.elements.push(iterator.next());
		}
		return this;
	};
	_$.prototype = {
		each: function(fn) {
			for ( var i = 0, len = this.elements.length; i < len; ++i ) {
				fn.call(this, this.elements[i]);
			};
			return this;
		},
		comissionar:function(vendedor) {
			var comissao = function(e) {
				vendedor.comissao += (e.total * e.percentual);
			}
			this.each(comissao);
		}
	};
	$ = function() {
		return new _$(arguments[0]);
	};
}());
$('lista').comissionar();

Fortemente inspirado no c√≥digo do prototype resolvi o problema temporariamente sem precisar refatorar o c√≥digo da aplica√ß√£o e deixei aberto para quantas modifica√ß√Ķes forem necess√°rias nessa parte que √© vari√°vel.

Categories: DSL, Engenharia de Software, Fluent Interface, Java, Linguagens, Melhores práticas, Orientação a Objetos ~ ~ Trackback


Assine os coment√°rios deste artigo.


16 Responses to “Regras din√Ęmicas no Domain Model com linguagens de script”

  1. 1
    Felipe Ga√ļcho

    humm, o exemplo nao convence muito porque voc√™ pode usar o padr√£o Strategy e conseguir a mesma flexibilidade. De qualquer forma, voc√™ precisa manter o script ou c√≥digo “est√°tico”, e supor que uma coisa eh mais leve ou mais f√°cil que outra n√£o me convence muito :)

    Outra: em web-services, a separação entre processamento e camada de visão fica quase implícita a tecnologia. Mesmo que você não queira deixar suas regras codificadas estaticamente, elas serão transportadas via soap ou rest e o sistema vai ser naturalmente heterogêneo :) então não sei ateh onde a tua injeçao de regras vai sobreviver :)

    Boas id√©ias, bom post, mas assunto pol√™mico… a palestra promete ser muito boa..

  2. 2
    Hildeberto

    Se MapReduce √© um framework, porque voc√™ diz: ” (…) esquecem que existem outras funcionalidades que Java n√£o implementa (lembre-se que voc√™ n√£o cria um MapReduce sem conhecimentos profundos de programa√ß√£o funcional).” MapReduce pode ser implementado perfeitamente em Java sem precisar de nenhuma feature adicional: http://en.wikipedia.org/wiki/Hadoop

  3. 3
    cmilfont

    @Felipe Ga√ļcho

    Usar “Strategy” para todas as as poss√≠veis combina√ß√Ķes de l√≥gicas √© invi√°ve, vai causar um overpattern. Fiz um exemplo apenas para comiss√£o, mas imagine que na venda eu tenho reflexo na contabilidade, tratamento de descontos, impostos e uma massa d informa√ß√Ķes em constante muta√ß√£o.
    A estratégia de usar um script nesse caso agiliza o desenvolvimento por tirar a complexidade do deploy, resolver rapidamente sem mexer na estrutura estática e mesmo assim o código pode passar para a estrutura estática caso seja relevante e detectado que faz parte dela.
    Webservices em um DomainModel? Web Services são consumidos de srviços de ouros sistemas estritamente, porque eu faria webservices no meu domainmodel? Que ganho eu teria nisso?

  4. 4
    cmilfont

    @Hildeberto
    MapReduce n√£o √© apenas um framework, √© baseado em um algoritmo. Algoritmo esse baseado em duas fun√ß√Ķes de alta ordem que j√° existiam a Map e a Reduce (ou Fold) e que s√≥ quem tem conhecimentos em Lisp ou outra linguagem funcional conseguiria criar j√° que exige abstra√ß√£o pelo c√°lculo lambda coisa que um Javer puro n√£o tem.
    Implementar esse tipo de coisa em Java até que não é difícil quando se vai copiar, já que até tail recursion dá para fazer, mas o desempenho não será o mesmo de uma linguagem funcional.

  5. 5
    Felipe Ga√ļcho

    1 – falar em MapReduce nao faz parte da realidade brasileira :)

    2 – supor que o deployment vai ficar mais simples por ter scripts eh supor que voc√™ nao vai precisar testar a parte est√°tica contra as novas regras editadas no script.. Na pr√°tica, alterando qualquer linha do projeto (seja est√°tica ou din√Ęmica) voc√™ precisa executar todos os testes de aceita√ßao novamente, ent√£o adeus simplicidade :) Jah vi muitos palestrantes sugerirem “eu vou abrir um editor de texto, trocar meia duzia de linhas do meu script e tudo estar√° atualizado sem a necessidade de compilar c√≥digo, etc.”.. me parece uma grande fal√°cia quando eu lembro que o codigo vai ter que ser retestado.. ent√£o a unica simplicidade eh usar um editor de texto para editar o script ao inves do eclipse para edtar o codigo Java. Depois de editados, ambos os artefatos passar√£o por uma bateria de testes que nao vao ficar mais simlpes pelo formato dos arquivos :)

    Ainda espero alguém que me convença da menor complexidade dos scripts diante de linguagens OO e fortemente tipadas :) Continuo supondo que exista grandes benefícios no uso do script, mas ateh hoje nao apareceu a prova cabal disso :) eheh a menos, claro, se estamos falando no maldito browser e suas gambiarras javascript.. aih nao tem jeito mesmo.. ahah

  6. 6
    Rafael Ponte

    Post muito bom, mas por que você complicou tanto o código JavaScript, poderia ter simplificado para o post :) Pára de ser esnobe, rss.. Vê se não complica na palestra de amanhã!

    Pare com essa balela de “somente com linguagem funcional √© poss√≠vel implementar MapReduce”, toda vida voc√™ fala isso, rsss.. Acho que voc√™ quis dizer que Java n√£o implementa as fun√ß√Ķes map e reduce que s√£o comumente usadas em linguagens funcionais :)

    Enfim, eu gostei do post, excelente qualidade no texto, contudo isso ainda n√£o me convenceu, por incr√≠vel que pare√ßa ainda me parece complicado manter um sistema assim, talvez por n√£o haver ainda uma estrutura de organiza√ß√£o, n√£o sei.. mas ser√° que n√£o seria mais f√°cil utilizar-se de Groovy √† JavaScript, n√£o? Assim n√£o precisar√≠amos ficar “populando” as vari√°veis atrav√©s daquela engine..

    Parabéns, estou muito ancioso pela palestra de amanhã!

  7. 7
    Hildeberto

    Desempenho parece ser o √ļnico argumento para MapReduce em linguagem funcional? Hadoop t√° implementando isso em Java. Obvio que √© melhor fazer em C (e n√£o em C++ para os puristas) se o problema for desempenho. Porque o Google usou C++ mesmo? Deve ter algum objeto l√°, n√£o? heheheh

  8. 8
    cmilfont

    @Felipe Ga√ļcho

    “1 – falar em MapReduce nao faz parte da realidade brasileira :)”

    MapReduce foi apenas um exemplo de algo que se cria conhecendo linguagens funcionais, sequer faz parte do foco do Post. Mesmo assim dizer que MapReduce n√£o faz parte da realidade brasileiro voce cai em erro, temos muitas empresas que se preocupam com escalabilidade, imagine quantos milh√Ķes de pessoas consultam o BigBrother diariamente, n√£o que o MapReduce esteja envolvido diretamente e sim que solu√ß√Ķes de manipual√ß√£o maci√ßa de dados s√£o da realidade brasileira sim. Mas esquecamos o MapReduce no foco do artigo…

    “2 – supor que o deployment vai ficar mais simples por ter scripts eh supor que voc√™ nao vai precisar testar a parte est√°tica contra as novas regras editadas no script.. Na pr√°tica, alterando qualquer linha do projeto (seja est√°tica ou din√Ęmica) voc√™ precisa executar todos os testes de aceita√ßao novamente, ent√£o adeus simplicidade :)

    Custo de deploy não tem nada a ver com testes, rodar uma bateria de testes é primordial sim e os testes devem e são feitos no script tambem. Reveja seus conceitos de deploy, o que excutar uma bateria de testes tem a ver com o custo do deploy diretamente?
    Outra coisa, a proposta abordada no artigo são para mudanças imprevisíveis e ágeis, separei bem os conceitos do código estático, aquele que envolve os principios do negocio daquela parte dinamica que são regras gerais de varejo.

    “Jah vi muitos palestrantes sugerirem ‚Äúeu vou abrir um editor de texto, trocar meia duzia de linhas do meu script e tudo estar√° atualizado sem a necessidade de compilar c√≥digo, etc.‚ÄĚ.. me parece uma grande fal√°cia quando eu lembro que o codigo vai ter que ser retestado.. ent√£o a unica simplicidade eh usar um editor de texto para editar o script ao inves do eclipse para edtar o codigo Java. Depois de editados, ambos os artefatos passar√£o por uma bateria de testes que nao vao ficar mais simlpes pelo formato dos arquivos :)”

    Abro o Eclipse mesmo para editar os scripts e me beneficio de uma IDE moderna para isso, a simplicidade está na manutenção e agilidade nas mudanças e não com o que se vai alterar.
    Mais uma ves, codigo estatico ou não, a bateria de testes são rodados do mesmo jeito e isso não tem impacto em nenhuma abordagem em relação a diferenciação de custo

    “Ainda espero algu√©m que me conven√ßa da menor complexidade dos scripts diante de linguagens OO e fortemente tipadas :) Continuo supondo que exista grandes benef√≠cios no uso do script, mas ateh hoje nao apareceu a prova cabal disso :) eheh a menos, claro, se estamos falando no maldito browser e suas gambiarras javascript.. aih nao tem jeito mesmo.. ahah”

    Como eu enfatizei no texto, cada linguagem tem seu uso, a construção de um Domain Model com uma linguagem estática é primordial por tudo ue envolve a qualidade de verificação em tempo de compilação, etc. não há nesse ponto concorrência entre linguagens dinamicas e estaticas, o uso das dinamcias seriam nos pontos que a estatica sofre com manutenção e agilidade.

  9. 9
    cmilfont

    @Rafael Ponte

    “Post muito bom, mas por que voc√™ complicou tanto o c√≥digo JavaScript, poderia ter simplificado para o post :) P√°ra de ser esnobe, rss.. V√™ se n√£o complica na palestra de amanh√£!”

    Pelo contrário, eu usei um trecho de código roubado do prototype e comum a quem conhece algum framework javascript, pode ser difícil de ler para quem não tem conhecimento de javascript da New School.

    “Pare com essa balela de ‚Äúsomente com linguagem funcional √© poss√≠vel implementar MapReduce‚ÄĚ, toda vida voc√™ fala isso, rsss.. Acho que voc√™ quis dizer que Java n√£o implementa as fun√ß√Ķes map e reduce que s√£o comumente usadas em linguagens funcionais :)”

    Eu não falei em ponto algum que MapReduce é implementado apenas em linguagens funcionais, entenda de uma ves por todas, eu falei que MapReduce é criado por QUEM conhece linguagens funcionais porque exige uma abstração de alguem que já trabalhou com Lisp ou similar. Implementar voce consegue com outra linguagens, mas criar, imaginar só tendo a abstração necessária. Um Javer puro que não conhece linguagens funcionais dificilmente sairia com um algoritmo desses.

    “Enfim, eu gostei do post, excelente qualidade no texto, contudo isso ainda n√£o me convenceu, por incr√≠vel que pare√ßa ainda me parece complicado manter um sistema assim, talvez por n√£o haver ainda uma estrutura de organiza√ß√£o, n√£o sei.. mas ser√° que n√£o seria mais f√°cil utilizar-se de Groovy √† JavaScript, n√£o? Assim n√£o precisar√≠amos ficar ‚Äúpopulando‚ÄĚ as vari√°veis atrav√©s daquela engine..”

    Popular variáveis através de que? não entendi.
    O que voce quis dizer com estrutura de organização?
    Groovy a Javascript é questão mais de gosto pessoal.
    Observe que o foco do artigo √© no Domain Model, quando existe um, falei claramente que se o seu sistema √© uma amontoado de consultar, cadastros e relat√≥rios, n√£o h√° necessidade aparente de ter um Domain Model e consequente utilizar uma abordagem com linguagens din√Ęmicas.

    “Parab√©ns, estou muito ancioso pela palestra de amanh√£!”
    Amanh√£ nos degladiamos ao vivo :)

  10. 10
    cmilfont

    @Hildeberto

    “Desempenho parece ser o √ļnico argumento para MapReduce em linguagem funcional? Hadoop t√° implementando isso em Java. Obvio que √© melhor fazer em C (e n√£o em C++ para os puristas) se o problema for desempenho. Porque o Google usou C++ mesmo? Deve ter algum objeto l√°, n√£o? heheheh”

    Desempenho n√£o √© o √ļnico argumento para linguagens funcionais. Processamento ass√≠ncrono de um loop da fun√ß√£o s√≥ √© feito em linguagens funcionais, n√£o em java.
    Os proprios criadores do MapReduce admitiram que foi pela influência de LISP que criaram o algoritmo, desenlveram em C++ mas se voce observar o Paper não há nenhum objeto lá, não usaram como uma linguagem OO. Aliás Alan kay nem considera C++ uma linguagem adequada para OO :)

    Outra coisa, como falei para o @Rafael Ponte e para o @Felipe Ga√ļcho, MapReduce foi apenas um exemplo de algo que se cria apenas com a abstra√ß√£o necess√°ria para isso e um Javer puro que n√£o conhe√ßa linguagens funcionais dificlmente conseguiria, n√£o afirmei em ponto algum que n√£o d√™ para implementar em outros paradigmas.

  11. 11
    Rafael Ponte

    @Christiano Milfont

    “Pelo contr√°rio, eu usei um trecho de c√≥digo roubado do prototype e comum a quem conhece algum framework javascript, pode ser dif√≠cil de ler para quem n√£o tem conhecimento de javascript da New School.”

    Exacto, e quem disse que o código do prototype é simples? Como você disse, o código acima é comum à quem conhece um framework javascript, mas essa não é a realidade da maioria do desenvolvedores do mercado, eu mesmo me perco na New School :) Não é só porque vou utilizar o Spring ou Hibernate que preciso entender o código contido neles, alias, com certeza é algo até complexo e muito extenso de entender, além do mais eu quero somente utilizar o framework, não preciso entendê-lo a fundo.

    “Popular vari√°veis atrav√©s de que? n√£o entendi.”

    Atrav√©s da engine de scripting, engine.put(“lista”, this.itens);

    Com Groovy e até mesmo com JRuby você consegue acessar as classes e objetos Java, assim não há necessidades de usar essa engine ae :) Não sei se é possível diretamente com JavaScript e o Rhino, sabe dizer se é possível?

  12. 12
    cmilfont

    @Rafael Ponte

    “Exacto, e quem disse que o c√≥digo do prototype √© simples? Como voc√™ disse, o c√≥digo acima √© comum √† quem conhece um framework javascript, mas essa n√£o √© a realidade da maioria do desenvolvedores do mercado, eu mesmo me perco na New School :) N√£o √© s√≥ porque vou utilizar o Spring ou Hibernate que preciso entender o c√≥digo contido neles, alias, com certeza √© algo at√© complexo e muito extenso de entender, al√©m do mais eu quero somente utilizar o framework, n√£o preciso entend√™-lo a fundo.”

    Voce precisa entender os princípios de um framework se quer usá-lo, saber quais patterns ele implementa, na verdade qual o problema que ele resolve, mas isso é assunto que já extrapola essa discussão. O ue importa é criar uma linguagem comum para a equipe em seus diversos niveis, lembre-se que o dominio que essa linguagem atuará é bem específico, a arquitetura como um todo ficará n a linguagem multipropósito como todo mundo tem o costume de usar.

    “Atrav√©s da engine de scripting, engine.put(‚ÄĚlista‚ÄĚ, this.itens);”

    Esse método é para compartilhar variáveis em tempo de execução no mesmo contexto, seja em Jruby, Groovy ou outra linguagem qualquer usando a JSR223

    “Com Groovy e at√© mesmo com JRuby voc√™ consegue acessar as classes e objetos Java, assim n√£o h√° necessidades de usar essa engine ae :) N√£o sei se √© poss√≠vel diretamente com JavaScript e o Rhino, sabe dizer se √© poss√≠vel?”

    Veja que o Java que est√° chamando o script e n√£o o contr√°rio, voce precsa compartilhar as variaveis no mesmo contexto que seu script. Voce deve ta confundindo com a chamada a partir do script a um objeto java como por exmeplo a chamada a uma Util:

    importClass(“java.util.List”);

  13. 13
    Rafael Ponte

    @Christiano Milfont

    “Veja que o Java que est√° chamando o script e n√£o o contr√°rio, voce precsa compartilhar as variaveis no mesmo contexto que seu script. Voce deve ta confundindo com a chamada a partir do script a um objeto java como por exmeplo a chamada a uma Util:

    importClass(‚ÄĚjava.util.List‚ÄĚ);”

    Não, não.. estou falando de código JavaScript instanciando classes Java, em JRuby (ou mesmo Groovy) teríamos algo como:

    frame = javax.swing.JFrame.new()
    frame.getContentPane().add(javax.swing.JLabel.new(‘Hello, World!’))
    frame.setDefaultCloseOperation(javax.swing.JFrame::EXIT_ON_CLOSE)
    frame.pack()
    frame.set_visible(true)

    Saca? D√° uma olhada em http://en.wikipedia.org/wiki/JRuby
    Com Groovy tamb√©m √© poss√≠vel, assim conseguimos ter uma “conversa√ß√£o” mais agrad√°vel entre os dois paradigmas :)

  14. 14
    cmilfont

    @Rafael Ponte

    Eu falei sobre isso mesmo, releia minha resposta, colei um trecho de importação para que possa instanciar objetos diretamente como voce exemplificou.
    Agora entenda, preciso trocar referencias entre contextos diferentes já instanciados no java para o script, daí precisa usar a APi da jsr223 para enviar esses valores ao script.

    para clarear, faça uma analogia com Http, preciso botar variaveis no request ou session para compartilhar contextos diferentes:

    uma coisa é voce fazer
    var frame = new JFrame(“”);

    outra é var desconto = valorTotal Р10; // onde esse ValorTotal é uma propriedade de uma classe java fora do contexto do script

  15. 15
    David

    √ďtimo post. Escrevi um post parecido (n√£o t√£o claro como o seu) onde uso o pattern Command para fazer a parte Dinamica. S√≥ que ao invez de utilizar a OO, pretendo utilizar o Windows Workflow Foundation (WWF).

    http://cquesabe.blogspot.com/2007/12/workflow-foundation-ou-porque-existem.html

    Abs. David

  16. 16
    Christiano via Rec6

    Regras din√Ęmicas no Domain Model com linguagens de script – CMilfont Tech…

    Criando um mecanismo de execu√ß√£o de regras em alto n√≠vel dentro do cora√ß√£o do sistema…

Leave a Reply