O 'C' no MVC é realmente necessário?

37

Eu entendo o papel do modelo e da visualização no padrão Model-View-Controller, mas não consigo entender por que um controlador é necessário.

Vamos supor que estamos criando um programa de xadrez usando uma abordagem MVC; o estado do jogo deve ser o modelo e a GUI deve ser a visualização. O que exatamente é o controlador neste caso?

É apenas uma classe separada que tem todas as funções que serão chamadas quando você clica em um bloco? Por que não apenas executar toda a lógica no modelo na própria exibição?

    
por Anne Nonimus 28.03.2012 / 00:27
fonte

11 respostas

4

Usando o seu exemplo, o controlador seria o que decidia o que era um movimento legal ou não. O Controlador deixava a visão saber como organizar as peças no quadro ao iniciar usando as informações recebidas do Modelo. Há mais coisas que podem ser manipuladas pelo Controlador, mas a chave é pensar na Business Logic nessa camada.

Há momentos em que tudo que o Controlador faz é passar informações de um lado para o outro, como uma página de inscrição. Outras vezes, o Controlador é a parte difícil do desenvolvimento, porque há muitas coisas que precisam ser feitas nessa camada, como impor regras ou fazer matemática complicada, por exemplo. Não esqueça o controlador!

    
por 28.03.2012 / 00:46
fonte
39

Why not just perform all the logic on the model in the view itself?

O controlador é a cola que liga o modelo e a visualização em conjunto e também é o isolamento que os separa. O modelo não deve saber nada sobre a exibição e vice-versa (pelo menos na versão da Apple do MVC). O controlador age como um adaptador bidirecional, traduzindo as ações do usuário da exibição em mensagens para o modelo e configurando a exibição com dados do modelo.

Usar o controlador para separar o modelo e a visualização torna seu código mais reutilizável, mais testável e mais flexível. Considere o seu exemplo de xadrez. O modelo naturalmente incluiria o estado do jogo, mas também poderia conter a lógica que afeta as mudanças no estado do jogo, como determinar se um lance é legal e decidir quando o jogo termina. A visão exibe um tabuleiro de xadrez e peças e envia mensagens quando uma peça se move, mas não sabe nada sobre o significado por trás das peças, como cada peça se move, etc. O controlador conhece tanto o modelo quanto a visão, bem como o fluxo global do programa. Quando o usuário clica no botão 'novo jogo', é um controlador que diz ao modelo para criar um jogo e usa o estado do novo jogo para configurar o tabuleiro. Se o usuário fizer um movimento, o controlador retransmite o comando para o modelo e, com base na resposta, permite a movimentação ou não.

Veja o que você obtém mantendo o modelo e a visualização separados:

  • Você pode alterar o modelo ou a exibição sem alterar o outro. Talvez seja necessário atualizar o controlador quando você alterar qualquer um deles, mas de certa forma isso é parte da vantagem: as partes do programa que têm maior probabilidade de serem alteradas estão concentradas no controlador.

  • O modelo e a visualização podem ser reutilizados. Por exemplo, você poderia usar a mesma visão do tabuleiro de xadrez com um feed RSS como modelo para ilustrar jogos famosos. Ou você poderia usar o mesmo modelo e substituir a exibição por uma interface baseada na Web.

  • É fácil escrever testes para o modelo e a visualização para garantir que funcionem como deveriam.

  • O modelo e a visualização geralmente podem aproveitar as peças padrão: matrizes, mapas, conjuntos, seqüências de caracteres e outros contêineres de dados para o modelo; botões, controles, campos de texto, visualizações de imagens, tabelas e outros para a exibição.

por 28.03.2012 / 05:11
fonte
7

Existem muitas, muitas maneiras diferentes de implementar esse padrão geral de design, mas a idéia básica é separar as várias preocupações conforme necessário. O MVC é uma boa abstração no sentido de que:

Modelo : Representa os dados, o que quer que isso signifique
Visualizar : Representa a interface do usuário, o que quer que isso signifique
Controlador : Representa a cola que faz com que esse modelo e visualização interajam, o que quer que isso signifique

