MVC: a essência do padrão Model-View-Controller e sua implementação

Autor: IT Sectr Publicado: 2026-02-16 Tempo de leitura: 9 min

MVC (Model-View-Controller) é um padrão arquitetural que divide uma aplicação em três componentes: Model é responsável pelos dados e lógica de negócio, View é responsável pela interface do usuário, Controller é responsável pelo processamento de entrada e coordenação entre Model e View. Em iOS, MVC é implementado através de UIViewController, em Android — através de Activity e Fragment. MVC continua sendo o padrão fundamental sobre o qual MVVM, MVP e Clean Architecture são construídos. Saiba mais em MVC in Cocoa Core.

Principais pontos

  • MVC — três componentes: Model (dados), View (interface), Controller (lógica)
  • UIViewController — implementação do Controller em iOS, responsável pelo ciclo de vida da tela
  • Activity/Fragment — implementação do Controller em Android com funções similares
  • Massive View Controller — principal problema do MVC: o controlador cresce para milhares de linhas
  • Comunicação de componentes — Controller atualiza View e Model, Model notifica Controller sobre mudanças

O que é MVC: a essência do padrão Model-View-Controller

MVC (Model-View-Controller) é um padrão arquitetural proposto por Trygve Reenskaug em 1979 para a linguagem Smalltalk-80. O padrão divide uma aplicação em três camadas: Model contém dados e lógica de negócio, View é responsável pela exibição, Controller processa a entrada do usuário e atualiza Model e View. A separação de responsabilidades permite alterar cada camada independentemente — por exemplo, substituir View de UIKit para SwiftUI sem alterar a lógica de negócio em Model.

Interação de componentes em MVC segue um ciclo: o usuário interage com View → Controller recebe o evento → Controller atualiza Model → Model notifica Controller sobre mudanças → Controller atualiza View. Na implementação clássica, Model usa o padrão Observer: quando os dados mudam, Model envia notificações, Controller se inscreve e atualiza View. Na implementação da Apple, Key-Value Observing (KVO) ou NotificationCenter desempenham esse papel.

ComponenteResponsabilidadeExemplo em iOSExemplo em Android
ModelDados, lógica de negócio, redeStruct User, CoreDataData class, Repository
ViewExibição de UIStoryboard, XIB, UIViewXML layout, Jetpack Compose
ControllerProcessamento de entrada, coordenaçãoUIViewControllerActivity, Fragment

MVC no desenvolvimento móvel moderno é usado menos do que há 10 anos, mas continua essencial para entender. A Apple recomenda MVC para telas simples em aplicações UIKit. O Google não recomenda MVC puro para Android — a documentação oficial sugere MVVM com Jetpack. No entanto, o conhecimento de MVC é necessário para trabalhar com projetos legados e para entender a evolução dos padrões arquiteturais.

MVC em iOS: UIViewController e Storyboard

Apple MVC é uma implementação personalizada do padrão incorporada no UIKit. UIViewController atua como Controller: gerencia o ciclo de vida da tela (viewDidLoad, viewWillAppear, viewDidDisappear), lida com toques e ações do usuário, atualiza View através de IBOutlets. View é criada no Interface Builder (storyboard ou XIB) ou programaticamente. Model — qualquer objeto de dados: serviços de rede, pilhas CoreData, estruturas Swift.

swift
final class UserViewController: UIViewController {
    // View (através de storyboard outlet)
    @IBOutlet private var nameLabel: UILabel!
    @IBOutlet private var emailLabel: UILabel!

    // Model
    private let userService = UserService()

    override func viewDidLoad() {
        super.viewDidLoad()
        loadUser()
    }

    private func loadUser() {
        userService.fetchUser { [weak self] user in
            // Controller atualiza View
            self?.nameLabel.text = user.name
            self?.emailLabel.text = user.email
        }
    }
}

O problema do Apple MVC — View e Controller são fortemente acoplados. UIViewController gerencia simultaneamente View e lógica. Storyboard armazena View em XML, mas o controlador tem referências diretas a elementos UI através de IBOutlets. Isso viola o princípio de responsabilidade única: o controlador é responsável pelo ciclo de vida, delegados, datasource, target-action e animações. Como resultado, uma tela padrão de aplicativo iOS contém 200–500 linhas no controlador.

Ciclo de vida do ViewController — a Apple fornece 6 métodos de ciclo de vida: loadView (criação manual de View), viewDidLoad (após carregar View na memória), viewWillAppear (antes de aparecer na tela), viewDidAppear (após a animação), viewWillDisappear (antes de sair da tela), viewDidDisappear (após sair). Cada método é um lugar para colocar lógica em MVC. Usar esses métodos para lógica de negócio acelera o crescimento do controlador.

MVC em Android: Activity, Fragment e XML Layout

Android MVC — Activity e Fragment atuam como Controller, arquivos XML layout como View, qualquer classe POJO com dados como Model. Activity gerencia o ciclo de vida da tela: onCreate, onStart, onResume, onPause, onStop, onDestroy. Fragment é uma subtela dentro de Activity com seu próprio ciclo de vida. View (XML) é separada do Controller e carregada via setContentView ou LayoutInflater. Model — repositórios, bancos de dados, chamadas de rede.

kotlin
class UserActivity : AppCompatActivity() {
    // View através de XML layout
    private lateinit var binding: ActivityUserBinding

    // Model
    private val userRepository = UserRepository()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityUserBinding.inflate(layoutInflater)
        setContentView(binding.root)
        loadUser()
    }

    private fun loadUser() {
        userRepository.getUser { user ->
            runOnUiThread {
                binding.nameText.text = user.name
                binding.emailText.text = user.email
            }
        }
    }
}

Android ViewBinding e DataBinding — ferramentas modernas que reduzem o acoplamento entre Controller e View. ViewBinding gera uma classe com referências diretas a Views do XML, eliminando findViewById. DataBinding adiciona a capacidade de vincular dados à UI na marcação XML através de @{user.name}. DataBinding é um passo em direção ao MVVM, pois permite passar dados de Model para View sem código em Activity. O Google recomenda DataBinding para todos os novos projetos.

Ciclo de vida do Android é mais complexo que iOS: Activity pode ser destruída e recriada na rotação da tela, falta de memória ou mudança de configuração. Em MVC puro, o controlador (Activity) contém lógica que é perdida na destruição. Isso requer salvar estado através de onSaveInstanceState ou ViewModel do Jetpack, o que vai além do MVC puro e aproxima a arquitetura do MVVM.

Massive View Controller e limitações do MVC

Massive View Controller é um termo que descreve o principal problema do MVC no desenvolvimento móvel. O controlador em iOS e Android assume muitas responsabilidades: processamento de entrada, validação de dados, interação de rede, navegação, cache, animações, gerenciamento de ciclo de vida. Como resultado, o controlador cresce para 500–2000 linhas de código, tornando-se difícil de ler, testar e manter.

Causas do Massive View Controller — a arquitetura do UIKit e Android Framework incentiva colocar lógica no controlador. Chamadas de rede, processamento JSON, navegação — tudo isso naturalmente vai para Activity ou UIViewController porque eles têm acesso ao ciclo de vida e à UI. O desenvolvedor deve conscientemente extrair a lógica para classes separadas (Service, Manager, Interactor), o que requer disciplina e compreensão dos princípios arquiteturais.

Problema do MVCDescriçãoSolução
Alto acoplamentoController conhece View e ModelMVVM — ViewModel não conhece View
Complexidade de testeController depende de UIKit/AndroidExtrair lógica para serviços
Ciclo de vidaEstado é perdido na rotaçãoViewModel do Jetpack/SwiftUI
Falta de navegaçãoController gerencia transiçõesPadrão Coordinator, Router

Testando MVC — Model é testado isoladamente com testes unitários. Controller é difícil de testar devido à dependência de UIKit/UIFoundation. XCTest não permite criar UIViewController sem uma janela de visualização. Para Android, ActivityTestRule e Robolectric resolvem parcialmente o problema, mas os testes são lentos. View geralmente não é testada com testes unitários — para UI são usados testes de captura de tela e testes de UI (XCUITest, Espresso).

Quando MVC é justificado — telas simples com um ou dois elementos (tela de login, perfil, configurações). Protótipos e MVP para validação de hipóteses — MVC é mais rápido de escrever sem camadas adicionais. Projetos com base de código pequena de até 10–15 telas. Em projetos complexos, MVC leva ao acúmulo de dívida técnica e requer refatoração a cada 6–12 meses.

Comparação do MVC com MVVM, MVP e Clean Architecture

MVC vs MVVM — a principal diferença: em MVVM, o controlador é substituído por ViewModel que não tem referência a View. Os dados são passados através de Observable (SwiftUI), LiveData/StateFlow (Android) ou Combine/RxSwift. ViewModel é testável com testes unitários sem dependências de UI. A Apple recomenda MVVM com SwiftUI desde 2019, o Google — MVVM com LiveData/Flow como arquitetura oficial do Android. MVVM requer mais código para vinculação, mas melhora significativamente a testabilidade.

