Onde colocar a lógica de negócio?
21/02/2008 00:00
0
Uma pergunta na lista do Grails gerou uma discussão interessante sobre onde a lógica de negócio deve ser codificada. Nos controllers? Em services? Nas classes de domínio?

Enfim, onde vcs codificam as regras de negocio da aplicação?

valeuz...
Tags: Grails


0
Eu coloco nas classes de domínio. Eventualmente uso um service...

[]'s

Rodrigo Auler
21/02/2008 00:00


0
Tudo, menos nos controllers
22/02/2008 00:00


0
Idem aos colegas acima...
Preferencialmente nos domains, eventualmente em services, mas nunca em controllers...
22/02/2008 00:00


0
Esta é uma discussão interessante.

Quem tiver interesse, dê uma olhada neste artigo... ele fala sobre a "Mítica Camada de Negócios". Leitura interessante.

Eu procuro seguir o seguinte:
- quando uma regra diz respeito a um objeto de domínio específico, como por exemplo, calcular algum valor do objeto Divida (dívida) a partir de determinados atributos deste objeto (se é dívida por juros compostos ou simples, taxa anual ou mensal, valor presente, etc....), este cálculo pode ser feito por um método do próprio objeto Divida, certo? Ou seja:
def valor = Divida.calculaSeiLaOQue()

- quando uma regra de negócio se faz a partir da interação de mais de um objeto de domínio, aí neste caso eu geralmente uso uma classe Service, que irá encapsular as chamadas aos métodos de cada objeto de domínio, chamadas a um web service externos, ou a um DAO em Java, e por aí vai.

Isso exclui portanto, as regras nos Controladores. Por outro lado, os controladores sempre tem uns IFs, sempre monta alguma mensagem a ser exibida, ou passa objetos para a View, etc, etc. Será que eu poderia chamar isso de regras de negócio?

Olhando um pouco pelo lado de desenvolvimento ágil, incremental, com refactorings, etc, etc, às vezes eu me pego com alguma regra no controlador, e ao fazer outro controlador, vejo que vou usar a mesma regra. Simplesmente eu movo esse código do primeiro controlador para uma classe Service, e faço os dois controladores usarem este Service. Mas se o segundo controlador nunca tivesse existido, talvez a regra teria ficado no primeiro controlador mesmo.

Numa equipe maior, as coisas ficam um pouco mais críticas, e normas e práticas de encapsulamento de regras de negócio nas classes de Service podem facilitar muito o reaproveitamento de código.

Abcs
Felipe
22/02/2008 00:00


0
Olá!
Sei que este post já é antigo, mas esta é uma questão que sempre me inquietou.

Então, para tratar diversas situações, principalmente relacionados às persistências de forma que as regras fiquem isoladas do controlador e da classe de domínio, eu resolvi criar uma nova camada, que chamei de camada de negócios.

A estratégia consiste em:
1) Quando eu identificar que alguma classe de domínio possui regras diferenciadas de negócio, eu crio uma classe de negócio que fica responsável por aplicar as regras e chamar a persistência dos objetos. Algo como VendasNegócio.
Por exemplo, se eu possui a classe de domínio faturamento.Vendas e se antes de vender eu precisasse checar algo sobre o cliente comprador, eu crio a classe VendasNegocio que fica em src/groovy/negocio/faturamento/VendasNegocio.groovy.
seu conteúdo seria algo como:
package negocio.faturamento;

class VendasNegocio {

public faturamento.Vendas insert(faturamento.Vendas _oObjDomain) {
/*
* coloco todas as regras aqui : checar o cliente comprador
*/

oObjSalvo = _oObjDomain.save(flush: true);
return oObjSalvo;
}
/*
* podem ser colocados todas as outras actions que existem no template
* controller.groovy do scaffold
*/
}

2) Alterar os templates do scaffold controller.groovy para:
a) verificar se existe uma classe de negócio para a classe de domínio em questão;
b) instanciar a classe de negócio, caso exista;
c) transferir a persistência para o método adequado do objeto da classe de negócio instanciada (insert, update, delete, list, etc);
as alterações seriam algo como:
def save = {
def ${propertyName} = new ${className}(params);

/*
* Caso exista uma classe de negócio implementada para esta classe
* utiliza a classe de negócio para salvar o objeto
*/
def oObjSalvo;

<%=
String sPackageName = "negocio.${packageName}";
String sClassName = "${className}Negocio";
def cNegocio = null;
try {
cNegocio = Class.forName(sPackageName + "." + sClassName, true, Thread.currentThread().getContextClassLoader());
def oMetodo = cNegocio.methods.findAll { it.name == "insert" };
if (oMetodo) {
String sRetorno = 'def o'+ sClassName + ' = new ' + sPackageName + '.' + sClassName + '(); oObjSalvo = o' + sClassName + '.insert(' + propertyName + ');';
sRetorno;
} else {
String sRetorno = 'oObjSalvo = ' + propertyName + '.save(flush: true);';
sRetorno;
}
} catch (ClassNotFoundException e) {
String sRetorno = 'oObjSalvo = ' + propertyName + '.save(flush: true);';
sRetorno;
}
%>
if(oObjSalvo) {
flash.message = message(code: 'default.created.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), ${propertyName}.id])
redirect(action: "list")
} else {
return render(view: "create", model: [${propertyName}: ${propertyName}]);
}
}


conclusão:
Com esta estratégia eu isolo as regras de negócio, aproveito os templates e não preciso ficar construindo controladores para cada caso específico.
30/12/2011 13:46



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto