Arquitetura MVC - Quantos controladores eu preciso?

54

Estou codificando há um tempo, mas principalmente scripts e aplicativos simples. Eu mudei para uma nova função, onde se trata de desenvolver aplicativos da Web e usar uma arquitetura MVC adequada, por isso estou tentando desesperadamente aprender tudo isso muito rapidamente.

Espero que essa pergunta não seja muito parecida com " Boas práticas para arquitetura MVC ", mas, enquanto estou passando por alguns tutoriais diferentes, notei que alguns têm vários controladores para coisas diferentes.

De quantos controladores um único aplicativo Web precisa?

Sei que seria difícil responder sem um exemplo, portanto fornecerei um:

Inscrição:

  1. Usuário faz login.
  2. O usuário pode fazer uma de três coisas:
    a) Carregar um arquivo (armazenado em um banco de dados mongodb com metadados).
    b) Procure um arquivo.
    c) Saia.

Minha pergunta é geral, mas dei o exemplo para ajudar qualquer um que tente responder.

Jeff
fonte
8
Uma pergunta muito bem feita.
precisa saber é o seguinte

Respostas:

34

Para o seu exemplo, eu criaria dois controladores:

  • Controlador de Sessões para Login e Logout (crie e destrua a sessão para o layout REST)
  • Controlador de arquivos para tudo nos arquivos (index = search e create = upload)

Em geral, uma abordagem RESTful, na qual você pensa em tudo como um recurso que pode ser exibido, criado, editado e destruído, fornece uma boa idéia de como estruturar as coisas. Como você pode ver nos meus exemplos, eu não fico muito perto de cada verbo no REST.

Você provavelmente precisará de mais controladores para obter mais funcionalidades. Por exemplo, um Controlador de usuários em que os usuários podem criar novas contas. Além disso, você precisaria de uma interface de administração na qual possa editar os recursos com privilégios mais altos. Nesse caso, é bastante comum ter quase todos os controladores duplicados.

Uma estimativa muito aproximada para obter uma idéia inicial pode ser um controlador para cada tabela em seu banco de dados que os usuários possam acessar. Mas esta é realmente apenas uma medida muito grosseira.

thorsten müller
fonte
3
Tomando o seu exemplo de administrador: o controlador de administração estenderia o usuário geral ou você redefiniria completamente todos os métodos? Por exemplo, talvez todos os usuários possam fazer upload e pesquisar, mas apenas os administradores podem excluir. A classe do controlador admin apenas herdaria todos os métodos gerais do usuário?
21813 Jeff Jeff
4
Isso realmente depende muito da funcionalidade real. Mas, em geral, eu simplesmente escrevo um segundo controlador sem nenhuma herança. Seguindo o princípio de 'controlador fino', não deve haver muito código em um controlador. E o controlador administrativo pode ser especialmente simples. Toda funcionalidade importante entra no modelo. (por exemplo, se a exclusão de um meio de usuários todos os seus arquivos também devem ser excluídos, em seguida, as alças modelo este, não há uma única linha para este no controlador)
Thorsten Müller
6

Realmente depende do aplicativo da web. No seu exemplo, um é provavelmente suficiente. Se você implementasse um aplicativo de comércio eletrônico completo com frete, impostos, gerenciamento de inventário, preços em camadas etc., talvez queira ter mais alguns.

Se o seu controlador sofre de um ou mais odores de código (especialmente Classe Grande ou Objeto Deus ), então você sabe que provavelmente já passou do ponto em que apenas um fará.

Dan Pichelman
fonte
5

Realmente depende das necessidades da sua aplicação e da arquitetura dos módulos de negócios.

Como regra geral , o número de controladores necessários depende de vários módulos e submódulos no aplicativo Web.

Como um complemento, seria útil organizar os controladores em Áreas . O conceito de Áreas é incorporado à estrutura do ASP.NET MVC e simplifica a organização dos controladores que atendem a um módulo.

Há várias discussões relacionadas:

EL Yusubov
fonte
11
Ótimas referências! Eu vou ter certeza de vê-los!
101313 Jeff Jeff
Claro, sem problemas.
EL Yusubov 13/08/2013
4

Eu gosto da maneira da Apple de fazer isso.

Toda visualização é controlada por apenas um controlador de visualização. ~ Ver Guia de programação do controlador para iOS

A ideia é que você possa trocar facilmente as Views. Na IMO, ao ter apenas 1 Controllerpor Viewisso, é mais fácil fazer isso. Mas tenho certeza de que você pode ter um controlador com várias visualizações e ainda projetá-lo para poder alternar as visualizações sem alterar a lógica do programa.

Korey Hinton
fonte
Esse é um bom ponto, mas você precisaria ter um controlador para todas as visualizações, além de outras para cuidar de coisas como usuários? Eu também acho que se meu projeto fosse maior, faria mais sentido ter mais controladores.
13133 Jeff
Os modelos devem acompanhar os usuários. Portanto, vários controladores podem usar o mesmo objeto de modelo, se necessário.
Korey Hinton
2
Portanto, um controlador possui um objeto Model e um objeto View. O Controlador solicita informações ao objeto Modelo (como Informações do Usuário) e define a Visualização adequadamente. O Modelo deve ter a maior parte da lógica do programa, enquanto o Controlador apenas possui a lógica para poder se comunicar entre a Vista e o Modelo.
Korey Hinton
2
Um controlador por visualização é um design muito limitado, pois seu controlador não seria capaz de exibir modelos de visualização diferentes, para diferentes estados do Modelo.
EL Yusubov 13/08/13
11
@ElYusubov Eu posso ver onde isso pode ser confuso. No iOS, cada visualização possui apenas um controlador de visualização e todo controlador de visualização possui apenas 1 visualização ativa (e essa visualização pode ter sub-visualizações), mas esse controlador de visualização também pode conter referências a qualquer número de visualizações.
Korey Hinton
2

