Desenvolvimento Web, Design, Design Patterns, Experiências

MVC não é sobre camadas!

– Como você separa as camadas do seu sistema?

– Ah… Sistema Web eu uso MVC mesmo.

Apesar de pouco tempo de carreira, já ouvi respostas como essas de tuia. Desenvolvedores graduados, mestrados, doutorados, verdadeiros alquimistas (note o tom irônico) argumentando que MVC é um padrão arquitetural onde você divide seu sistema em camadas, sendo elas: Model, View e Controller.  E, logo, se você utiliza MVC não há espaço para as camadas mais tradicionais: Apresentação, Negócios e Persistência. A verdade é que esse argumento é tão infundado quanto errôneo.  Apesar de achar essa confusão um tanto quanto natural (afinal eu já fiz essa confusão também), entendo porque ela existe. A sigla MVC tem sido “passada” para os aprendizes de desenvolvimento de software como… justamente, um sigla. Não é explicada a origem do padrão, nem a definição formal do que é, nem tampouco onde ela deve ser aplicada.  Enfim, não vou nem me delongar muito sobre o porquê da confusão, mas antes, pretendo esclarecê-la. Primeiro, vamos ver um pouco sobre a origem do MVC e sua definição.

O que danado é MVC ?


MVC é um padrão arquitetural originalmente criado em Smalltalk no fim da década de 70 que teve por objetivo inicial trazer simplicidade ao manipular interfaces  gráficas.  O que simbolizam essas letras?

M: Model. É o modelo de negócio da sua aplicação. Suas classes básicas, seus Services, o que quer que você utilize e seja particular do seu domínio. Seria o core da sua aplicação. Classes como Conta, Banco, classes de repositórios (não confundir com DAOs), classes de serviço, as exceções específicas do seu domínio e  classes utilitárias do domínio se encaixam no ‘M’ de Model, ou modelo.

V: View. É a parte responsável por mostrar visual para o usuário. O objetivo da View é mostrar o estado atual do seu modelo. É papel da View saber quando o modelo foi mudado (o modelo também pode notificar a view da mudança, apesar de eu não gostar desta versão), de forma que ela possa refletir isso de forma plena. Todos os componentes gráficos estão incluídos nessa categoria. E por componente eu não quero dizer classe, por exemplo, JSPs são views. Também arquivos html, javascript, swf, além de classes que tratam de interfaces gráficas – Actions da vida em ambiente web e TelaCadastro ou TelaLogin em ambientes Desktop etc.

C: Controller. É a parte mais inteligente desse padrão. É responsável por tomar a decisão “para quem devo direcionar, dado que o usuário propagou esse estímulo”. Por exemplo, uma classe ‘Controller’  recebe uma requisição do usuário e, baseada nessa requisição, decide qual view será mostrada para o usuário. Em ambientes Web essa classe faz o papel de “Front Controller”, que já é outro padrão arquitetural.

Já vi muito, mas muito mesmo, ocorrer a confusão entre Controllers e Controladores. Controller é completamente diferente de Controladores de objetos de domínio. Controladores são parte do domínio: realizam serviços utilizando classes básicas e suas dependências.  São Model. Controllers não devem fazer parte do seu domínio. Alguns colocam como View e em alguns casos utilizam como parte da camada de aplicação. Certa vez,  decidimos não utilizar esse nome confuso, mas o sufixo “Service” para nomear as classes que realizavam operações nas classes básicas. Mais tarde, um dos líderes técnicos disse que tinha uma observação a fazer. Ele incentivou a equipe a prezar por código de qualidade, porque no nosso sistema estávamos manipulando objetos de negócio diretamente na “Camada de View” sem passar pela “Camada do Controlador”. Um verdadeiro estupro. Claro que não o critiquei publicamente e não expus o comentário cheio de infelicidades, mas me limitei a esclarecer que os controladores estavam sim ali, apenas com sufixos diferentes. Também expliquei a diferença entre Controller e Controladores, e que aquilo estava causando confusão, de forma que todos ficaram satisfeitos.

MVC são apenas alguns patterns!

MVC na verdade tem por objetivo definir interações entre componentes do sistema e não agrupar componentes da aplicação, como muitos o entendem. Para entender isso, note que  MVC realmente é sobre design patterns (padrões de projeto). Mais especificamente – Strategy e Observer. Mais especificamente são 2 interações entre componentes:

1 – Quando o Model (Observable) muda seu estado, a View (um Observer) é notificada.

2 – Quando a View propaga alguma ação, como o Controller é o Strategy da View, a View delega ao Controller a decisão de “para que parte do Model notificar a mudança”. Esse Controller, por ser um Strategy, pode ser modificado em tempo de execução.

 

Interações são descritas por meio de Patterns.

Head First Design Patterns (Freeman & Freeman)

Estes são os 2 princípios fortes por trás do MVC. Alguns ainda dizem que existe um Composite limitado ao Model, mas isso é se prender demais a versão original do padrão feita em SmallTalk. Enfim, note que estas interações não dizem NADA a respeito de camadas. São interações ora essa! Ou seja, não é necessário você ter um componente View pra estar utilizando MVC, apesar de eu nunca ter visto isso acontecer na prática. Mas sim, você pode utilizar esse mesmo modelo de interações entre componentes de inúmeras formas diferentes, usando View ou não.  Também não é necessário estar usando Web pra utilizar MVC. De fato, originalmente MVC surgiu pra aplicações Desktop… Enfim, você pode sim utilizar o padrão MVC num sistema Desktop tipo um Swing do Java ou na sua aplicação Android ou Flash! Lembre-se, MVC é sobre interações entre componentes! Repita pra você mesmo: MVC não é sobre camadas! É sobre interações!


