Design Patterns and MVC

Introduction to Software Engineering (CSSE 1001)

Author

Paul Vrbik

Published

May 21, 2026

Model View Controller

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

  • Model: Stores the data and business rules of the application; responsible for every state change.
  • View: Some (usually visual) representation of the data without altering it.
  • Controller: Receives user input (commands), tells the Model what to do, then selects a View to present the result.

Anatomy of MVC

Layer Core question Owns MUST NOT
Model What is the data? Data & rules print, parse args, call input()
View How is info shown? Formatting & rendering Change state, validate data
Controller What happens next? Workflow & commands Store raw data, format output

Model knows nothing about how (or whether) the state is being displayed to a user. View knows nothing about where the data comes from, and doesn’t store the data / state within itself; it just displays what it’s told to display.

MVC Flow

  1. User issues a command.
  2. Controller parses input and calls the appropriate Model method.
  3. Model mutates state and returns domain data.
  4. Controller selects a View and passes the data.
  5. View formats the data and decides how to display it.
  6. Control returns to the main loop, waiting for the next user action.

Why MVC?

Modularity – we can swap new models, views, and controllers without breaking the application.

Testability – each component can be tested in isolation.

Separation of concerns – each component has a distinct responsibility.

Exercise

Implement a minimal todo-list manager using the MVC design pattern.

  • Task + TodoListModel (domain)
  • TodoViewView (presentation only)
  • TodoApp + run-loop → Controller (input parsing & orchestration)

Model

class Task:
    def __init__(self, title: str) -> None:
        self._title = title
        self._done = False


class TodoList:
    def __init__(self) -> None:
        self._tasks = []

    def add(self, title: str) -> Task:
        task = Task(title)
        self._tasks.append(task)
        return task

    def all(self) -> list[Task]:
        return list(self._tasks)

View

class TodoView:
    def show_task(self, task: Task) -> None:
        mark: str = "/" if task._done else "X"
        print(f"[{mark}] {task._title}")

    def show_list(self, tasks: list[Task]) -> None:
        print("\nMy Tasks\n--------")
        for t in tasks:
            self.show_task(t)

Controller

class TodoApp:
    def __init__(self, todo: TodoList, view: TodoView) -> None:
        self._todo = todo
        self._view = view

    def handle(self, command: str) -> None:
        parts = command.strip().split(maxsplit=1)
        if not parts:
            return

        cmd: str = parts[0]
        if cmd == "add" and len(parts) == 2:
            self._todo.add(parts[1])
            print("Task added!")
        elif cmd == "list":
            self._view.show_list(self._todo.all())
        else:
            print("Commands: add <title>, list, quit")

Controller (run-loop)

app = TodoApp(TodoList(), TodoView())

while True:
    user_cmd: str = input("$")
    if user_cmd.strip() in ("quit", "exit"):
        break
    app.handle(user_cmd)

# Sample session
$add Work on A2
Task added!
$add buy groceries
Task added!
$list
My Tasks
--------
[X] Work on A2
[X] buy groceries

MVC Flow (example)

  1. User issues a command (e.g., add Buy groceries).

  2. Controller parses input and calls the appropriate Model method (TodoList.add).

  3. Model mutates state and returns domain data (Task).

  4. Controller selects a View (e.g., show_task) and passes the data.

  5. View formats the data and pushes it to stdout.

  6. Control returns to the main loop, waiting for the next user action.

Summary

  • MVC is a pattern, which is typically used in web/GUI applications.

  • Separation of concerns makes code more organised.

  • Easier to test, maintain, and extend.

  • Provides a solid foundation for future enhancements.

  • Numerous variants of MVC exist. In this course we use a variant called Apple MVC, which enforces a strict separation of the model and view.