O padrão MVC (Model-View-Controller) é uma arquitetura de software amplamente utilizada no desenvolvimento web, especialmente em frameworks PHP como Laravel, Symfony e CodeIgniter. Ele organiza o código em três componentes interconectados: Model (Modelo), View (Visão) e Controller (Controlador). Essa separação visa promover a organização, a manutenibilidade e a escalabilidade do código, separando a lógica de negócio, a apresentação e o controle de fluxo.

Nesta aula, vamos explorar cada um desses componentes, entender a separação de responsabilidades, os motivos para usar o padrão e ver um exemplo conceitual de como ele funciona na prática. Ao final, você terá uma base sólida para aplicar MVC em seus projetos PHP.

Model, View, Controller

O MVC é composto por três papéis principais, cada um com uma responsabilidade específica:

  • Model (Modelo): Representa a camada de dados e a lógica de negócio. Ele é responsável por acessar o banco de dados, realizar validações, aplicar regras de negócio e fornecer os dados para o resto da aplicação. O Model não conhece a interface ou como os dados serão exibidos.
  • View (Visão): É a camada de apresentação. Ela exibe os dados fornecidos pelo Model ao usuário, geralmente em HTML, mas também pode gerar JSON, XML, PDF, etc. A View não contém lógica de negócio; ela apenas renderiza as informações.
  • Controller (Controlador): Atua como intermediário entre o Model e a View. Ele recebe as requisições do usuário, processa-as (por exemplo, validando entradas), interage com o Model para obter ou modificar dados e, em seguida, seleciona a View adequada para exibir a resposta.

No contexto PHP, um exemplo clássico é um sistema de blog. O Model Post seria responsável por buscar os posts do banco de dados. O Controller PostController teria métodos como index() (listar posts) e show() (exibir um post específico). A View index.php exibiria a lista de posts em HTML, enquanto show.php exibiria o post completo.

<?php
// Model: Post.php
class Post {
    public function getAll() {
        // Consulta ao banco de dados
        return [['id' => 1, 'title' => 'Hello World']];
    }
}

// Controller: PostController.php
class PostController {
    private $post;

    public function __construct() {
        $this->post = new Post();
    }

    public function index() {
        $posts = $this->post->getAll();
        // Inclui a View
        include 'views/index.php';
    }
}

// View: views/index.php
<ul>
    <?php foreach ($posts as $post): ?>
        <li><?php echo $post['title']; ?></li>
    <?php endforeach; ?>
</ul>
?>

Separação de responsabilidades

A separação de responsabilidades é o princípio fundamental do MVC. Cada componente tem uma função bem definida, o que evita que o código se torne um emaranhado de lógica misturada. Por exemplo, sem MVC, é comum ver scripts PHP que misturam consultas SQL, HTML e lógica de validação em um único arquivo. Isso dificulta a manutenção, pois qualquer alteração visual pode quebrar a lógica de negócio, e vice-versa.

Com o MVC, você pode alterar a interface (View) sem tocar na lógica de negócio (Model), ou modificar as regras de negócio sem afetar a apresentação. Além disso, os controllers podem ser testados isoladamente, e as views podem ser reutilizadas em diferentes partes da aplicação. Essa separação também facilita o trabalho em equipe, pois diferentes desenvolvedores podem trabalhar em componentes distintos simultaneamente.

Um exemplo claro: imagine que você precise alterar o layout do site. Com MVC, basta editar os arquivos de View, sem se preocupar com as consultas ao banco. Da mesma forma, se precisar mudar a regra de cálculo de um preço, você altera o Model, sem tocar no HTML.

Por que usar

Adotar o padrão MVC traz diversos benefícios para projetos PHP, mesmo os de médio porte. Entre eles:

  • Organização: O código fica estruturado em camadas, facilitando a navegação e a compreensão.
  • Manutenibilidade: Alterações são mais seguras e rápidas, pois cada componente é independente.
  • Reutilização: Models e Views podem ser reutilizados em diferentes controllers ou até em outros projetos.
  • Testabilidade: É mais fácil escrever testes unitários para cada componente, especialmente para Models e Controllers.
  • Escalabilidade: O padrão permite que a aplicação cresça de forma organizada, sem que o código se torne caótico.
  • Padronização: Frameworks baseados em MVC (como Laravel) já fornecem uma estrutura padrão, o que acelera o desenvolvimento e facilita a colaboração.

Em projetos pequenos, o MVC pode parecer excessivo, mas mesmo neles, a separação ajuda a evitar retrabalho quando o projeto cresce. Por isso, é uma prática recomendada desde o início.

Exemplo conceitual