É extremamente flexível porque não especifica muito. Muitas pessoas desperdiçam muita largura de banda argumentando os detalhes do que cada elemento pode significar, que nomes devem ser usados em vez destes, e se realmente deve haver 3 ou 2 ou 4 ou 5 componentes, mas isso não faz sentido. certo grau.

A ideia é separar os diferentes "pedaços" da lógica para que eles não se sobreponham. Mantenha seu material de apresentação junto, mantenha seu material de dados junto, mantenha seu material de lógica junto, mantenha seu material de comunicação junto. E assim por diante. Até certo ponto, quanto menos essas áreas de preocupação se sobrepõem, mais fácil é fazer coisas interessantes com elas.

Isso é tudo o que você realmente deveria se preocupar.

    
por 28.03.2012 / 06:56
fonte
4

Todas as boas respostas até agora. Meus dois centavos é que eu gosto de pensar no controlador como sendo basicamente construído com perguntas como What e where?

  • Fui perguntado se uma peça de xadrez (vista) pode ser movida para x. É o que você permitido? Não tenho certeza, mas sei onde e quem perguntar (o modelo).
  • Algo me pediu para salvar meus dados. Como diabos eu faço isso? Eu sei onde perguntar embora! Como salvamos os dados ou para onde são salvos Eu não tenho ideia, mas essa classe Repository deve saber. Vou encaminhá-lo e deixá-lo lidar com isso.
  • Eu tenho que mostrar a atual posição da peça de xadrez para o usuário que o modelo mudou para. não tenho certeza se quero mostrar a peça como verde ou amarelo? Bah, quem se importa, eu sei que há uma visão que pode lidar isso, então eu vou passar em os dados e eles podem decidir como vai ser showen.

Esses pequenos trechos são exemplos de como estou tentando lembrar a abstração e o conceito que o MVC está tentando transmitir. O que, onde e como são meus três principais processos de pensamento.

O que e onde = > Controlador Como e quando = > Modelos e visualizações

Em essência, minhas ações de controle tendem a ser pequenas e compactas e, ao lê-las, tendem a parecer às vezes uma perda de tempo. Em uma inspeção mais próxima, eles estão agindo como o homem do sinal de trânsito, canalizando os vários pedidos para os trabalhadores apropriados, mas não fazendo nenhum dos trabalhos propriamente ditos.

    
por 28.03.2012 / 09:28
fonte
2

Um Controller pode ajudar a abstrair as interfaces da View e do Model para que elas não precisem se conhecer diretamente. Quanto menos um objeto precisa saber, mais portátil e testável se torna.

Por exemplo, o Model poderia estar tocando outra instância de si mesmo através de um Controller. Ou um Controlador em rede poderia conectar os objetos Views de dois players juntos. Ou pode ser um teste de Turing onde ninguém sabe qual.

    
por 28.03.2012 / 04:54
fonte
2

Ele realmente entra em jogo quando você está lidando com manipuladores de eventos, mas ainda precisa do controlador para lidar com as interações entre a visualização e o modelo. Idealmente, você não quer que a visão saiba nada sobre o modelo. Pense nisso, você quer um jsp para fazer todas as chamadas de banco de dados diretamente? (A menos que seja algo como uma pesquisa de login.) Você deseja que a visualização renderize dados e não tenha nenhuma lógica de negócios, a menos que seja lógica de renderização de visualização, mas não lógica de negócios perse.

No GWT, você obtém uma separação mais clara com o MVP. Não há lógica comercial (se for feita corretamente) na exibição. O apresentador age como um controlador e a visualização não tem conhecimento do modelo. Dados do modelo são simplesmente passados para a vista.

    
por 28.03.2012 / 00:38
fonte
1

Document-View (ou seja, visualização de modelo) é o modelo padrão para a maioria dos aplicativos do Windows escritos no MFC, portanto, ele deve funcionar para muitos casos.

    
por 23.08.2012 / 01:38
fonte
1