MVC vs MVP — em MVP (Model-View-Presenter), Presenter é uma camada testável que recebe View através de uma interface. Ao contrário do MVC onde Controller gerencia diretamente View através do UIKit, Presenter não depende do framework — ele funciona através da abstração ViewInterface. MVP foi popular no desenvolvimento Android antes do Jetpack e é usado em projetos legados. Presenter sobrevive a Activity e preserva o estado na rotação da tela.

MVC vs Clean Architecture — Clean Architecture adiciona camadas: Use Cases (Interactors), Entities, Gateways e Repository. MVC permanece na camada de Presentation, mas a lógica de negócio é movida para a camada de Domain com Use Cases. Clean Architecture resolve radicalmente o problema do Massive View Controller — Controller contém apenas chamadas de Use Cases e atualizações de View. A desvantagem é um aumento significativo no número de classes e arquivos, o que é justificado para projetos com 50+ telas.

swift
// MVC em iOS: Controller contém tudo
class OrderViewController: UIViewController {
    func placeOrder() {
        // Validação + rede + atualização de UI
        guard Validation.isValid(total) else { return }
        NetworkService.shared.submit(order) { [weak self] result in
            self?.handleResult(result)
        }
    }
}

// MVVM: lógica em ViewModel
class OrderViewModel: ObservableObject {
    @Published var state: OrderState = .idle
    func placeOrder() { /* lógica de negócio */ }
}

Escolha da arquitetura depende do tamanho da equipe, escopo do projeto e testabilidade necessária. Para uma equipe de 1–2 desenvolvedores e um projeto de até 20 telas, MVVM funciona bem. Para uma equipe grande de 5+ desenvolvedores e um projeto com 50+ telas — Clean Architecture com estrutura modular. MVC continua relevante para entender a evolução das arquiteturas, manter projetos legados e para telas simples de UIKit sem lógica de negócio complexa.

Perguntas frequentes

Qual é o principal problema do MVC no desenvolvimento móvel?

O principal problema é o Massive View Controller. Em iOS, UIViewController lida com tudo: processamento de entrada, atualização de View, rede, navegação e ciclo de vida. Em Android, Activity/Fragment realiza funções similares. Como resultado, o controlador cresce para milhares de linhas de código, tornando-se difícil de testar e manter, violando o princípio de responsabilidade única.

Como o MVC difere do MVVM?

Em MVC, o controlador atualiza diretamente View e processa a entrada do usuário. Em MVVM, o papel de controlador é desempenhado por ViewModel, que não tem referência a View — os dados são passados através de mecanismos de vinculação. MVVM é mais fácil de testar porque ViewModel não depende de UIKit ou Android Framework. A Apple recomenda MVVM com SwiftUI, o Google recomenda MVVM com Jetpack Compose.

Pode-se usar MVC em projetos modernos?

Sim, MVC continua sendo um padrão funcional para telas simples e protótipos. A Apple recomenda MVC para aplicações UIKit com telas simples. Para projetos complexos com muitas telas, requisições de rede e cache, é melhor escolher MVVM, VIPER ou Clean Architecture. Desenvolvedores iniciantes são recomendados a dominar MVC antes de aprender padrões mais complexos.

Como testar uma aplicação MVC?

Model é testado isoladamente — são objetos de dados e lógica de negócio comuns. Controller é difícil de testar devido à dependência de UIKit ou Android Framework. Recomenda-se extrair a lógica de negócio do controlador para serviços ou interactors separados, que são testados com testes unitários. View geralmente não é testada com testes unitários — são usados testes de UI e testes de captura de tela.

Qual padrão escolher depois do MVC?

Em iOS — MVVM com SwiftUI e Combine, padrão da Apple desde 2019. Em Android — MVVM com LiveData ou StateFlow, oficialmente recomendado pelo Google. Para projetos grandes com equipes de 5+ desenvolvedores — Clean Architecture com VIPER em iOS ou Clean Architecture em Android com separação de módulos por funcionalidade. Para projetos legados com MVC — refatoração gradual com extração de lógica para serviços separados.

Resumo

  • MVC — padrão arquitetural com separação em Model, View e Controller
  • iOS MVC — UIViewController + storyboard + serviços de dados
  • Android MVC — Activity/Fragment + XML layout + repositórios
  • Massive View Controller — principal problema devido à mistura de responsabilidades
  • Testes — Model é fácil de testar, Controller requer extração de lógica
  • Evolução — MVC → MVVM → Clean Architecture para projetos em crescimento
  • Compatibilidade — padrões podem ser combinados no mesmo projeto

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também