Este tópico me fez pensar sobre Regras de Negócio…
Levando-se em consideração um blog extremamente simples, com apenas Posts e Comentários onde a unica coisa possível é fazer CRUD de Posts e Adicionar/Remover comentários.
Aí vem a pergunta (sem adicionar nenhuma funcionalidade a mais): esse tipo de aplicação não tem regras de negócio? Se não, então suas Entities seriam como (de acordo com o post citado) “VOs” seguindo o modelo anemico?
Outra questão é sobre ActiveRecord. Lendo em alguns lugares percebi que a persistência de um Objeto é de responsabilidade de outro Objeto, correto? Então o ActiveRecord foge dos princípios OO?
Talvez a resposta seja: “Um projeto tão simples como esse não precisa se preocupar com tantos paradigmas”. Mas, e se esse simples projetinho fizer sucesso e começar a crescer? E se os usuários quiserem adicionar tags aos seus Posts? E se quiserem gerar relatórios para os posts mais acessados? E os mais comentados? E se quiserem controlar o acesso dos posts a usuários de um determinado perfil? E isso é só o começo…
Será que modelar de uma maneira mais bem elaborada (se for possível) não ajuda para possíveis modificações/novas implementações?
A grande questão é… será que este dia vai acontecer… e se acontecer será que as previsões que você fez se concretizarão ou será que você terá que excluir tudo e começar um novo projeto mais complexo… acho que nunca saberemos…
Primeiro, pode-se considerar crudo como ações de um objeto.
Sobre active record… O projeto pode continuar sendo orientado a objetos mesmo sendo implementando diversas formas de persistência. Inclusive dentro do próprio objeto.
Eu posso desenvolver em OO sem usar padrões de projetos… posso por regras de negócio dentro ou fora dos beans… são apenas maneiras diferentes de desenvolver… Utilizar boas práticas ou não não quer dizer que vc está desenvolvendo OO ou não.
Sim, possui regras de negócio. Como você as vai implementar é outra coisa.
A grande maioria das críticas com relação à modelos anêmicos se refere ao fato de que eles são geralmente usados simplesmente porque não se entende Orientação a Objetos. Existem situações onde se toma conscientemente a decisão de criar um modelo procedural ou anêmico (não são sinônimos) e me parece que seu exemplo de “blog simples” pode cair neste caso.
Hoje em dia fala-se de “Regras de Dominio” no sentido que todos os blog funcionam da mesma forma já todos pertencem ao mesmo dominio : blog.
Regra de Negocio é o que diferencia o Blog X do Blog Y ( o wordpress fo jblooger… sei lá…).
Ai existe regras suplementares ( inteligentes) que fazem algo a mais do gravar e acessar posts.
Então, o seu blog tem regras de dominio, mas não de negocio.
Hoje em dia “Regra de Dominio” e “Regra de Negocio” ainda são vistos como a mesma coisa, mas não são.
Se vc acha que são a mesma coisa, então a resposta é sim , o blog sim tem regras de negocio.
Não necessáriamente. Se eu definir Post com o método getComments() já não é anêmico
Não necessáriamente de outro.
São responsabilidades diferentes . Ok.
Se , e apenas se, vc aplicar o Principio de Separação (SoC) então cada responsabilidade deveria ser um objeto diferente.
A questão é: vc quer aplicar o SoC ?
Não. O ActiveRecord escolhe conscientemente não aplicar o SoC. É isso que forma a essência do padrão.
O ActiveRecord parte do principio que embora as responsabilidades sejam diferentes, ha vantagem em não as separar em dois objetos distintos. É nesta escolha consciente que fica a orientação a objetos.
O ponto é que ActiveRecord adiciona uma terceira linha na equação de modo a existir:
ha vantagem em não separar as responsabilidades.
Ora o que acontece, é que isso é verdade em alguns casos, mas não em geral ( se fosse verdade em geral o SoC seria furado o que seria absurdo porque o padrão é exatamente negar o uso SoC do caso geral)
A escolha ( o trade-off) de usar ActiveRecord é dificil. Então, para o principiante, comece usando o SoC como mandam as regras e deixe o ActiveRecord quando vc preceber nitidamente que ha a vantagem necessária ao uso do padrão. Caso contrário tudo irá virar uma amalgama de codigo.
[quote]
Talvez a resposta seja: “Um projeto tão simples como esse não precisa se preocupar com tantos paradigmas”. Mas, e se esse simples projetinho fizer sucesso e começar a crescer? E se os usuários quiserem adicionar tags aos seus Posts? E se quiserem gerar relatórios para os posts mais acessados? E os mais comentados? E se quiserem controlar o acesso dos posts a usuários de um determinado perfil? E isso é só o começo…
Será que modelar de uma maneira mais bem elaborada (se for possível) não ajuda para possíveis modificações/novas implementações?[/quote]
Sim, ajuda. Quem disser o contrário é porque nunca teve que implementar funcionalidades extra em um sistema pré-existente. Tornar a vida do cara que vem a seguir a vc é a missão de um bom programador.
Se vc não se preocupa com isso, vc não é um bom programador.
Essa coisa de sobre-engenharia não existe em software já que quanto mais geral mais barato ( na cosntrução civil é ao contrário). E pq mais barato ? Menos classes, responsabilidades mais definidas , melhor facilidade de alteração , melhor integração com testes, melhor entendimento por quem vem a seguir (poucos métodos em cada classe pq tem poucas responsabilidades). Tudo isto significam: menos bugs, maior aderencia às exisgencias do dominio, maior rapidez na alteração.
Etenda que o dominio é vasto. É por causa dele que vc sabe que mais tarde ou mais cedo o cliente vai querer ter a funcionalidade X no seu programa porque o concorrente tb tem. Se ambos têm a mesma necessidade é porque ela pertence ao dominio, não ao negocio. Quanto mais o seu programa aderir ao dominio, mais facil de expandir. ( um exmeplo rápido: na area financeira converter moedas é coisa do dominio. É algo todo o mundo precisa. Agora, cobrar pela consulta do cambio ou da propria conversão ou disponibilizar isso via webservice, etc. é coisa de negocio)
Faça códigos bem feitos, não apenas que funcionam.
Criar um monte de setters e getters não é nenhum crime. Não entender OO é. O código que eu exemplifiquei no post referenciado ilustra isso.
E sim, o grosso da maioria dos projetos é CRUD. É ser babá de banco-de-dados. Isso não deve ser vergonha de nenhum projeto. É claro que existem regras de negócio e elas só aumentam a medida que o sistema evolui.
Uma boa linguagem (Java ao invés de MS Access) e uma boa arquitetura (Action -> Service -> Repository/DAO ao invés de Action -> DB) pode ser um overkill no início, mas se paga no futuro a medida que o projeto ganha corpo e mais regras de negócio que não sejam apenas CRUD de beans.
A verdade é que objetos, por natureza, não pressupõe a necessidade de persistência. Mas o problema é que na maioria das platadormas isso não é nada natural.
Assim, ter um data mapper ou active record pra atender a essa necessidade é apenas uma maneira de se resolver o problema. Você pode optar por uma ou por outra, e ainda assim ser “orientado a objetos”.
É importante resaltar que aqui no GUJ se evangeliza muito o uso de OO porque grande parte da comunidade de desenvolvedores ainda não compreendeu direito o paradigma. Mas isso não significa que 100% dos softwares devem ser feitos de forma OO.
Aí vem a pergunta (sem adicionar nenhuma funcionalidade a mais): esse tipo de aplicação não tem regras de negócio? Se não, então suas Entities seriam como (de acordo com o post citado) “VOs” seguindo o modelo anemico?[/quote]
Baixe o JBoss Seam e analise o exemplo de um blog que implementa classes de negócio como Blog, BlogEntry, HitCount a la Hibernate/JPA.
Ou seja, até um blog, por mais simples que possa parecer, tem suas regras de negócios/conceitos de domínio.
Eu tenho uma plataforma de blog semelhante ao wordpress, e possui algumas regras bem complexas. Escolhi usar controller > service/business > repository, com Vraptor, Spring e Hibernate.
A area pública a regra grande fica apenas no envio de comentários, o que já é bem extenso:
verificar se o post está ativo e pode receber comentários
conforme a política do post aprovar ou não o comentário (a post que o autor quer aprovar, outros aprova automatico, etc)
se anti-spam estiver ativo:
verificar se o post é spam
verificar se vem de alguma rede de spammer conhecidos
fazer um parse do comentário para evitar XSS e afins
limpar o comentário deixando apenas as tags HTML permitidas
enviar email para autor do post
Outra regra que tenho é quando um link for chamado, antes de exibir um post é necessário verificar a permissão, pois os posts podem ser públicos ou protegidos por senha. Posts em DRAFT apenas o autor pode visualizar, e os posts em Pending Review apenas o autor ou algum usuário com a role REVIEW pode acessar.
No admin, a coisa é mais complicada:
apenas autores podem editar seus posts
quando um post está marcado como Pending Review os revisores podem fazer alterações, porém antes da publicação o autor necessita aprovar.
apenas o autor do post pode excluir e editar comentários
Estou agora fazendo suporte a multiplos domínios, sendo assim vou ter umas regras mais chatas ainda.
E por ai vai… Como sempre digo, qualquer projeto começa pequeno, mas logo logo cresce… então é bom já ir pensando grande.
Pela quantidade de citações sobre Repository neste fórum acredito que este seja o padrão mais utilizado por aqui. Será que alguém poderia fazer a gentileza de informar alguma literatura para que possa aprender mais sobre este padrão. As únicas que achei tratam do assunto no contexto de domain-driven design, mas por exemplo que raios é um Repositório/DAO?
Acho que o pessoal confunde um pouco o modelo anêmico. (Posso até estar incluído nessa também).
No meu entendimento, você só tem um modelo anêmico quando você separa estado de comportamento. Você ter objetos apenas com construtor, getters e setters não indica que o seu modelo seja anêmico. Quando você tem VOs e BOs, sim você está construindo um modelo anêmico.
O maior problema desse modelo, ainda de acordo com o meu entendimento, é a quebra do princípio da OO que diz que você tem estado e comportamento no mesmo artefato de software. Essa quebra dificulta a manutenção.