I understand the role of the model and view in the Model-View-Controller pattern, but I have a hard time understanding why a controller is necessary.

Você tem certeza disso? (Pelo menos como originalmente descrito) O ponto do modelo é ser o modelo de domínio. A exibição deve exibir o modelo de domínio para o usuário. O controlador deve mapear a entrada de baixo nível para o modelo de alto nível. Tanto quanto eu posso dizer o raciocínio é algo ao longo das linhas de: A) um uso de alto nível do SRP. B) O modelo foi considerado a parte importante do aplicativo, portanto, mantenha a mudança sem importância e mais rápida. C) lógica de negócios facilmente testável (e capaz de gerar scripts).

Pense apenas se você quiser tornar seu programa de xadrez utilizável pelos cegos, trocar a exibição por uma versão audível e um controlador que funcione com o teclado. Digamos que você queira adicionar jogos por email, adicione um controlador que aceite texto. Versão net do jogo? Um controlador que aceita comandos de um soquete faria o trabalho. Adicione um bom 3d render para ele, uma nova visão legal. Mudanças no modelo zero necessárias Xadrez ainda é xadrez.

Se você misturar a entrada com a representação do modelo, perderá essa habilidade. De repente, Xadrez não é Xadrez, é Xadrez com um mouse que é diferente do Xadrez com um teclado ou conexão de rede.

    
por 23.08.2012 / 17:37
fonte
0

Eu acho que MVC é burro, talvez em áreas específicas funcione bem, mas pessoalmente, mesmo os sites que escrevo não são adequados para o mvc. Há uma razão pela qual você ouve frontend, backend e nunca database-end ou something-else-end

IMO deve haver uma API (backend) e o aplicativo que usa a API (frontend). Eu acho que você poderia chamar o comando GET de controller (que simplesmente chama o backend api) e o html de view, mas eu não costumo ouvir as pessoas falando sobre o view como puro html nem o model sendo backend API.

IMO tudo deve ser uma API sólida. Na verdade, eles não precisam ser sólidos (como limpos e bem construídos), mas seus internos devem permanecer privados e o app / frontend / outside da API nunca deve informar a conexão com o banco de dados nem fazer consultas brutas.

Agora, se o seu código / design envolve cola, tudo bem. Se em seu jogo de xadrez houver alguma marcação que você pode editar para eliminar a GUI, o gui coleta as coordenadas / entradas e chama MovePiece (srcPosition, dstPostion) (que pode retornar um bool ou enum para dizer se é um movimento válido ou não ) e seu ok com toda a lógica estando no modelo, então, é certo chamá-lo de MVC. No entanto, eu ainda organizaria as coisas por classes e APIs e me certificaria de que não houvesse uma classe de pia de cozinha que tomasse tudo (nem APIs para saber sobre tudo).

    
por 23.08.2012 / 04:31
fonte
0

Pense em um navegador que exibe uma página da Web estática. O modelo é o HTML. A visualização é o resultado real na tela.

Agora adicione um pouco de JavaScript. Esse é o controlador. Quando o usuário clica em um botão ou arrasta algo, o Evento é enviado para o JavaScript, ele decide o que fazer e altera o HTML subjacente (Modelo) e o navegador / renderizador exibe essas alterações na tela (Visualizar).

Talvez seja clicado outro botão, o evento é enviado para algum manipulador (Controlador) e isso pode fazer com que uma solicitação de dados adicionais seja enviada para um serviço da web. O resultado é então adicionado ao HTML (Modelo).

O Controlador responde a eventos e controla o que está no Modelo e, portanto, o que está na tela / Visualizar.

Recuando um pouco, você pode pensar em todo o navegador como o View e o servidor como o Controller e os dados como o Model. Quando o usuário clica em um botão no navegador do evento que enviou para o servidor (Controller), reúne recursos como uma página HTML (Model) e os envia de volta para o browser a ser exibido (View)

