Onde a lógica de negócios deve ir em uma arquitetura em camadas?

5

Em primeiro lugar, não estou falando de validação no sentido da nulidade ou duração de um campo como em este e esta perguntas onde podemos use métodos isValid () em classes de negócio ou um validador externo. No entanto, minha pergunta está relacionada a validar ou não em classes de negócios. Estou usando um estilo de arquitetura em camadas com serviços consumindo a camada da fonte de dados e interagindo com o modelo de domínio.

Seguindo os requisitos de domínio, suponha que eu tenha filmes e resenhas, e os usuários podem fazer apenas uma resenha por filme. Assim, uma segunda revisão é um objeto válido, mas as regras de negócios não devem permitir que a revisão seja concluída.

Então, eu poderia fazer:

ReviewService >> addReview(review,movie)
  loggedUser = getLoggedUser()
  review = reviewRepository.searchReviewFrom(loggedUser,movie)
  if (review == null)
    reviewRepository.save(review)
  else
    // some mechanism to inform the error, it could be NotificationPattern

Ou:

Movie >> addReview(review)
   for r in this.reviews
     if r.user = review.user
       throw ReviewAlreadyUploaded
   // if no expcetion is thrown
   this.reviews.add(review)

Acho que essa validação de oneReviewPerUser é uma regra de negócios pura e deve ser incluída nas classes de negócios, neste caso, a classe Movie. Assim, as regras de negócios estão contidas no domínio e não estão dispersas entre as camadas. No entanto, se as listas de Comentários dos Filmes forem grandes em quase todos os casos, essa opção implicará em consultar e instanciar um grande número de objetos de Revisão e iterar sobre todos os elementos.

Então, suponha que eu escolha a opção 1, tenho que garantir que cada cliente que queira criar um comentário para um Filme deve usar o Serviço, pois pode quebrar a restrição comercial de 1 revisão por usuário se, por exemplo, usar diretamente o ReviewRepository. Isso começa a soar como uma camada de Serviços com toda a lógica de negócios e um AnemicModel com Classes de Domínio sendo pacotes de atributos para transportar dados de e para o banco de dados.

Onde está a linha que separa a lógica de negócios que deveria estar em Serviços daquela que deveria estar nas classes de domínio.

    
por gabrielgiussi 12.07.2015 / 21:48
fonte

2 respostas

3

Em um aplicativo DDD (Domain Driven Design) usando uma arquitetura em camadas convencional, a lógica de negócios entra na camada domínio . Agora, observe que essa camada não contém apenas as entidades de domínio ( Movie , Review ), mas também serviços de domínio (como ReviewService class) e repositórios. Então, ReviewService também é uma classe de negócios.

Sua preocupação com cada cliente ter para usar o método de negócios apropriado ( addReview ) não é realista. Simplesmente não há nenhuma maneira prática de evitar que uma classe de clientes mal escrita viole regras de negócios, se os desenvolvedores não seguirem as regras da arquitetura escolhida. Por exemplo, se Movie tiver um método getReviews() (ou uma propriedade reviews ) que expõe uma coleção mutável de revisões, o código do cliente sempre poderá adicionar uma revisão arbitrária. E mesmo que seja imutável, o código do cliente sempre pode criar o Review inválido no banco de dados usando diretamente um repositório.

Na minha opinião, é melhor ter apenas métodos de negócios relativamente simples em entidades de domínio e, geralmente, apenas para operações somente leitura. Uma lógica de negócios mais complexa é melhor atribuída a classes de serviço de domínio coesas. Caso contrário, suas classes de entidade se tornarão muito grandes e complexas. Assim, por exemplo, uma operação de negócios que adiciona um assunto de revisão de filme a regras de validação de negócios seria melhor colocada em uma classe de serviço de domínio ReviewMaintenance ou até mesmo uma classe ReviewCreation se a operação "adicionar revisão" fosse suficientemente complexa. / p>     

por 12.07.2015 / 23:09
fonte
1

Você está deixando de fora a possibilidade de restringir a entrada no banco de dados. Se realmente pode haver apenas uma revisão de um filme em particular por um usuário em particular, isso deve ser uma restrição de banco de dados. Se você fizer isso, sua preocupação é como lidar com uma tentativa fracassada de inserir uma segunda revisão - como isso é reportado ao usuário?

    
por 13.07.2015 / 03:14
fonte