Modelos por tabela de banco de dados?

11

Estou usando o codeigniter e me encontrei em uma situação semelhante em que repeti os métodos Model. Estou criando um modelo por controlador. Mas a criação de uma tabela Modelo por banco de dados seria considerada uma boa prática? Dessa forma, os métodos não são escritos duas vezes.

Em vez de modelo por controlador ou vários modelos pequenos que são compartilhados.

Exemplo: se eu tenho um método de modelo, get_user ($ user_id), posso escrever em users_models.php ...

Uma das desvantagens que vejo disso é que talvez eu precise chamar vários modelos, em vez de apenas controllerername_models.php.

O carregamento de vários modelos em que vários métodos podem não ser usados ​​em um controlador afeta o desempenho e a velocidade? Qual poderia ser a melhor maneira de resolver isso?

Nota: Há uma pergunta semelhante, mas eles não cobrem o terreno do Modelo por tabela de banco de dados.

Howard Steff
fonte

Respostas:

8

Eu digo que um modelo por tabela está apenas recriando seu banco de dados em uma estrutura de classes. É conhecido como modelo anêmico e considerado antipadrão. Isso ocorre porque as classes devem ter dados e comportamento. Se você restringe seus modelos a uma única tabela, onde coloca o código (comportamento) que precisa lidar com dados e comportamento de várias tabelas? Seus controladores precisariam de modelos que usem um ou mais desses modelos de "tabela" ... Portanto, além dos aplicativos mais básicos, você ganha pouco ou nada com essa abordagem.

Marjan Venema
fonte
Apenas um adendo - é considerado anti-padrão por Martin Fowler. Ponto final aqui. Ele tem algumas idéias sobre esse caso, mas isso não significa que seja ruim - diferente do God Object, que quase sempre é ruim, uma estrutura como essa às vezes é incrívelmente útil e facilmente consertável. Não considero isso um antipadrão.
527 Sar
11
Como exemplo, o "modelo anêmico" é compatível com SOLID - é realmente ruim ter um objeto com uma única finalidade (armazenar dados)? Embora eu respeite muitas coisas que o Sr. Fowler diz, essa foi uma besteira.
T. Sar
7

Em geral, você deve criar seus modelos não por tabela ou por controlador, mas por objeto de negócios. Às vezes, talvez seja um relacionamento 1: 1 com a estrutura de suas tabelas ou com seus controladores, mas não é necessário.

No seu exemplo, você pode ter uma users_modelclasse chamada de vários controladores. Isso é bom e às vezes até desejável. No entanto, na maioria dos casos, a users_modelclasse obtém seus dados de várias tabelas.
Por exemplo, a last_login_datepropriedade da users_modelclasse pode ( não deve ) ser obtida de uma user_audittabela separada que possui um relacionamento com muitos com a userstabela principal .

E eu diria que se você tiver uma tabela SQL por objeto de negócios, é mais provável que sua estrutura de banco de dados não seja normalizada.

Dime
fonte
3

Concordo principalmente com a resposta de Dime que você deseja criar seus modelos por objeto de negócios - os problemas que a empresa está tentando resolver devem orientar como você cria as classes de modelo. Na prática, descobri que criar um modelo por tabela é um bom ponto de partida. É provável que um esquema projetado adequadamente imite os processos de negócios que você precisa modelar no código do aplicativo - também chamado de Modelo de Domínio.

O uso de uma camada de Mapeamento de Objetos / Relacional é útil para que seu Modelo de Domínio contenha os mesmos relacionamentos que o esquema do banco de dados sem a necessidade de chamadas repetidas para uma camada de acesso a dados. Confira o Eloquent for PHP como um exemplo. O esquema e o Modelo de Domínio devem ser projetados para suportar os processos de negócios.

Isso leva à primeira parte da resposta de Marjan Venema:

Eu digo que um modelo por tabela está apenas recriando seu banco de dados em uma estrutura de classes. É conhecido como modelo anêmico e considerado antipadrão.

Um modelo de domínio anêmico é um antipadrão. Um "modelo por tabela", como sugere Venema, pode ser visto como "recriando seu banco de dados", no entanto, é absolutamente incorreto dizer que apenas isso é um modelo de domínio anêmico.

Partida Martin Fowler:

O sintoma básico de um modelo de domínio anêmico é que, à primeira vista, ele se parece com a coisa real. Existem objetos, muitos nomeados após os substantivos no espaço do domínio, e esses objetos estão conectados aos ricos relacionamentos e estrutura que os verdadeiros modelos de domínio possuem. O problema ocorre quando você olha para o comportamento e percebe que quase não há comportamento nesses objetos, tornando-os pouco mais do que sacos de caçadores e caçadores.

(ênfase minha)

O fator chave em um modelo de domínio anêmico é a falta de comportamento, ou métodos, nas classes do Modelo de Domínio.

Isso ocorre porque as classes pretendem ter dados e comportamento. Se você restringe seus modelos a uma única tabela, onde coloca o código (comportamento) que precisa lidar com dados e comportamento de várias tabelas?

Novamente, você pode e deve colocar o comportamento nos seus Modelos de Domínio, mesmo que eles sejam mapeados apenas para uma tabela. O comportamento que afeta várias tabelas realmente afeta vários objetos que são mapeados para várias tabelas. O Design Orientado a Domínio é uma abordagem precisamente para o mesmo problema que Venema mencionou: "onde você coloca o código (comportamento) que precisa lidar com dados e comportamento de várias tabelas?"

E a resposta é uma raiz agregada . Martin Fowler afirma:

Agregado é um padrão no Design Orientado a Domínio. Um agregado DDD é um cluster de objetos de domínio que podem ser tratados como uma única unidade. Um exemplo pode ser um pedido e seus itens de linha, esses serão objetos separados, mas é útil tratar o pedido (junto com seus itens de linha) como um único agregado.

(ênfase minha)

Um "cluster de objetos de domínio" também pode ser exibido como "Modelos de Domínio que mapeiam para várias tabelas". O comportamento que afeta várias tabelas deve ser definido na Raiz Agregada - Uma classe que encapsula a "coisa" que afeta várias tabelas ou objetos:

Novamente, de Martin Fowler:

Um agregado geralmente contém coleções múltiplas, além de campos simples.

Para responder à pergunta original do OP:

... criar uma tabela Modelo por banco de dados seria considerado uma boa prática? Dessa forma, os métodos não são escritos duas vezes.

Eu diria que este é um bom ponto de partida, mas lembre-se de que seu esquema e modelo de objeto não precisam corresponder a 100%. O modelo de objeto deve estar mais preocupado em implementar e impor regras de negócios. O esquema deve se concentrar mais no armazenamento de dados corporativos de forma modular e escalável.

Um modelo por controlador não seria uma boa prática, embora exista uma variação do modelo chamada View Model que se encaixe na camada Controller. Um modelo de exibição é uma reorganização do modelo de domínio para ajustar-se a um determinado tipo de exibição, seja uma página da web ou formulário em um aplicativo GUI.

Greg Burghardt
fonte