Model-View-Controller (MVC) Design Pattern: Complete Guide

The Ultimate Reference for Implementing MVC in Web Applications

 

Table of Contents

1. Introduction to MVC

The Model-View-Controller (MVC) pattern is an architectural design pattern that separates an application into three interconnected components:

MVC Components:
- Model: Manages data and business logic
- View: Handles display and presentation
- Controller: Processes user input

First introduced in 1979 by Trygve Reenskaug for Smalltalk, MVC has become fundamental in modern web development frameworks like Laravel, Ruby on Rails, and Django.

Key Characteristics

  • Separation of Concerns: Isolates business logic from presentation
  • Multiple Views: Same data can be displayed in different ways
  • Testability: Components can be tested independently
  • Maintainability: Easier to modify and extend

2. Core Components

Model

The Model represents the application’s data structure and business logic:

class UserModel {
private $db;

public function __construct(Database $db) {
$this->db = $db;
}

public function getUsers() {
return $this->db->query('SELECT * FROM users');
}

public function createUser($data) {
// Validation logic
if (empty($data['email'])) {
throw new Exception('Email is required');
}

// Business rules
if ($this->emailExists($data['email'])) {
throw new Exception('Email already registered');
}

// Data persistence
return $this->db->insert('users', $data);
}
}

View

The View presents data to the user and handles presentation logic:

<!-- users/view.php -->
<h1>Registered Users</h1>
<ul>
 	<li style="list-style-type: none;">
<ul><!--?php foreach ($users as $user): ?-->
 	<li><!--?= htmlspecialchars($user['name']) ?-->
(<!--?= htmlspecialchars($user['email']) ?-->)</li>
</ul>
</li>
</ul>
 

Controller

The Controller handles user input and mediates between Model and View:

class UserController {
private $model;

public function __construct(UserModel $model) {
$this->model = $model;
}

public function listUsers() {
$users = $this->model->getUsers();
require 'views/users.php';
}

public function createUser() {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$this->model->createUser($_POST);
header('Location: /users');
exit;
} catch (Exception $e) {
$error = $e->getMessage();
}
}
require 'views/create_user.php';
}
}

3. MVC Workflow

The typical MVC request lifecycle:

1. User interacts with View (clicks button, submits form)
2. View sends action to Controller
3. Controller processes request
4. Controller updates Model if needed
5. Controller selects appropriate View
6. Model notifies View of changes
7. View updates display

Sequence Diagram

Visual representation of MVC flow:

User -> View: Interacts (click, submit)
View -> Controller: Sends action
Controller -> Model: Updates data
Model -> Controller: Returns result
Controller -> View: Selects view
View -> User: Renders output

4. MVC in Web Development

Modern web frameworks implement variations of MVC:

Front Controller Pattern

Most web MVC implementations use a front controller:

// index.php (Front Controller)
require 'controllers/UserController.php';
require 'models/UserModel.php';

$model = new UserModel($db);
$controller = new UserController($model);

$action = $_GET['action'] ?? 'list';

switch ($action) {
case 'create':
$controller->createUser();
break;
default:
$controller->listUsers();
}

HTTP Request Handling

How web requests map to MVC components:

HTTP Request -> Router -> Controller -> Model -> View -> HTTP Response

5. Framework Implementations

Laravel MVC Example

// Model (app/Models/User.php)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;

class User extends Model {
protected $fillable = ['name', 'email'];
}

// Controller (app/Http/Controllers/UserController.php)
namespace App\Http\Controllers;
use App\Models\User;

class UserController extends Controller {
public function index() {
$users = User::all();
return view('users.index', compact('users'));
}
}

// View (resources/views/users/index.blade.php)
@extends('layouts.app')
@section('content')
@foreach ($users as $user)

{{ $user->name }}

@endforeach
@endsection

Other Framework Examples

  • Ruby on Rails: Convention over configuration
  • Django: MTV (Model-Template-View) variation
  • Spring MVC: Java implementation
  • ASP.NET MVC: Microsoft’s implementation

6. Benefits of MVC

Development Advantages

  • Parallel Development: Different teams can work on components simultaneously
  • Code Reusability: Models can be used with different views
  • Easier Maintenance: Changes in one component rarely affect others

Architectural Benefits

- Clear separation of concerns
- Better testability (unit testing components)
- More organized codebase
- Scalable architecture
- Flexible user interfaces

7. Best Practices

Model Guidelines

  • Keep business logic in models
  • Don’t put presentation logic in models
  • Make models framework-agnostic when possible

View Guidelines

- Minimal logic in views
- Use template engines
- Escape all output
- Keep HTML/CSS/JS separate

Controller Guidelines

- Thin controllers
- Handle input/output
- Don't put business logic in controllers
- Return appropriate responses

8. MVC Alternatives

MVVM (Model-View-ViewModel)

Common in frontend frameworks like Angular and Vue:

- View: UI structure
- ViewModel: Presentation logic
- Model: Data and business logic

Other Patterns

  • MVP: Model-View-Presenter
  • MVU: Model-View-Update (Elm architecture)
  • Flux: Unidirectional data flow (React)