Em uma arquitetura MVC, quão bem acoplados são o Modelo e a Visualização para o Controlador?

15

Eu tenho um aplicativo que usa MVC, mas estou lutando um pouco sobre como o controlador deve ser arquitetado. Por exemplo, a Visualização está vendo apenas alguns subconjuntos dos dados do modelo de uma só vez. No entanto, não tenho certeza de como isso deve ser organizado. É normal que a View ou Model chame diretamente funções no Controlador, por exemplo? Através de algum tipo de interface? Ou eles são totalmente encapsulados e nunca conhecem o Controlador ou um ao outro?

Apenas como uma edição; este é um aplicativo personalizado que não está escrito em nenhuma estrutura da web, portanto, não estou procurando detalhes específicos do framework aqui e tenho a liberdade de fazer minha própria escolha.

    
por DeadMG 12.05.2012 / 22:04
fonte

7 respostas

14

O controlador controla o fluxo de atividade. O usuário executa essa ação, o controlador passa os dados da visualização para o domínio que faz o que precisa fazer, com base na (s) resposta (s), o controlador informa à estrutura qual visualização deve ser mostrada a seguir (e fornece dados suficientes para fazer assim).

O controlador deve, portanto, ser acoplado ao modelo de domínio, até certo ponto. ie. Você poderia colocar uma camada de serviço entre, mas, por definição estrita, que se tornasse parte do domínio.

Ele também é acoplado aos dados da visualização, mas não à visão em si. ie. simplesmente diz "mostre a visão do cliente usando esse detalhe do cliente". A estrutura então decide onde deve encontrar essa visão.

Agora, isso deve permitir que você desvincule o modelo de domínio da exibição, usando um modelo de exibição dos mesmos dados. Alguns desenvolvedores fazem isso, outros não, e eu acho que é basicamente uma questão de preferência pessoal.

No Rails, você é muito encorajado a empurrar os objetos de domínio (ActiveRecord) para a view e confiar que a view não tira proveito desse acesso (por exemplo, você não deve chamar customer.save da view, mesmo estando disponível).

No mundo do .NET, nós tendemos a reduzir o risco por não permitir que coisas não aconteçam e, possivelmente por essa razão, parece-me que o modelo de visualização desanexada é mais popular.

    
por 13.05.2012 / 00:09
fonte
7

Nota: Robert C. Martin (tio Bob) explica isso de uma maneira muito melhor e bem-humorada em seu discurso, Arquitetura dos Anos Perdidos . Um pouco longo, mas ensina muitos bons conceitos.

tl: dr: não pense e planeje seu aplicativo em termos de MVC. O framework MVC é apenas um detalhe de implementação.

A coisa mais confusa sobre o MVC é que os desenvolvedores tentam usar todos os componentes colados juntos.

Tente pensar nos termos de um programa, não nos termos do framework.

Seu programa tem um propósito. Ele pega alguns dados, faz coisas com dados e retorna alguns dados.

Dessa forma, o controller é o mecanismo de entrega do seu programa.

  1. Um usuário envia uma solicitação ao seu programa (digamos, adicione um produto ao carrinho de compras).
  2. O controlador aceita essa solicitação (informações do produto e informações do usuário), chama a parte necessária do programa que manipulará essa solicitação $user->addToCart($product)
  3. Seu programa ( addToCart function do objeto user neste caso) faz o trabalho que pretende fazer e retorna uma resposta (digamos success )
  4. O controlador prepara a resposta usando o% relevante% co_de: por exemplo. no objeto do controlador view

Desta forma, os controladores são desacoplados do programa e usados como mecanismo de entrega. Eles não sabem como seu programa funciona, eles apenas sabem qual parte do programa precisa ser chamada para as solicitações.

Se você quiser usar outra estrutura, seu aplicativo não precisará de uma alteração. Você só precisará gravar os controladores relevantes para chamar seu programa para solicitações.

Ou se você quiser criar uma versão para computador, seu aplicativo permanecerá o mesmo, você só precisará preparar um mecanismo de entrega.

