MVC: meu controlador parece inútil metade do tempo. Isso é um problema?

9

Frequentemente, quando eu desenho um programa com MVC, o controlador é inútil na metade do tempo.

O que quero dizer é o seguinte: algo acontece na visualização (por exemplo, um clique no botão). A vista então notifica o controlador. O controlador delega diretamente ao modelo e não faz mais nada porque não tem nada a fazer.

Por exemplo:

O usuário pressiona o botão 'Cor azul'> a visualização informa ao controlador controller.colorBlue()> o controlador informa o modelo model.colorBlue()> o modelo colore algo azul.

Neste exemplo, o controlador parece inútil. Não acrescenta nada. A visão também poderia ter falado diretamente com o modelo.

Na outra metade do tempo, no entanto, o controlador faz algum tipo de mediação entre a visualização e o modelo.

Minha pergunta é a seguinte: quão comum isso é nas estruturas MVC? É razoável que metade do tempo meu controlador pareça desnecessário? Ou isso é um problema? Isso é comum? Como devo abordar isso?

Se minha pergunta não estiver clara o suficiente, diga-o.

Aviv Cohn
fonte
1
como sugerido por RobertHarvey, porém, para este exemplo em particular, pode ser melhor se controller.colorBlue()realmente chamar model.setColor(0, 0, 255);. Um motivo para a separação entre Model e View é que geralmente há vários elementos da interface do usuário para representar um único estado no modelo (por exemplo, um item é verificado no menu, a barra de ferramentas é pressionada e o ponteiro é alterado para um preenchimento icon all corresponde ao campo de ferramentas atualmente selecionado no modelo), com a separação do MVC, o modelo não precisaria se preocupar em sincronizar os diferentes elementos da interface do usuário.
Lie Ryan

Respostas:

12

Você está subestimando a importância de ter uma camada de abstração entre a interface do usuário e o modelo. O controlador cumpre essa função 100% do tempo.

Seu exemplo model.colorBlue()é um pouco ilusório. Em um modelo real, isso provavelmente seria um método CRUD. Portanto, seu botão pode ser um botão Criar Cliente, seu método de controlador CreateCustomer()e seu Modelo CreateCustomer(). Claro, você está apenas passando a ligação.

Mas e se você precisasse mudar a maneira como o modelo funciona? Se o seu View estava chamando seu modelo diretamente, seu aplicativo será interrompido se você alterar o modelo. Os métodos do controlador fornecem um "ponto de acesso" para o seu View; você pode fazer uma modificação simples no método do controlador, talvez alterando a chamada Model para CreateCustomerWithVerification(), e tudo ainda funcione.

O mesmo raciocínio se aplica a ter uma Camada de Serviço. Em vez de simplesmente ter métodos CRUD em seu modelo, você deve ter ações de negócios. Dessa forma, você mantém a lógica comercial fora de seus controladores e possibilita o uso do Modelo em outro lugar, talvez em um aplicativo WPF.

Pense no controlador como um "pátio de manobra". Deve ser um intermediário, solicitações de mediação entre sua interface do usuário e seu modelo, mas os métodos do controlador devem ter a menor lógica possível.

Robert Harvey
fonte
Deixe-me ver se entendi o que você está dizendo. Você está dizendo que, mesmo que o controlador simplesmente delegue diretamente para o modelo, ainda é bom ter um entre a visualização e o modelo por causa disso: se o modelo mudar, todos os objetos que chamam de métodos podem ter que mudar. Se a visualização for a que chama métodos no modelo, ela terá que mudar. Se o controlador chamar os métodos, ele também terá que mudar. Mas a diferença é que a exibição é responsável por exibir a interface do usuário - uma parte importante do aplicativo. Única responsabilidade do controlador, no entanto, é exatamente isso - comunicar [..]
Aviv Cohn
com o modelo. E, por causa disso, é melhor alterar o controlador quando o modelo mudar (e deixar a visualização da mesma), depois alterar a visualização.
Aviv Cohn
3
Sim, isso é exatamente correto. A separação fornecida pela camada Controller permite alterações no modelo sem interromper a interface do usuário ou o roteamento.
Robert Harvey
Eu vejo. E só para ter certeza: é melhor mudar o controlador do que a vista quando o modelo muda, porque a vista é responsável por uma lógica importante - a exibição da interface do usuário. Mudá-lo teoricamente coloca todos os outros códigos em risco. No entanto, o único objetivo do controlador é exatamente isso, comunicar as coisas ao modelo e, portanto, depender do modelo - para que a visualização não precise. E como o controlador não inclui nenhuma outra lógica importante, é melhor que o controlador mude quando o modelo, do que a visualização que precisa ser alterada. Isso é preciso?
Aviv Cohn
Sim, essencialmente. Ao isolar essas alterações na superfície da API do Modelo e nos métodos do controlador, você fornece melhor dissociação da interface do usuário. O View nunca deve ter que mudar como resultado de uma alteração que ocorra na lógica de negócios, a menos que o View também precise refletir as mudanças na maneira como os negócios operam. Em outras palavras, a View deve ter o mínimo de conhecimento possível dos objetos Model; é por isso que temos coisas como ViewModels (que fornecem dissociação adicional do modelo).
Robert Harvey
-1

Ao codificar, você pode pensar desta maneira:

  • Poderei mudar a visualização para outra coisa (console, serviço) ou o mesmo controlador para uma visualização diferente?
  • Poderei alterar o modelo para lidar com bancos de dados diferentes ou gravar em algum serviço externo?

No seu caso, parece que você está colocando a lógica de domínio no modelo e isso causaria problemas se você quiser alterá-la: você terá que copiar métodos como "model.colorBlue" para o novo modelo.

E o que aconteceria se a definição de "azul" mudar? Você terá que mudar 2 modelos. Também no controlador, você não deve escrever diretamente no seu banco de dados, mas como Lie Ryan apontou, você deve usar model.setColor.

Mesmo com vistas. Se você começar a colocar a lógica ou a validação em exibição, se desejar alterar a exibição, precisará copiar toda essa funcionalidade.

Mantas Karanauskas
fonte