No servidor, seja asp, php ou java, o 'código' (Controlador) recebe o evento click e consulta um banco de dados ou repositório de documentos (Model) e cria HTML. Do ponto de vista do servidor, o resultado de todas as suas ações é uma Visualização (HTML) de seu armazenamento de dados subjacente (Modelo). Mas do ponto de vista do cliente o resultado do seu pedido para o servidor é o seu modelo (HTML)

Mesmo se você misturar seu JavaScript em seu HTML ou seu PHP em seu HTML, o Model, View, Controller ainda existe. Mesmo se você pensar em sua solicitação para um servidor e na resposta do servidor como uma via de mão dupla simples, ainda haverá um Modelo, uma Visualização e um Controlador.

    
por 24.03.2013 / 22:16
fonte
-2

Na minha experiência, em um programa de gui mvc de área de trabalho tradicional, o controlador é esparramado na exibição. A maioria das pessoas não dedica tempo para fatorar uma classe de controle.

o livro da gangue de quatro diz:

Design Patterns in Smalltalk MVC

The Model/View/Controller (MVC) triad of classes [KP88] is used to build user interfaces in Smalltalk-80. Looking at the design patterns inside MVC should help you see what we mean by the term "pattern."

MVC consists of three kinds of objects. The Model is the application object, the View is its screen presentation, and the Controller defines the way the user interface reacts to user input. Before MVC, user interface designs tended to lump these objects together. MVC decouples them to increase flexibility and reuse.

MVC decouples views and models by establishing a subscribe/notify protocol between them. A view must ensure that its appearance reflects the state of the model. Whenever the model's data changes, the model notifies views that depend on it. In response, each view gets an opportunity to update itself. This approach lets you attach multiple views to a model to provide different presentations. You can also create new views for a model without rewriting it.

The following diagram shows a model and three views. (We've left out the controllers for simplicity.) The model contains some data values, and the views defining a spreadsheet, histogram, and pie chart display these data in various ways. The model communicates with its views when its values change, and the views communicate with the model to access these values.

Taken at face value, this example reflects a design that decouples views from models. But the design is applicable to a more general problem: decoupling objects so that changes to one can affect any number of others without requiring the changed object to know details of the others. This more general design is described by the Observer (page 293) design pattern.

Another feature of MVC is that views can be nested. For example, a control panel of buttons might be implemented as a complex view containing nested button views. The user interface for an object inspector can consist of nested views that may be reused in a debugger. MVC supports nested views with the CompositeView class, a subclass of View. CompositeView objects act just like View objects; a composite view can be used wherever a view can be used, but it also contains and manages nested views.

Again, we could think of this as a design that lets us treat a composite view just like we treat one of its components. But the design is applicable to a more general problem, which occurs whenever we want to group objects and treat the group like an individual object. This more general design is described by the Composite (163) design pattern. It lets you create a class hierarchy in which some subclasses define primitive objects (e.g., Button) and other classes define composite objects (CompositeView) that assemble the primitives into more complex objects.

MVC also lets you change the way a view responds to user input without changing its visual presentation. You might want to change the way it responds to the keyboard, for example, or have it use a pop-up menu instead of command keys. MVC encapsulates the response mechanism in a Controller object. There is a class hierarchy of controllers, making it easy to create a new controller as a variation on an existing one.

A view uses an instance of a Controller subclass to implement a particular response strategy; to implement a different strategy, simply replace the instance with a different kind of controller. It's even possible to change a view's controller at run-time to let the view change the way it responds to user input. For example, a view can be disabled so that it doesn't accept input simply by giving it a controller that ignores input events.

The View-Controller relationship is an example of the Strategy (315) design pattern. A Strategy is an object that represents an algorithm. It's useful when you want to replace the algorithm either statically or dynamically, when you have a lot of variants of the algorithm, or when the algorithm has complex data structures that you want to encapsulate.

MVC uses other design patterns, such as Factory Method (107) to specify the default controller class for a view and Decorator (175) to add scrolling to a view. But the main relationships in MVC are given by the Observer, Composite, and Strategy design patterns.

    
por 24.03.2013 / 23:32
fonte