How to Build an MVP Presenter View Mock in Python

A minimal MVP (Model-View-Presenter) mock showing a Presenter controlling a SlideDeck model with slide navigation and typed state via dataclasses.

Easy Python 3.9+ Aug 9, 2026 System design patterns 13 views 0 copies

Python code

57 lines
Python 3.9+
from dataclasses import dataclass, field
from typing import List


@dataclass
class SlideDeck:
    title: str
    slides: List[str] = field(default_factory=list)
    current_index: int = 0

    def next_slide(self) -> str:
        if self.current_index < len(self.slides) - 1:
            self.current_index += 1
        return self.current_slide()

    def previous_slide(self) -> str:
        if self.current_index > 0:
            self.current_index -= 1
        return self.current_slide()

    def current_slide(self) -> str:
        return self.slides[self.current_index]

    def set_slide(self, index: int) -> str:
        if 0 <= index < len(self.slides):
            self.current_index = index
        return self.current_slide()


@dataclass
class Presenter:
    name: str
    deck: SlideDeck

    def present(self) -> str:
        return f"{self.name} is showing: {self.deck.current_slide()}"


if __name__ == "__main__":
    deck = SlideDeck(
        title="MVP Demo",
        slides=[
            "Welcome: Intro to the app",
            "Architecture: MVP pattern",
            "Live demo: Feature walkthrough",
            "Q&A and next steps"
        ]
    )
    presenter = Presenter("Alice", deck)

    print(presenter.present())
    print(presenter.deck.next_slide())
    print(presenter.present())
    print(presenter.deck.previous_slide())
    presenter.deck.set_slide(3)
    print(presenter.present())
    print(f"Deck: {presenter.deck.title} | Position: {presenter.deck.current_index + 1}/{len(presenter.deck.slides)}")

Output

stdout
Alice is showing: Welcome: Intro to the app
Alice is showing: Architecture: MVP pattern
Alice is showing: Welcome: Intro to the app
Alice is showing: Q&A and next steps
Deck: MVP Demo | Position: 4/4

How it works

The code models the MVP pattern with SlideDeck as the Model (holds data + navigation state) and Presenter as the Presenter (mediates access and formatting). The @dataclass generates __init__, __repr__, and equality automatically, reducing boilerplate. field(default_factory=list) gives each instance its own list, avoiding the shared mutable-default trap. Navigation methods mutate current_index only within bounds and always return the current slide, making the UI/model contract predictable. The present() method formats a view-ready string, keeping the underlying state untouched.

Common mistakes

  • Using a mutable default like `slides=[]` instead of `field(default_factory=list)`, which shares state across instances
  • Forgetting bounds checks in `set_slide`, causing IndexError on invalid indices
  • Mutating the deck state inside `present()` instead of leaving it a pure read operation
  • Not including a `previous_slide` guard, so moving back at index 0 wraps incorrectly

Variations

  1. Use a plain class with manual `__init__` and property-based navigation instead of dataclasses
  2. Add a View layer (e.g., a `display()` method) that listens to deck changes via callbacks or the observer pattern

Real-world use cases

  • Prototyping a slide deck presenter UI for a desktop or web app before wiring real rendering
  • Testing presenter state transitions in a unit test suite without a live view layer
  • Mimicking a wizard or onboarding flow where a controller steps users through ordered screens

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from System design patterns

Related tutorials and quizzes for this topic.