Problem statement
Design the object model and core APIs for a Pomodoro-style focus timer that cycles a user through work intervals and breaks, and notifies listeners as each phase begins and ends.
Operating context. A user starts a session configured with a work length (e.g. 25 minutes), a short-break length, a long-break length, and how many work intervals precede a long break. The timer runs, and the user may pause, resume, skip the current phase, or reset. When a phase completes the timer auto-advances to the next phase in the cycle and notifies any subscribed listeners (to play a sound, update a badge, log the session). Time advances from a tick source that must be replaceable in tests. Single process, one active session at a time.
Out of scope. Persisting session history to a database, the OS notification / sound transport, syncing timers across devices, background-process / OS-scheduler concerns, and the UI — design the timer's object model and its event surface.
What to produce. The class hierarchy (Session, the timer engine, phase / state definitions, the cycle policy, the tick source, the listener interface), the public API each exposes, and the exact state machine. Be explicit about: the legal transitions between running, paused, and the phase types; how the tick source is injected so a test can fast-forward without real waiting; and how the work / break cycle policy is swapped without rewriting the engine.
Functional requirements
- Start a session from a configuration of work, short-break, and long-break durations and the intervals-per-long-break count.
- Pause and resume the running timer without losing elapsed time in the current phase.
- Auto-advance to the next phase when the current phase's duration elapses, following the cycle policy.
- Let the user skip the current phase or reset the whole session to its start.
- Notify subscribed listeners on every phase start, phase end, and timer tick.
Non-functional requirements
- State transitions are total and explicit: every user action in every state either has a defined outcome or is cleanly rejected.
- The tick source is injected so the engine advances deterministically in tests with no real elapsed time.
- The cycle policy is pluggable behind an interface so an alternative cadence swaps in without editing the engine.
- Adding a new listener type requires no change to the timer engine (open for extension).
- Listener notification is thread-safe if ticks arrive on a timer thread while the user acts on another.
- The engine is unit-testable in isolation from any real clock, sound, or UI.
Topics
- System Design LLD
- Oop Solid
- Patterns State
- Concurrency Timers
- Patterns Observer