Em um sistema MVC, onde deve estar o código de persistência do banco de dados?

21

Eu já vi várias configurações para persistir informações no banco de dados. Geralmente, três tipos de design parecem comuns no meu canto do mundo:

  • Controlador gerencia a persistência
  • O modelo gerencia a persistência
  • A biblioteca de terceiros gerencia a persistência, geralmente exigindo algum tipo de anotação no modelo.

Gostaria de saber qual configuração (se houver) é, conceitualmente, a mais fácil de usar / mais compatível com uma arquitetura MVC?

(Se não for o que eu listei, forneça um resumo / visão geral como parte da resposta)

blueberryfields
fonte

Respostas:

13

Suas segunda e terceira opções são idênticas. O M no MVC não é o modelo de dados, mas o modelo de domínio. Isso inclui persistência, seja feita diretamente ou via ORM, e ambas estão perfeitamente corretas.

O controlador deve gerenciar o fluxo do site e transmitir as coisas para o domínio (às vezes por meio de uma camada de serviço) a serem manipuladas, para que a persistência seja errada - ou pelo menos semanticamente desconfortável.

pdr
fonte
2
Eu discordo até certo ponto. A utilização concreta da persistência é lógica da aplicação e, portanto, pertence a uma camada de aplicação e não à camada de domínio. A camada de domínio (contendo o modelo de domínio) deve desconhecer a persistência do programa de negócios casual. O controlador é um orquestrador . Ele pode orquestrar serviços (dados), a interface do usuário e o modelo de domínio.
Falcon,
1
@ Falcon: Enquanto o controlador deve controlar quando os dados são carregados e persistidos no banco de dados, é perfeitamente certo que ele diga ao modelo para fazê-lo. O uso de um ORM (padrão ou faça você mesmo) normalmente significa dizer ao modelo para carregar / salvar, que depois delega ao ORM. Outra maneira seria fazer com que o controlador dissesse a um ORM para carregar / salvar algo passando uma classe de modelo para carregar (com critérios de seleção) ou uma instância de modelo para salvar. De qualquer forma, o carregamento / salvamento real será vinculado de maneira integrada ao modelo.
Marjan Venema
@ Marjan Venema: Sim, eu concordo, mas a questão é onde esse código deve residir. Esforço-me para manter o modelo o mais ignorante possível da persistência e apenas modelo as entidades do domínio com seus comportamentos e interações. Qualquer outra coisa viverá nas camadas de aplicativos (como é uma aplicação do meu modelo). O mapeamento de informações / acesso a dados é completamente dissociado do modelo de domínio e também pode cuidar da versão (atualização / downgrade). O pedido de acesso a dados também vive em camadas de aplicação (que contêm serviços, repositórios etc)
Falcon
@ Falcon: Sim, essa é uma boa maneira de fazê-lo e é como eu fiz isso no passado usando classes de mapeamento separadas. No entanto, com o advento do RTTI estendido (Delphi) e da reflexão (.Net e outros), não tenho escrúpulos em usá-los em conjunto com a anotação dos atributos do Modelo de Objetos de Negócios para dar tudo certo e usar sobrecargas de, ganchos de código em e / ou classes de inicialização codificadas especificamente para cuidar da versão do banco de dados.
Marjan Venema
5

Realisticamente, o MVC é principalmente um padrão de implementação de interface do usuário, portanto a questão é um tanto discutível. No entanto, existem realmente apenas duas opções gerais. Seu controlador normalmente envia solicitações para carregar ou salvar entidades em seu modelo usando 1) uma camada de serviço de algum tipo ou 2) o padrão Active Record.

A camada de serviço pode assumir várias formas, embora minha preferência pessoal seja trabalhar com uma abstração de repositório para as entidades raiz agregadas, cujas implementações concretas funcionarão com algum tipo de ORM ou um DAO leve ou um API para algum armazenamento não relacional, se isso fizer sentido para o aplicativo.

O padrão Active Record significa que seu modelo tem responsabilidade pela persistência, embora geralmente signifique uma classe base de algum tipo que gerencia os mapeamentos para sua loja, portanto, seu modelo não está diretamente envolvido diretamente.

Basicamente, o controlador despacha solicitações para persistir objetos, seja uma chamada para seu repositório, sua implementação UnitOfWork ou o método Save em suas entidades. Se você estiver usando repositórios, seus objetos de modelo ignoram a persistência.

JasonTrue
fonte
3

Em um sistema MVC (model-view-controller), o modelo contém os dados. Então, acredito que a persistência do banco de dados deve estar nela.

Nettogrof
fonte
2

A maioria das amostras de MVC de alto nível que eu já vi possuem uma infrastructurecamada separada que possui o código de implementação do banco de dados real (ou seja, as chamadas específicas para NHibernate, EF ou Linq ou qualquer que seja sua camada de dados), enquanto a camada "model" (geralmente também a camada "Domínio") possui as interfaces que definem os serviços de dados.

Wayne Molina
fonte
0

A prática padrão no MVC é incluir estrutura e persistência de dados na camada M (odel).

A camada de modelo não inclui apenas as classes (POCOs etc) que você usará em seu aplicativo. Eles incluem os repositórios para essas classes.

Um exemplo seria um repositório em que você tem um monte de instâncias de classes de dados, ou seja:

Clients repository

AllClients()
RecentClients()
ClientByID(int id)

Você será capaz de organizar melhor o domínio do modelo e também terá acesso aos seus dados de várias maneiras, mas ainda assim a camada de dados / modelo será compacta e robusta.

Mihalis Bagos
fonte