Vamos imaginar um sistema simples de cadastro de usuários. O fluxo de uma requisição para listar usuários seria:

  1. O usuário acessa a URL /usuarios.
  2. O roteador (parte do front controller) direciona a requisição para o método index() do UsuarioController.
  3. O Controller instancia o Model Usuario e chama o método getAll().
  4. O Model consulta o banco e retorna um array de usuários.
  5. O Controller recebe os dados e inclui a View usuarios/index.php, passando os dados.
  6. A View itera sobre os usuários e gera o HTML final.
  7. O navegador exibe a página.

Esse fluxo ilustra como cada componente tem seu papel: o Controller orquestra, o Model fornece os dados e a View apresenta. Em código PHP, essa estrutura pode ser implementada manualmente, mas frameworks como Laravel já fornecem a estrutura pronta, com rotas, controllers e blade templates (views).

<?php
// Exemplo de rota simples (pseudo-código)
if ($_GET['url'] === 'usuarios') {
    $controller = new UsuarioController();
    $controller->index();
}

// Controller
class UsuarioController {
    public function index() {
        $usuarioModel = new Usuario();
        $usuarios = $usuarioModel->getAll();
        include 'views/usuarios/index.php';
    }
}

// Model
class Usuario {
    public function getAll() {
        // Simulação de consulta
        return [['nome' => 'João'], ['nome' => 'Maria']];
    }
}

// View (views/usuarios/index.php)
<ul>
    <?php foreach ($usuarios as $usuario): ?>
        <li><?php echo $usuario['nome']; ?></li>
    <?php endforeach; ?>
</ul>
?>

Boas práticas

Ao trabalhar com MVC, algumas boas práticas ajudam a manter o código limpo e eficiente:

  • Controllers finos, Models gordos: Mantenha a lógica de negócio no Model, deixando os controllers enxutos (apenas orquestrando).
  • Views sem lógica: Evite colocar consultas ou regras de negócio nas views; elas devem apenas exibir dados.
  • Use namespaces: Organize suas classes em namespaces para evitar conflitos e facilitar o autoload.
  • Padronize a nomenclatura: Por exemplo, UsuarioController, UsuarioModel, etc.
  • Considere usar um framework: Laravel, Symfony e outros já implementam MVC e oferecem ferramentas extras, mas entender o padrão é essencial.

Referências

Exercícios

  1. Explique com suas palavras as responsabilidades de cada componente do MVC (Model, View, Controller).

    ✓ Resposta: O Model é responsável pela lógica de negócio e acesso a dados. A View é responsável pela apresentação, ou seja, exibir os dados ao usuário. O Controller é o intermediário que recebe as requisições, processa-as (validando, por exemplo), interage com o Model e seleciona a View adequada.
  2. Qual é a principal vantagem da separação de responsabilidades no MVC? Dê um exemplo de como isso facilita a manutenção.

    ✓ Resposta: A principal vantagem é que cada componente tem uma função bem definida, o que evita que o código fique bagunçado. Por exemplo, se precisar alterar o layout do site, você só precisa editar as Views, sem se preocupar com a lógica de negócio. Isso reduz o risco de introduzir bugs em outras partes do sistema.
  3. No exemplo conceitual, o que aconteceria se a View tentasse acessar diretamente o banco de dados? Isso violaria o padrão MVC?

    ✓ Resposta: Sim, violaria o padrão MVC. A View deve ser apenas uma camada de apresentação e não deve conter lógica de acesso a dados. Isso quebraria a separação de responsabilidades, dificultando a manutenção e a testabilidade. O acesso a dados deve ser feito exclusivamente pelo Model.
  4. Escreva um pequeno código PHP que simule um Controller com um método show que recebe um ID e exibe um usuário específico, usando um Model simples.

    ✓ Resposta:
    <?php
    class Usuario {
        public function find($id) {
            // Simulação de busca
            return ['id' => $id, 'nome' => 'João'];
        }
    }
    
    class UsuarioController {
        public function show($id) {
            $usuario = (new Usuario())->find($id);
            include 'views/usuarios/show.php';
        }
    }
    // Em views/usuarios/show.php
    // <p><?php echo $usuario['nome']; ?></p>
    ?>
  5. Cite três benefícios de usar MVC em projetos PHP e explique um deles em detalhes.

    ✓ Resposta: Três benefícios: organização, manutenibilidade e testabilidade. Explicando a testabilidade: como cada componente é separado, você pode escrever testes unitários para o Model (lógica de negócio) e para o Controller (fluxo), usando dados simulados, sem depender da interface ou do banco de dados real. Isso aumenta a confiabilidade do código.