Exercise: Single Responsibility
This exercise puts the Single Responsibility Principle into code.
Scenario
Implement a user-registration flow split into single-responsibility classes. Four classes own the four distinct concerns of the flow: EmailValidator checks whether an address is syntactically valid, UserRepository stores registered users by name, Notifier produces notification messages, and UserService orchestrates the other three. No class should handle more than one of those concerns.
Commands
| Command | Behavior | Output |
|---|---|---|
["register", name, email] | Validate email; if invalid, reject; otherwise store user | "Invalid email: <email>" if email lacks @; "Registered <name>" on success |
["notify", name] | Notify an existing user | "Email sent to <name>" if user exists; "No such user: <name>" otherwise |
["count"] | Return count of registered users | "Users: <n>" |
Example
Input
6 register alice alice@example.com register bob notavalidemail count notify alice notify charlie register carol carol@test.org
Output
Registered alice Invalid email: notavalidemail Users: 1 Email sent to alice No such user: charlie Registered carol
Explanation
Alice registers successfully. Bob's email has no `@`, so registration fails. The count is 1 (only alice). Notifying alice succeeds; notifying charlie fails because charlie is not registered. Carol registers at the end.
Your task
Fill in each method body so the commands produce the output above.