Bem, estou com uma dúvida na implementação de minha camada de negócios. Estou fazendo uma aplicação de testes onde trabalho da seguinte forma:
Tenho minhas classes. Exemplo: Conta, ContaCorrente, ContaPoupança
Tenho minhas classe de acesso a dados: ContaDAO
Tenho minhas classes de negócio: ContaBLL
Daí vai minha dúvida:
Como Conta é genérica com suas filhas(ContaCorrente, ContaPoupanca), como devo implementar os métodos para minha classe de negócio ContaBLL? Devo criar classes de negócio ContaCorrenteBLL? Pois alguns métodos são iguais.
ContaBLL é minha classe onde vai a regra de negócio. Conta é somente a classe com suas propriedades.
Y
YvGa
Por que voce nao faz tudo na mesma?
G
guilhermezerbinatti
Valmir,
Na sua classe que implementa a regra de negocio deve contar todas as validações que são necessarias fazer antes de chamar a sua classe ContaDAO.
Por exemplo, na classe BLL pode existir um método que verifica se o saldo da conta é o suficiente para efetuar o pagamento, caso não seja sobe um erro.
As classes da regra de negócios devem que implementa esses tipos de tratamento para o seu sistema.
Abraços
B
bKn
Neste caso creio que não seja necessário mais de uma classe para regras de negócio, você pode estar fazendo todas as validações (mesmo que específicas das implementações) na mesma classe.
Por que voce nao faz tudo na mesma?
Ai meu rim.
laudenpower
Nesse caso não entrando na questão sobre o anemic model (Ler fowler), acredito que o que for especifico fica nos filhos, o que for geral fica no pai.
Espero ter ajudado
V
valmirbispo
Até que enfim alguém me entendeu. Mas de qualquer forma segue uma ilustração do que eu estava falando. Tenho o diagrama 1 e o diagrama 2.
Comecei implementando como no diagrama 1. Fiz uma classe de negócio para cada filha. Acontece que para implementar o método carregar deixei somente na pai e este seria usado por todas as filhas. Tive uma dificuldade, pois estou usando NHibernate (Estou iniciando nesta tecnologia) e quando faço o cast para o retorno dá erro, pois meu método retorna um tipo conta, mas este pode ser Corrente ou Poupança. Bem, ilustrarei para que me entendam melhor.
A saída que achei foi um case onde dependendo do tipo que retorno faço o cast específico. Posso estar fazendo bobeira, já que sou iniciante em NHibernate.
Emerson_Macedo
Colega, você não precisa de ContaBLL. Você precisa apenas de Conta com estado e comportamento. Da forma que você está fazendo, está programando procedural, como em C por exemplo. Dá uma lida em 2 artigos do Phillip Calçado que são bem legais pra te dar um start no assunto.
Principio da Orientacao a Objetos: Dados e Logica juntos.
Acredite, depois que vc passar a juntar essas coisas vc vai ser muito mais feliz. E vai codificar menos.
V
valmirbispo
Posso fazer isto. Posso juntar dados e lógica sem problemas. Agora e quanto a DAO? Tenho que fazer toda a codificação como consultas no mesmo método da classe. Ou mantenho a DAO?
fabim
DAO tem a ver com persistencia.
Persistencia nao tem a ver com objetos, é apenas uma maneira de guardar os dados pra vc poder “reconstruir” esses objetos depois.
Resumindo: Mantenha seus “DAOs”.
Agora tenha em mente: DAOs, como o proprio nome ja diz, sao Data-Mappers e devem lidar com dados brutos. Classes que te retornam um List por exemplo são classes de Repositorios.
De uma pesquisada no GUJ e vc vai entender tudo sobre DAOs e Repositorios.
laudenpower
fabim:
DAO tem a ver com persistencia.
Persistencia nao tem a ver com objetos, é apenas uma maneira de guardar os dados pra vc poder “reconstruir” esses objetos depois.
Resumindo: Mantenha seus “DAOs”.
Agora tenha em mente: DAOs, como o proprio nome ja diz, sao Data-Mappers e devem lidar com dados brutos. Classes que te retornam um List por exemplo são classes de Repositorios.
De uma pesquisada no GUJ e vc vai entender tudo sobre DAOs e Repositorios.
Bom mas nesse caso os métodos que retornam List utilizando JDBC? Nesse caso é feito o mapeamento do objeto que será inserido na lista, para que seja passado aos seus atributos os valores vindos do banco.
Sempre entendi que qualquer classe que tenha que fazer acesso direto ao banco era um DAO…
fabim
"Sempre entendi que qualquer classe que tenha que fazer acesso direto ao banco era um DAO… "
Esse entendimento está correto.
Mas perceba que somado a isso deve-se levar em conta que um DAO deve ser plugável.
Se 2 sistemas acessam um mesmo banco, eu deveria poder reaproveitar seu DAO nos 2.
Porem se seu DAO conhece objetos especificos do dominio, como manter essa portabilidade?
Um sistema pode persistir os dados de um objeto CLIENTE em uma tabela.
E se outro sistema, que acessa o MESMO banco, persistir um objeto PESSOA?
laudenpower
fabim:
"Sempre entendi que qualquer classe que tenha que fazer acesso direto ao banco era um DAO… "
Esse entendimento está correto.
Mas perceba que somado a isso deve-se levar em conta que um DAO deve ser plugável.
Se 2 sistemas acessam um mesmo banco, eu deveria poder reaproveitar seu DAO nos 2.
Porem se seu DAO conhece objetos especificos do dominio, como manter essa portabilidade?
Um sistema pode persistir os dados de um objeto CLIENTE em uma tabela.
E se outro sistema, que acessa o MESMO banco, persistir um objeto PESSOA?
Nesse caso estamos assumindo que pessoa contém os mesmo atributos de cliente? Ou seria um objeto “pai” do qual cliente herda tudo e ainda tem mais outros atributos?
V
valmirbispo
Bem gente,
Estou aqui outra vez para expor ainda algumas dúvidas. Pesquisei sobre DAO e Repository. Entendi, mas ainda surgiram dúvidas. Pelo que entendi, tenho meu repositório onde posso acessá-lo de minha camada de negócio. Este repositório pode ser implementado pela DAO que por sua vez acessa a base de dados diretamente.
Minha dúvida ainda assim, fica no nível inicial. Como implemento minha DAO? Para cada tabela tenho uma DAO? Um bom exemplo seria que minha tabela conta teria um ContaDAO e com ela faria todas as transações referentes a esta tabela? E quanto a herança, como ficaria? PoupancaDAO?
Sobre Repository, uma introdução é bem feita aqui:
Tem que tomar cuidado com essa coisa de DAO e Repository. São coisas diferentes e confundem muito inclusive algumas pessoas que já lidam com isso. No livro do Fowler (Patterns of Enterprise Application Architecture) ele introduz o pattern Repository. Dá uma lida lá e faz uma busca pra saber mais. Como eu falei, é MUITO fácil confundir as duas coisas.
Y
YvGa
bKn:
Neste caso creio que não seja necessário mais de uma classe para regras de negócio, você pode estar fazendo todas as validações (mesmo que específicas das implementações) na mesma classe.
Por que voce nao faz tudo na mesma?
Ai meu rim.
O que lhe aflige? Precisa de medico?
Sim, tudo na mesma, separar regra dos dados nao tem necessidade, se uma classe possui os dados, qual o problema de conter as regras aplicadas sobre eles? ContaBLL, Conta? Pra que?
Agora dizer que não é necessario mais de uma classe para regras de negócio é boa, hein. Todas as validacoes numa mesma classe? Tipo um tripão de 1000 linhas?
Devemos ter mais educacao ao responder os topicos, principalmente aqueles relacionados a assuntos que nao temos dominio.
B
bKn
Para desacoplar a camada de negócio e torná-la orientada a objetos. Para centralizar o seu comportamento e promover o reuso. Para evitar duplicidade e melhorar a manutenção do código. Para promover uma arquitetura orientada a serviços.
É a consequência dos business objects, objetos inchados. Antes isso do que 500 linhas em dois lugares diferentes, ou vai me dizer que trabalhar com POJOs é mágico e diminui a quantidade de regras de negócio?
Concordo. Imposição de opinião não é nada educado; só porque você trabalha de uma maneira ele tem que o fazer também?
Y
YvGa
bKn:
YvGa:
Sim, tudo na mesma, separar regra dos dados nao tem necessidade, se uma classe possui os dados, qual o problema de conter as regras aplicadas sobre eles? ContaBLL, Conta? Pra que?
Para desacoplar a camada de negócio e torná-la orientada a objetos. Para centralizar o seu comportamento e promover o reuso. Para evitar duplicidade e melhorar a manutenção do código. Para promover uma arquitetura orientada a serviços.
Com isso voce nao a esta tornando orientada a objeto, esta fazendo justamente ao contrario. Separar dados e regra, nao evita duplicidade, nem promove reuso. Separar dados e regras é programacao procedural com variaveis e funcoes.
Nao, nao diminui a quantidade de regras, mas aumenta muito a legibilidade do codigo. Uma classe com 1000 linhas estara repleta de if-else e código que podia estar mais bem organizado. Qualquer alteracao que precise ser feita, por menor que seja, leva horas só pra encontrar o lugar, ou os lugares (na maioria dos casos) onde ela deve ser feita.
Repare que eu fiz uma pergunta ao criador do topico, em nenhum momento disse a ele como ele tem que fazer, muito menos disse “ai meu rim” para a implementacao que ele propos. Eu perguntei por que, com o intuito dele avaliar a decisao dele. Quem sabe ele tentando uma explicacao vai perceber que nao esta tomando a melhor decisao.
B
bKn
Não é raro validar estados de entidades de acordo com estados de outras. Fazer isso com DOs, na minha concepção, é extremamente bolorento, e cria sim duplicidade, a menos que se aumente o acoplamento entre elas. Deixar regras de negócio dentro de entidades é atribuir à elas responsabilidades que muitas vezes não lhe dizem respeito.
De que maneira? Não vejo como isso é possível.
O que te faz concluir isso? Antes saber que terei de modificar a minha classe de negócio do que modificar a entidade em si, podendo ocasionar erros em todo o resto da minha aplicação que a manipula.
Y
YvGa
bKn:
YvGa:
Com isso voce nao a esta tornando orientada a objeto, esta fazendo justamente ao contrario. Separar dados e regra, nao evita duplicidade, nem promove reuso. Separar dados e regras é programacao procedural com variaveis e funcoes.
Não é raro validar estados de entidades de acordo com estados de outras. Fazer isso com DOs, na minha concepção, é extremamente bolorento, e cria sim duplicidade, a menos que se aumente o acoplamento entre elas. Deixar regras de negócio dentro de entidades é atribuir à elas responsabilidades que muitas vezes não lhe dizem respeito.
Validar o estado de objetos baseado no estado de outros objetos sim é alto acoplamento, pois se para um objeto ser valido é preciso que outra seja valido eles estao acoplados. Isso nao só deveria ser raro, mas evitado a todo custo (exceto no caso da relacao root-agregates). Como pode nao ser responsabilidade de um objeto realizar operacoes sobre os seus proprios dados? Quem mais pode ter a responsabilidade de alterar o estado de um objeto se nao ele mesmo? Em que isso aumenta o acoplamento? Lembre-se que um objeto nao é composto por dados e regras, mas por estado e comportamento. Separar o estado do comportamento é caminhar na direcao procedural, onde funcoes alteram o valor de variaveis. É o que voce esta fazendo separando o estado do comportamento.
Voce acha mais facil entender o que faz um metodo com 500 linhas do que um com 5?
Hmmm, ja ouvi essa expressao em algum lugar. Algo como o inferno das variaveis globais??? Encapsule os dados e esse medo diminui bastante.
s4nchez
Pelo que voce descreveu ate agora a responsabilidade de todas as suas entidades eh a mesma: ser um saco de atributos.