Um exemplo que eu gosto é pensar em um termostato. Um termostato é um excelente visual para visualizar o padrão MVC.


Em um termostato analógico mais antigo, você pode imaginar coisas como estas:

Ver - O leitor de temperatura, que exibe a temperatura atual.

Controlador - o mostrador, onde você altera a temperatura

Modelo - As partes internas invocadas pelo controlador que causam alterações na temperatura.


Você deve sempre respeitar os projetos que permitem o acoplamento flexível e limitar os modelos e seus controladores associados a uma única tarefa , além de usar quantos módulos / controladores forem necessários . Dependendo do tamanho do seu aplicativo, você pode ter muito menos visualizações do que modelos e controladores. Isso é esperado em qualquer aplicativo de tamanho grande. A boa programação orientada a objetos é caracterizada por acoplamento frouxo, encapsulamento, herança e polimorfismo. Nem todos os idiomas suportam polimorfismo no mesmo grau (função, método, sobrecarga / substituição do operador).

Se você deseja entender melhor o uso correto da arquitetura MVC, consulte o GoF "Design Patterns: Elements of Reusable ... Software", que usa C ++ e SmallTalk, por exemplo, código. Este livro não é o alfa e o ômega, mas certamente é um começo!

Boa sorte!

Charles Addis
fonte
1

Suponho que seu exemplo evolua para um sistema complexo.

Inscrição:

Usuário efetua login:

  • LoginController

Sua única responsabilidade é manipular logins, redirecionar ou notificar o usuário sobre o resultado.

Enviar um arquivo

  • UploadController

Presumo aqui que você deseja fazer upload de qualquer tipo de arquivo. Se, posteriormente, você decidir fazer upload de MP3s e PDFs, eu teria um UploadController básico, um MP3UploadController e um PDFUploadController.

Procure um arquivo.

  • SearchFileController

Isso seria suficiente para um requisito básico. Você pode ter vários controladores de pesquisa posteriormente, dependendo da complexidade da lógica de pesquisa. A última coisa que você deseja é um único SearchController com 20 métodos de ação executando pesquisas diferentes.

Sair.

-LogoutController .

Pode-se considerar que isso é um exagero, mas acho que não. Eu acho que é limpo e bem separado.

Se eu visse essa estrutura do projeto, saberia instantaneamente o que ela faz e como está estruturada. Para dar um passo adiante, gostaria de colocar LoginControllere LogoutControllerem área separada.

Eu desenvolvi algo assim antes e funcionou muito bem.

CodeART
fonte
Obrigado pela contribuição! Tem algum código de trabalho? ficar preso em algumas coisas.
Jeff
Que problemas você está enfrentando?
CodeART 20/08/2013
Consigo fazer upload de um assunto e uma data (em formato de string), mas não consigo fazer upload do arquivo (consulte stackoverflow.com/questions/18344614/… ).
Jeff
Sou desenvolvedor .NET. Desculpe, não posso ajudá-lo.
CodeART
1

A maior parte do seu código estaria acontecendo em uma camada de negócios, certo? Se for esse o caso, tudo o que você realmente está fazendo no seu controlador é retornar dados para a visualização.

Não tenho certeza se sou fã de separar os controladores em subtipos. Enquanto você deve manter a separação de preocupações, acho que os subtipos estão indo longe demais. Além disso, você precisa ter cuidado nos casos em que objetos pesados ​​são inicializados no construtor ou em um controlador. Por exemplo: no seu exemplo, você deseja que um objeto pesado, usado apenas para a busca / upload de arquivo, seja liberado quando o usuário estiver na página de login.

É melhor ter um controlador por unidade lógica, por exemplo, AccountController (login, registro, logout), FileController (pesquisa, upload) e assim por diante.

harsha
fonte
0

Em geral, você pode dizer que todo modelo tem seus próprios CONTROLADORES e VISUALIZAÇÕES dedicadas. Ao dizer geral, quero dizer que esta é a melhor prática.

Aspectos do aplicativo (como gerenciamento de usuários) devem ser traduzidos para o serviço de aplicativo e precisam ser chamados pelo próprio controlador ou envolver o controlador (usando atributos que tornam a funcionalidade do controlador "visível" de acordo com a função de usuário solicitada, por exemplo).

Lembre-se de que todos os controladores devem lidar basicamente com operações CRUD sobre o modelo e usar visões diferentes para filtros diferentes.

Na minha opinião, uma das principais vantagens do MVC como padrão é que ele oferece a melhor maneira de vincular modelos e visualizações.

Sobre o exemplo que você adicionou: Eu criaria 2 controladores: um para a operação de login de todos os usuários (registro, login, logout etc.) e o segundo para operações de arquivo (Upload e pesquisa). observe que o primeiro também deve ter backup com algum aspecto relacionado à funcionalidade de login e o segundo é um controlador comum

Saturn Technologies
fonte
sem uma explicação, essa resposta pode se tornar inútil se outra pessoa postar uma opinião oposta. Por exemplo, se alguém postar uma declaração como "Gerenciando funções e autorização de usuário não deve estar no topo do controlador" , como essa resposta ajudaria o leitor a escolher duas opiniões opostas? Considere editar ing-lo em uma melhor forma
mosquito
11
@gnat Aceito o seu comentário, veja a resposta editada
Saturn Technologies