e o $this->render($cartView('success') . Pense nisso como um mecanismo de persistência.

No modo OO, existem objetos em seu programa que contêm os dados.

class User {
    //...
    private $id;
    private $shoppingCart;
    //...
}

class Product {
    //...
    private $id;
    //...
}

Quando você adiciona um produto ao carrinho de compras, pode adicionar o Model ao product::id .

E quando você quiser persistir os dados, você pode usar a parte user::shoppingCart da estrutura, que geralmente consiste em usar um ORM, para mapear as classes para as tabelas do banco de dados.

Se você quiser alterar o ORM que você usa, seu programa permanecerá o mesmo, somente as informações de mapeamento serão alteradas. Ou, se você quiser evitar todos os bancos de dados juntos, basta gravar os dados em arquivos de texto simples e seu aplicativo permanecerá o mesmo.

Então, escreva seu programa primeiro. Se você estiver programando com o modo 'OO', use objetos antigos da linguagem. Não pense em termos de MVC no começo.

    
por 13.05.2012 / 15:17
fonte
2

Martin Fowler faz um bom trabalho ao descrever o paradigma MVC. Aqui está um link para o artigo dele sobre o link

Observe sua citação sobre Apresentação Separada "A idéia por trás da Apresentação Separada é fazer uma divisão clara entre objetos de domínio que modelam nossa percepção do mundo real e objetos de apresentação que são os elementos da GUI que vemos na tela."

    
por 12.05.2012 / 22:20
fonte
1

Aqui está um exemplo simples de como o MVC pode ser usado em um aplicativo Java Swing típico ...

Digamos que você tenha um painel contendo um botão e um campo de texto. Quando o botão é pressionado, um evento é disparado, levando a alguma alteração de estado no aplicativo. Depois que a alteração de estado é registrada, o TextField fica desativado.

Esta, então, seria a abordagem típica adotada por um aplicativo MVC simples ...

O Controller se registra como o ouvinte dos eventos da View. Quando o botão é clicado, a exibição em si não manipula o evento; o controlador faz. O Controlador é Swing específico, pois deve lidar com eventos relacionados ao Swing.

O controlador recebe esta notificação e deve decidir quem deve lidar com ela (a visão ou o modelo). Como esse evento alterará o estado do aplicativo, ele decide encaminhar as informações ao Modelo responsável pela lógica de dados e programas. Alguns cometem o erro de colocar a lógica do programa no Controlador, mas na OOP, os Modelos representam os dados e o comportamento. Leia Martin Fowler em sua opinião sobre isso.

A mensagem é recebida pelo modelo no contexto adequado. Isto é, é completamente nulo de qualquer referência ao Swing ou qualquer outra referência específica da GUI. Esta mensagem fala ao modelo e SOMENTE o modelo. Se você estiver importando instruções javax.swing no Modelo, você não está codificando o Modelo corretamente.

O Modelo define seu estado como 'desativado' e passa a notificar todas as partes interessadas sobre essa mudança de modelo. A View, interessada neste evento, já se registrou como Observador de qualquer mudança de modelo. Uma vez que o evento de mudança de estado do modelo é escolhido pela visão, ele continua a desativar seu TextField. Também é legal para a View obter informações somente leitura diretamente de seu Modelo sem ter que passar pelo Controlador (geralmente através de uma interface específica exposta pelo Modelo para tal atividade)

Ao promover esse acoplamento flexível entre a apresentação e a lógica de negócios e as camadas de dados, você verá que seu código é muito mais sustentável. À medida que os sistemas crescem, também a sua abordagem ao MVC. Por exemplo, o Hierarchical MVC é uma extensão geralmente usada para vincular as tríades do MVC para formar grandes sistemas corporativos sem acoplar subsistemas juntos

    
por 05.08.2013 / 07:10
fonte
0

Acoplamento (o tipo que você deseja evitar) envolve uma dependência mútua entre duas classes. Isto é, um Foo depende de um Bar e um Bar depende de um Foo para que você não possa realmente modificar um sem modificar o outro. Isso é ruim.

Você não pode realmente evitar ter algumas dependências, no entanto. As turmas precisam saber um pouco sobre as outras, caso contrário elas nunca se comunicam.

No padrão MVC, o Controlador controla a comunicação entre o Modelo do domínio e a Visualização da apresentação. Como tal, o Controlador deve saber o suficiente sobre o Modelo para pedir que ele faça o que deve fazer. O Controlador também deve saber o suficiente sobre o View para poder apresentá-lo ao cliente ou usuários. Portanto, o Controlador Model tem dependências de ambos. No entanto, a View pode existir perfeitamente sem o Controller - não existe dependência. Da mesma forma, o Model não possui depencies no controlador - simplesmente é o que é. Finalmente, o modelo e a visualização são completamente separados um do outro.

Essencialmente, o Controlador é o nível de indireção que separa a Visualização do Modelo, de modo que eles não precisam saber um do outro.

    
por 13.05.2012 / 00:25
fonte
-5

Na minha experiência, geralmente o modelo só depende de uma vista, não de um específico, muitas vezes como um observador ... se tem algum tipo de acoplamento.

A visão geralmente se encaixa no que está olhando, o que faz sentido. Difícil chegar a uma visão que poderia ser dissociada do que está vendo ... mas às vezes você pode ter um acoplamento parcial ou algo assim.

O controlador geralmente tende a se acoplar a ambos. Isso também faz algum sentido, já que o trabalho é transformar os eventos de visualização em alterações no modelo.

Naturalmente, esta é apenas uma tendência que observei e não diz nada sobre um exemplo específico.

Para entender o que é o MVC e qual é o relacionamento de acoplamento, você deve verificar como o MVC surgiu. O ambiente no qual o MVC foi criado era aquele no qual "widgets" como elementos de formulário com os quais você pode criar diálogos não existiam. Uma "visão" era uma caixa e ela desenhava coisas. Uma exibição de texto seria uma caixa que desenharia texto. Uma exibição de lista era uma caixa que desenhava uma lista. O "controlador" recebeu todos os eventos de mouse e teclado do sistema de interface do usuário que ocorreram nessa visualização; não houve eventos "textChanged" ou "selectionChanged". O controlador tomaria todos esses eventos de baixo nível e geraria interação com o modelo. O modelo, ao ser alterado, notificaria seus pontos de vista; desde então, vemos essa relação como "observador" e ela é usada de outras maneiras como um padrão próprio.

Essa é a essência do padrão MVC. Como esse tipo de programação de interface de usuário de baixo nível geralmente não é mais feito, o MVC evoluiu em muitas direções diferentes. Algumas coisas que passam por esse nome hoje são quase nada como o MVC e devem ser chamadas de outra coisa. Ele ainda pode ser usado no sentido de um diálogo como um todo interagindo com um objeto maior. Há muitas alternativas melhores.

Basicamente, tudo que o MVC deveria resolver acontece dentro dos widgets agora e é algo que não precisamos mais usar.

Para aqueles que acham que sabem mais:

link

link

Tenho certeza de que há mais, mas esses são apenas o topo da lista no google. Como você pode ver, o modelo depende muito de uma interface de visualização em MUITAS implementações. Geralmente, um modelo é observável e a visão é um observador.

Mas por que os fatos atrapalham ...

Um artigo já publicado em outra resposta também suporta minhas afirmações:

link

Se as pessoas quiserem continuar dizendo que TODOS na indústria do design estão errados, tudo bem.

    
por 13.05.2012 / 00:45
fonte
-7
  • O controlador despacha o modelo para uma visão e processa o modelo enviado das visualizações, mas não está strongmente acoplado a uma visão ou modelo.

Se o controlador foi strongmente acoplado a uma visão, então estaremos em um mundo de formulários da web. Você teria um código por trás que seria vinculado a um arquivo de modelo (Aplicável a formulários da Web do ASP.NET)

Por causa disso, o controlador não está acoplado a um modelo ou a uma visualização. É apenas um mecanismo para processar solicitações e enviar respostas.

  • A visualização é strongmente acoplada a um modelo. Faça alterações em seu modelo (por exemplo, altere sua propriedade) e você terá que fazer alterações em sua visualização.

  • O modelo não está bem acoplado a uma exibição. Faça alterações em uma visualização e isso não afetará o modelo.

  • O modelo não sabe nada sobre o controlador ou exibições onde ele pode ser usado. Portanto, o modelo não está strongmente acoplado a uma visão ou controlador.

Outra maneira de pensar sobre isso:

  • Faça alterações em um controlador - a visualização e o modelo não serão afetados

  • Faça alterações em um modelo - a visualização será interrompida porque depende de um modelo

  • Faça alterações em uma visão - o modelo e o controlador não serão afetados

Esse acoplamento solto em projetos MVC é o que os torna fáceis para testes unitários.

    
por 13.05.2012 / 15:38
fonte

Tags