Três Olhares sobre Arquitetura de Software: Fowler, Evans e Uncle Bob: 3.1 - MVC e Front Controller: a porta de entrada

Depois de percorrer os padrões ligados ao coração do domínio e à persistência de dados, chegamos agora à camada mais visível de qualquer aplicação: a apresentação. É aqui que usuários, sistemas externos e integrações tocam o nosso software pela primeira vez. E, embora pareça apenas uma questão de “UI” ou “framework web”, a forma como estruturamos essa porta de entrada pode fortalecer, ou corroer, toda a arquitetura.
Martin Fowler dedicou uma parte importante do seu catálogo de Patterns of Enterprise Application Architecture a esse tema. Ele descreveu como padrões como MVC, Front Controller, Template View e Page Controller organizam a interação inicial com o sistema. São soluções para problemas recorrentes: evitar duplicação de lógica de roteamento, separar responsabilidades de renderização, manter consistência no fluxo de requisições.
Eric Evans, em Domain-Driven Design, lembra que o papel da camada de apresentação é traduzir intenções. Ela deve transformar cliques, mensagens ou chamadas HTTP em comandos compreensíveis para o domínio, preservando a Linguagem Ubíqua. O usuário nunca deveria sentir que está falando com tabelas ou APIs, mas sim com conceitos do negócio.
Já Robert C. Martin, em Clean Architecture, é incisivo: a web, o framework e a interface são apenas detalhes. Controllers, views ou middlewares não podem ditar a forma do modelo. A arquitetura deve gritar casos de uso, e não endpoints ou verbos HTTP.
Nesta terceira parte da série, exploraremos esses padrões de entrada e integração com o mesmo olhar triplo: Fowler com seu catálogo pragmático, Evans com a defesa do domínio como centro, e Uncle Bob com a disciplina que protege esse centro contra a pressão das bordas.
Índice da Série
Parte 1 – A lógica do domínio
- 1.1 Transaction Script: do procedural ao domínio rico
- 1.2 Table Module: tabelas falam mais alto que objetos?
- 1.3 Domain Model: o coração da arquitetura em três vozes
- 1.4 Service Layer: orquestrando casos de uso
Parte 2 – Persistência e Infraestrutura
- 2.1 Active Record: simplicidade que pode custar caro
- 2.2 Data Mapper: separando domínio e banco de dados
- 2.3 Unit of Work: coordenando mudanças no domínio
- 2.4 Identity Map & Lazy Load: truques de performance e consistência
Parte 3 – Apresentação e Integração
- 3.1 MVC e Front Controller: a porta de entrada
- 3.2 Template View e Page Controller: quando a UI dita o jogo
- 3.3 Gateways e Mappers: defendendo o domínio
- 3.4 Mensageria e integração: eventos em três perspectivas
MVC e Front Controller: a porta de entrada
O papel da camada de apresentação
Quando avançamos do núcleo da aplicação para a sua camada mais externa, a pergunta inevitável é: como as requisições chegam até o sistema e encontram o caso de uso correto? Martin Fowler, em Patterns of Enterprise Application Architecture, descreve dois padrões fundamentais: Model-View-Controller (MVC) e Front Controller. Eles nasceram em contextos de UI e web, mas continuam relevantes porque tratam da organização da porta de entrada.
Eric Evans, em Domain-Driven Design, lembra que esses padrões são infraestrutura. O domínio não deve conhecer HTTP, rotas ou controladores; deve apenas receber comandos e devolver respostas no seu próprio idioma. Já Robert C. Martin, em Clean Architecture, é categórico: o web framework é detalhe. A arquitetura deve gritar casos de uso e não endpoints ou verbos REST. A lição compartilhada pelos três é simples: use MVC e Front Controller para ordenar a borda, mas nunca deixe que ditem o formato do coração do sistema.
MVC na prática
Um exemplo de MVC em ASP.NET Core pode ser visto assim:
public class OrdersController : Controller
{
private readonly IPlaceOrderHandler _handler;
public OrdersController(IPlaceOrderHandler handler)
{
_handler = handler;
}
[HttpPost("/orders")]
public IActionResult PlaceOrder(PlaceOrderRequest request)
{
var command = new PlaceOrderCommand(request.CustomerId, request.Items);
var result = _handler.Handle(command);
if (!result.Success)
return BadRequest(result.Errors);
return Ok(new PlaceOrderResponse(result.OrderId));
}
}
// Presentation Model (DTO) for request
public record PlaceOrderRequest(int CustomerId, List<OrderItemDto> Items);
// Presentation Model (DTO) for response
public record PlaceOrderResponse(Guid OrderId);
Na prática atual, o “M” do MVC acaba sendo o Presentation Model — DTOs de entrada e saída. O “V” é a forma final de entrega: em uma API, JSON; em um webapp clássico, HTML. O domínio, por sua vez, continua isolado atrás do handler. Essa separação entre Presentation Model e Domain Model é crucial para evitar que o MVC se torne um “atalho” que contamina o coração do sistema.
O Front Controller segundo Fowler
O padrão Front Controller, descrito por Fowler em Patterns of Enterprise Application Architecture, propõe um ponto único de entrada para todas as requisições. Esse componente central é responsável por aplicar regras comuns como logging, autenticação, internacionalização ou qualquer outra preocupação transversal e então despachar a execução para a lógica adequada. Dessa forma, evita-se duplicação de infraestrutura e garante-se consistência no fluxo de requisições.
Nos frameworks modernos, esse padrão já não precisa ser implementado manualmente. Em ASP.NET Core, por exemplo, o pipeline de roteamento e despacho interno cumpre exatamente esse papel de Front Controller. Cada requisição HTTP passa por uma sequência de middlewares que cuidam de autenticação, autorização, logging e outros aspectos transversais, até chegar ao dispatcher que resolve a rota e chama o controller/action correto.
Isso significa que, como desenvolvedores, raramente escrevemos o Front Controller em si, ele já está embutido no framework. O nosso papel está em definir Controllers e Actions, que são os pontos de extensão para onde esse Front Controller despacha.
Do ponto de vista de Evans e Uncle Bob, a advertência é clara: o Front Controller pertence à infraestrutura e não deve vazar para dentro do domínio. Entidades e casos de uso não devem depender de HttpContext, rotas ou detalhes do pipeline. O domínio deve continuar puro, recebendo apenas comandos claros e devolvendo respostas no seu próprio idioma. O framework cuida da centralização e do despacho; nós cuidamos da disciplina arquitetural que mantém a separação entre borda e núcleo.
Um paralelo entre os três autores
A comparação entre os três autores deixa claro o alcance e o limite desses padrões. Fowler os apresenta como soluções pragmáticas para evitar duplicação e caos de roteamento. Evans alerta que eles não fazem parte do modelo de domínio, devendo ser tratados como infraestrutura. Uncle Bob radicaliza e lembra que MVC e Front Controller são detalhes que não podem determinar a forma da arquitetura. O perigo é deixar controladores ou middlewares manipularem entidades diretamente, criando um domínio anêmico disfarçado de caso de uso. O antídoto é disciplina: separar claramente adaptação de requisições e lógica de negócio.
Conclusão
No fim, MVC e Front Controller são a porta de entrada do sistema. Sem eles, a aplicação seria um labirinto de endpoints sem organização. Mas é preciso lembrar: portas não são a casa. Eles estruturam a borda, enquanto o valor real mora no domínio. Fowler nos dá o catálogo, Evans nos ensina a manter a pureza do modelo, e Uncle Bob nos lembra que frameworks são detalhes.
No próximo artigo, seguimos na camada de apresentação para explorar Template View e Page Controller, investigando como a renderização e a composição de UI podem reforçar, ou enfraquecer, a separação entre domínio e infraestrutura.