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.