Tá, mas e a divisão por camadas que a minha avó me ensinou?


Camadas são utilizadas nas aplicações modernas para separar responsabilidades do sistema. Componentes com responsabilidades iguais ou similares ficam na mesma camada. Como já dito, numa aplicação Enterprise clássica por exemplo, temos Apresentação (componentes de interface gráfica), Negócios (classes básicas, services, helpers etc.) e Persistência. Imagine que essas camadas são empilhadas de forma que as que lidam com infra-estrutura estão na parte de baixo da pilha e as que lidam com interação com usuário estão mais acima. Nesse caso, teríamos de cima pra baixo: Apresentação -> Negócio -> Persistência. O ideal é que as camadas se comuniquem sempre com as abaixo e jamais com as acima delas:

Camadas separando responsabilidades

Camadas separando responsabilidades

Repare bem que agora estou falando de separar responsabilidades. MVC me provê 2 interações chave,  e eu as aplico onde quiser. Já separação por camadas me provê onde colocar os componentes, e eu faço interações como quiser. Inclusive posso utilizar… MVC! Não, esses 2 padrões não são auto-excludentes! Posso sim usar ambos na minha aplicação. E muitas fazem isso.

Uma vez definidas as camadas (sendo da forma tradicional ou não), eu posso agora olhar para as classes que interagem entre si, aplicar os patterns mencionados e estarei usando MVC. Utilizando os 2 padrões, normalmente a camada de apresentação fica com todos os elementos da View, e a camada de Negócios fica com o Model. O Controller não é tão simples porque é uma classe bem inteligente e exige bastante controle. Se sua aplicação for Web você “ganha ele de graça” com o framework que estiver usando ou com Servlets. Caso precise implementar, acho preferível colocar na camada de apresentação para não gerar dependências desnecessárias.

Conclusão

Jamais confunda esses dois padrões. MVC diz respeito a interações entre componentes, não quer dizer que a aplicação tem que ser web nem mesmo que precise ter uma View. Camadas separam componentes da aplicação de acordo com responsabilidades. Ambos os padrões são muito úteis como ferramenta para qualquer desenvolvedor, mas é necessário ter perspicácia para ver as coisas além do óbvio, além do que é passado por aí. Não force o uso destes padrões (nem de algum outro). Mas use-os com moderação, onde os benefícios deles fiquem bem claros para você e para o seu cliente. Eu gosto muito deste post do Phillip Calçado sobre MVC e da explicação deste livro.  Qualquer dúvida, postem comentários. Ah! E usem filtro solar! =]

Padrão

8 comentários sobre “MVC não é sobre camadas!

  1. Meu caro, como sempre post muito bom!🙂 Gostaria somente de acrescentar informações sobre MVP que é bem similar

    http://martinfowler.com/eaaDev/ModelViewPresenter.html -> Nota de Aposentadoria do MVP!
    neste link martin fowler explica que este padrão foi “aposentado”, dando lugar a 2 outros, que são basicamente a mesma coisa com diferenças pequenas.

    Os dois que ficaram no lugar são:

    – “Supervising Presenter” (http://martinfowler.com/eaaDev/SupervisingPresenter.html), que é um MVP onde a view tem algumas responsabilidades, mas as maiores responsabilidades são do Presenter [supervisor]. Este é muito similar ao MVC convencial, podendo o presenter ser chamado de “Controller”;

    – “Passive View” (http://martinfowler.com/eaaDev/PassiveScreen.html), que é um MVP onde não existem dependencias entre a view e o model pois a view é completamente passiva [view burra], e tudo é executado pelo presenter.

    http://martinfowler.com/eaaDev/uiArchs.html -> Na seção do MVP ele explica as diferenças e compara com o MVP original popularizado por Potel [1996].

    é isso! parabéns!

  2. Tiago, parabéns pelo post. Utilizando-se de linguagem simples e bem humorada abordou um assunto que gera tanta confusão até mesmo para os desenvolvedores mais experientes. Espero não fazer mais confusão com estes conceitos. Vai loooogo!! =]

  3. Pingback: Aplicando MVC/Camadas em um projeto Android – Parte 1 | Eu, Android

  4. Bedrick disse:

    Olá Tiago, tudo bem.
    Gostaria de saber se meu raciocínio está correto sobre o que você disse “o modelo também pode notificar a view da mudança, apesar de eu não gostar desta versão”. Isto é, não usar o modelo para notificar a view da mudança.

    Sendo assim, tudo dependeria das classes controladoras, ou seja, uma view só poderia comunicar com o seu respectivo model por meio da controladora e vice-versa.

    Por exemplo, um usuario envia uma requisição para uma controladora qualquer, essa controladora chama uma model que verifica a
    veracidade dos dados (“passando a bola” para os objetos de persistencia – dependendo da condição em que os dados chegaram) e envia o sinal novamente para a controladora, que por sua vez exibe a view deste model.

    Abs

  5. Obrigado por me ajudar a recuperar meu sono! kkkk Estou iniciando no mundo do MVC, vindo de um intenso estudo do SOLID, e a duvida sobre a diferenca entre mvc e camadas estava me matando, obrigado e otimo post!

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s