Entendendo o Model-View-Controller

Como tudo o mais na engenharia de software, parece que o conceito de Modelo-Visão-Controlador foi originalmente inventado pelo Smalltalk programadores.

Mais especificamente, ele foi inventado por um programador de Smalltalk, Trygve Reenskaug. Trygve mantém uma página que explica a história do MVC em suas próprias palavras. Ele chegou a essas definições em um artigo que publicou em 10 de dezembro de 1979:

  1. Modelos

    Os modelos representam o conhecimento. Um modelo pode ser um único objeto (pouco interessante) ou pode ser uma estrutura de objetos.

    Deve haver uma correspondência de um para um entre o modelo e suas partes, por um lado, e o mundo representado, conforme percebido pelo proprietário do modelo, por outro.

  2. Visualizações

    Uma visualização é uma representação (visual) de seu modelo. Normalmente, ela destacaria determinados atributos do modelo e suprimiria outros. Assim, ela atua como um filtro de apresentação.

    Uma visualização é anexada ao seu modelo (ou parte do modelo) e obtém os dados necessários para a apresentação a partir do modelo, fazendo perguntas. Ela também pode atualizar o modelo enviando as mensagens apropriadas. Todas essas perguntas e mensagens precisam estar na terminologia do modelo, portanto, a visualização precisa conhecer a semântica dos atributos do modelo que representa.

  3. Controladores

    Um controlador é o elo entre o usuário e o sistema. Ele fornece a entrada do usuário, organizando as exibições relevantes para que se apresentem em locais apropriados na tela. Ele fornece meios para a saída do usuário, apresentando-lhe menus ou outros meios de fornecer comandos e dados. O controlador recebe essa saída do usuário, converte-a em mensagens apropriadas e passa essas mensagens para uma ou mais exibições.

Pode parecer que estamos no território dos astronautas da arquitetura agora, mas o senhor vai me acompanhar. Os conceitos de MVC são um pouco abstratos, é verdade, mas é um padrão incrivelmente comum. Ele está literalmente ao redor do senhor. Na verdade, deixe-me trazê-lo de volta à Terra desta forma: o senhor está olhando para o MVC neste exato momento.

Modelo = HTML Ver = CSS Controlador = Navegador
MVC: HTML = Modelo MVC: CSS = View MVC: Navegador = Controlador

Essa trifeta onipresente representa o MVC quase perfeitamente.

  1. Modelo

    O HTML é o “esqueleto” do conteúdo básico. O texto que comunica informações ao leitor.

  2. Ver

    O CSS acrescenta estilo visual ao conteúdo. É a “pele” que usamos para dar corpo ao nosso esqueleto e dar-lhe uma aparência específica. Podemos trocar diferentes skins por meio do CSS sem alterar o conteúdo original de forma alguma. Elas são relativamente, mas não completamente, independentes.

  3. Controlador

    O navegador é responsável por combinar e renderizar o CSS e o HTML em um conjunto de pixels finais e manipuláveis na tela. Ele reúne as entradas do usuário e as transfere para qualquer código JavaScript necessário para o funcionamento da página. Mas aqui também temos flexibilidade: podemos conectar um navegador diferente e obter resultados comparáveis. Alguns navegadores podem renderizá-la mais rapidamente, com mais fidelidade ou com mais recursos.

Portanto, se o senhor acredita que a Web foi bem-sucedida, a maioria dos sinais que vi apontam para sim — então o senhor também tem que reconhecer que o incrível poder do Model-View-Controller.

Não é coincidência que muitas das estruturas de programação da Web mais populares também encapsulam os princípios do MVC: Django, Ruby on Rails, CakePHP, Struts e assim por diante. Ele também está se infiltrando oficialmente no ASP.NET com o incipiente projeto ASP.NET MVC.

Basta dar uma olhada no layout do projeto em um exemplo de projeto ASP.NET MVC:

Organização do projeto ASP.NET MVC

É o quase autoexplicativo, caso o senhor já tenha criado um aplicativo de qualquer tipo:

  1. Modelo

    As classes que são usadas para armazenar e manipular o estado, normalmente em um banco de dados de algum tipo.

  2. Exibir

    Os bits da interface do usuário (neste caso, HTML) necessários para renderizar o modelo para o usuário.

  3. Controlador

    O cérebro do aplicativo. O controlador decide qual foi a entrada do usuário, como o modelo precisa ser alterado como resultado dessa entrada e qual visualização resultante deve ser usada.

É lindo em sua simplicidade, como observa Terence Parr:

Para o “MVC” de um aplicativo da Web, faço uma analogia direta com a noção de MVC do Smalltalk. O modelo é toda a lógica, o banco de dados ou os dados em si. A visualização é simplesmente como o senhor organiza os dados, como eles são exibidos. Se o senhor quiser um subconjunto de alguns dados, por exemplo, minha opinião é que essa é uma responsabilidade do modelo. O modelo sabe como criar um subconjunto. O senhor não deve pedir ao designer gráfico que filtre uma lista de acordo com a idade ou algum outro critério.

O controlador em um aplicativo Web é um pouco mais complicado, pois tem duas partes. A primeira parte é o servidor da Web (como um contêiner de servlet) que mapeia as solicitações de URL HTTP recebidas para um manipulador específico para essa solicitação. A segunda parte são os próprios manipuladores, que, na verdade, costumam ser chamados de “controladores”. Portanto, o C em um aplicativo Web MVC inclui o servidor Web “overlord” que roteia as solicitações para os manipuladores e a lógica desses próprios manipuladores, que extraem os dados do banco de dados e os enviam para o modelo. Esse controlador também recebe solicitações HTTP POST e as processa, às vezes atualizando o banco de dados.

Eu vejo um site apenas como um gráfico com bordas com POSTs e GETs que direcionam as páginas.

Esta é uma maneira rápida de testar se seu aplicativo se separou adequadamente entre as funções de modelo, visualização e controlador: seu aplicativo é skinnable?

Minha experiência é que os designers não entendem de loops ou de qualquer tipo de estado. Eles entendem de modelos com buracos. Todos entendem de mala direta. E se o senhor disser: “Aplique o modelo em negrito a este buraco”, eles também entenderão. Portanto, a separação entre modelo e visualização aborda esse problema prático muito importante de como fazer com que os designers trabalhem com os programadores.

O outro problema é que não há como criar adequadamente várias skins de site se o senhor não tiver uma separação adequada das preocupações. Se o senhor estiver fazendo geração de código ou sites com diferentes skins, não há como criar corretamente uma nova skin simplesmente copiando e colando a skin antiga e alterando-a. Se o senhor tiver a visualização e a lógica juntas, ao fazer uma cópia da visualização, copiará também a lógica. Isso quebra uma de nossas principais regras como desenvolvedores: ter apenas um local para alterar qualquer coisa.

A skinnability atinge o cerne do padrão MVC. Se seu aplicativo não for “skinnable”, isso significa que o senhor provavelmente colocou o chocolate do modelo na manteiga de amendoim da visualização, por acidente. O senhor deve refatorar seu código de modo que somente o controlador seja responsável por consultar os dados do modelo por meio dos modelos relativamente estáticos representados pela visualização.

O poder e a simplicidade do MVC implementado corretamente são inegáveis. Mas a primeira etapa para aproveitar o MVC é entender por que ele funciona, tanto na Web quanto em seus próprios aplicativos.