Episode 9 — System Design / 9.5 — Behavioral Design Patterns
9.5 Exercise Questions -- Behavioral Design Patterns
Observer Pattern (Questions 1-7)
Q1. Implement a WeatherStation class that acts as a subject. It should have temperature, humidity, and pressure properties. Create three observers: CurrentConditionsDisplay, StatisticsDisplay (tracks min/max/average temperature), and ForecastDisplay (simple rising/falling pressure prediction). All displays should update automatically when weather data changes.
Q2. Build a FormValidator using the Observer pattern. The form has fields (name, email, password). Each field is a subject that notifies a ValidationStatus observer whenever the value changes. The status observer should aggregate all field validities and enable/disable a submit button accordingly.
Q3. Create an event bus (global publish/subscribe system) with namespaced events. Support patterns like user.* that match user.login, user.logout, user.signup. Implement on(pattern, callback), emit(eventName, data), and off(pattern, callback). Include wildcard matching.
Q4. Implement an ObservableArray that wraps a regular array and emits events when items are added, removed, or updated. Support events: add, remove, update, sort, clear. Each event should include the affected items and their indices.
Q5. Build a real-time stock portfolio tracker. A Portfolio subscribes to multiple StockTicker subjects. The portfolio should calculate total value, daily gain/loss, and trigger alerts when any stock moves more than 5% in either direction. Handle the case where a ticker is removed from the portfolio.
Q6. Implement a MutationObserver-like system for a plain JavaScript object. When any property (including nested properties) changes, registered observers should be notified with the path of the changed property, old value, and new value. Use Proxy to detect changes.
Q7. Create a PerformanceMonitor that observes function calls. It should track execution time, call count, and error rate. Multiple displays can subscribe: a console logger, a metrics dashboard, and an alert system (triggers when error rate exceeds a threshold).
Strategy Pattern (Questions 8-14)
Q8. Build a TextFormatter that supports multiple formatting strategies: UpperCase, LowerCase, TitleCase, CamelCase, SnakeCase, KebabCase. The formatter should accept a strategy and apply it. Add a pipeline method that chains multiple strategies.
Q9. Implement a RouteFinder with different pathfinding strategies: ShortestDistance, LeastTraffic, FewestTurns, and TollFree. Given a graph of roads with distance, traffic level, and toll information, each strategy should find the optimal route based on its criteria.
Q10. Create a PricingEngine for a SaaS product. Strategies include: FlatRate, PerUser, Tiered (different price per tier), UsageBased (pay per API call), and Freemium (free tier + paid features). Each strategy should calculate monthly cost given usage data.
Q11. Build a FileParser that uses Strategy to handle different file formats. Support parsing JSON, CSV, XML, and YAML (simplified). The parser should auto-detect the format from the file extension or content, then apply the correct strategy.
Q12. Implement an AuthenticationService with interchangeable strategies: PasswordAuth, OAuthAuth, APIKeyAuth, JWTAuth, and BiometricAuth. Each strategy should implement authenticate(credentials) and validate(token) methods.
Q13. Create a CacheStrategy system with: LRU (Least Recently Used), LFU (Least Frequently Used), FIFO (First In First Out), and TTL (Time To Live). All strategies should implement get(key), set(key, value), and evict() with the same interface.
Q14. Build a NotificationDispatcher with strategies for different channels: Email, SMS, PushNotification, Slack, and InApp. Each strategy should implement send(recipient, message, options). Add a CompositeStrategy that sends through multiple channels.
Command Pattern (Questions 15-21)
Q15. Implement a full-featured drawing application with commands: DrawCircle, DrawRectangle, DrawLine, FillColor, Resize, Move, Delete. Support full undo/redo. The canvas should maintain a list of shapes that commands operate on.
Q16. Build a DatabaseMigrationSystem using commands. Each migration is a command with up() (apply migration) and down() (rollback migration). Support running all pending migrations, rolling back the last N migrations, and migrating to a specific version.
Q17. Create a SpreadsheetCell system with commands for: SetValue, SetFormula, MergeRows, SortColumn, InsertRow, DeleteRow. Implement undo/redo. Formulas should recalculate when dependent cells change (combine with Observer).
Q18. Implement a GitSimulator with command objects for: Commit, Branch, Checkout, Merge, Revert, CherryPick. Each command should be undoable. Maintain a commit graph and branch pointers.
Q19. Build a MacroKeyboard system. Users can record sequences of keyboard actions (type, shortcut, mouse click) as macro commands. Macros can be saved, loaded, and replayed. Support nested macros (a macro that triggers another macro).
Q20. Create a TransactionSystem using the Command pattern. Commands represent financial operations: Transfer, Deposit, Withdraw, CreateAccount. All operations must be atomic -- if any part fails, the entire transaction rolls back.
Q21. Implement a TaskScheduler that accepts command objects with execution times. Commands can be scheduled for a specific time, repeated at intervals, or triggered by conditions. Support cancellation and priority ordering.
Iterator Pattern (Questions 22-27)
Q22. Implement a Matrix class that supports three iteration orders: row-major, column-major, and diagonal. Each should use a different iterator. The matrix should be usable with for...of and should support both Symbol.iterator (default row-major) and named iterator methods.
Q23. Build a FileSystemIterator that traverses a directory tree. Support depth-first and breadth-first iteration. Add options to filter by file extension, skip hidden files, and limit depth. Use generator functions.
Q24. Create a DatabaseResultSetIterator that lazily fetches rows from a simulated database in batches (cursor-based pagination). The iterator should transparently fetch the next batch when the current one is exhausted. Support for await...of.
Q25. Implement a Calendar iterable that yields each day in a date range. Support iteration by day, week, month, or year. Add filtering for weekdays only, specific days of the week, or exclude holidays.
Q26. Build a CombinationIterator that lazily generates all combinations of given sets without computing them all upfront. For example, combine([1,2], ['a','b'], [true, false]) should yield [1, 'a', true], [1, 'a', false], etc. Use generators.
Q27. Create a StreamMergeIterator that takes multiple sorted iterators and yields values in sorted order (merge sort style). Support both sync and async iterators. Handle the case where some iterators are faster than others.
State Pattern (Questions 28-33)
Q28. Implement a TCPConnection state machine with states: Closed, Listen, SynSent, SynReceived, Established, FinWait1, FinWait2, TimeWait, CloseWait, LastAck. Implement open(), close(), acknowledge(), and send() methods that behave differently in each state.
Q29. Build a MediaPlayer with states: Stopped, Playing, Paused, Buffering, Error. Implement play(), pause(), stop(), next(), previous(). The player should handle edge cases like playing when already playing, or stopping when already stopped.
Q30. Create a TurnstileStateMachine with states: Locked and Unlocked. Actions: insertCoin() and push(). In locked state, pushing should display "Please insert coin" and inserting a coin should unlock it. In unlocked state, pushing should lock it after passing through.
Q31. Implement an ElevatorController with states: Idle, MovingUp, MovingDown, DoorOpen, DoorClosed, Emergency. Handle floor requests, door operations, and emergency stops. Queue requests and process them optimally.
Q32. Build a SubscriptionManager with states: Trial, Active, PastDue, Cancelled, Expired, Suspended. Implement transitions for: subscribe(), pay(), cancelRenewal(), reactivate(), expire(), suspend(). Each state should control what features are available.
Q33. Create a GameCharacter state machine with states: Idle, Walking, Running, Jumping, Attacking, Damaged, Dead. Each state affects the character's animation, speed, and available actions. Some actions should chain (jumping while running = long jump).
Template Method Pattern (Questions 34-38)
Q34. Build an HTTPRequestHandler template with steps: parseRequest, authenticate, authorize, validate, execute, formatResponse, log. Create concrete handlers for UserController, ProductController, and AdminController that override specific steps.
Q35. Implement a TestFramework where the template method is runTest() with steps: setup(), execute(), assert(), teardown(). Create concrete test classes for DatabaseTest (connects/disconnects DB), APITest (starts/stops mock server), and UITest (launches/closes browser).
Q36. Create a DocumentConverter template that converts documents between formats. Steps: read(input), parse(), transform(), render(), write(output). Concrete converters: MarkdownToHTML, HTMLToPDF, JSONToCSV.
Q37. Build a GameLevel template: initialize(), loadAssets(), setupEntities(), runGameLoop(), checkWinCondition(), cleanup(). Create concrete levels: TutorialLevel (slower, hints), BattleLevel (enemies, combat), BossLevel (single boss, phases).
Q38. Implement an ETLPipeline (Extract, Transform, Load) template. Steps: connect(), extract(), validate(), transform(), load(), disconnect(). Create pipelines for: CSVToDatabase, APIToDataWarehouse, DatabaseToDatabase.
Chain of Responsibility Pattern (Questions 39-44)
Q39. Build a SupportTicketEscalation system. Chain: AutoResponder (FAQ matching), L1Support (basic issues), L2Support (technical issues), L3Support (critical/security issues), Engineering (bugs). Each level should attempt to handle the ticket based on category and severity.
Q40. Implement an InputSanitizer chain for user input. Handlers: TrimWhitespace, RemoveHTML, EscapeSQL, NormalizeUnicode, ValidateLength, ProfanityFilter. Each handler should process the input and pass to the next.
Q41. Create a PurchaseDiscountChain. Handlers: CouponDiscount, MemberDiscount, BulkDiscount, SeasonalDiscount, LoyaltyDiscount. Rules: coupons and member discounts don't stack, but bulk and seasonal do. The chain should calculate the best applicable discount.
Q42. Build a RequestRouter for an HTTP framework. Handlers match by: HTTP method, URL pattern (with params), content type, and custom predicates. The first matching handler processes the request. Support middleware-style processing where multiple handlers run.
Q43. Implement a DataValidationChain for API requests. Handlers: TypeValidator, RangeValidator, FormatValidator (email, URL, phone), BusinessRuleValidator, CrossFieldValidator (field A must be less than field B). Collect ALL validation errors, don't stop at the first.
Q44. Create an ExceptionHandler chain for a web application. Handlers: ValidationErrorHandler (400), AuthenticationErrorHandler (401), AuthorizationErrorHandler (403), NotFoundErrorHandler (404), RateLimitErrorHandler (429), DefaultErrorHandler (500). Each handler decides if it can handle the error type and formats an appropriate response.
Mediator Pattern (Questions 45-51)
Q45. Build a TradeMarketplace mediator. Buyers and sellers post orders (buy/sell, quantity, price). The mediator matches buy and sell orders, executes trades, and notifies both parties. Implement price-time priority matching (best price first, then first-come-first-served).
Q46. Implement a SmartHomeHub mediator that coordinates devices: Thermostat, Lights, SecurityCamera, DoorLock, Speaker. Define scenes: "Good Morning" (lights on, thermostat up, speaker plays news), "Away" (lights off, lock doors, arm cameras), "Movie Night" (dim lights, lower thermostat).
Q47. Create a FlightBookingMediator that coordinates: FlightSearch, SeatSelector, PaymentProcessor, LuggageAddon, MealSelector, InsuranceAddon. Each component depends on selections in others (e.g., meal options depend on the flight, luggage costs depend on the seat class).
Q48. Build a MultiplexerMediator for a video conference system. Users can: join/leave rooms, share screens, send chat messages, raise hand, react, start/stop video. The mediator manages who sees what based on the current speaker, gallery view mode, and breakout rooms.
Q49. Implement a WorkflowOrchestrator mediator for a CI/CD pipeline. Components: SourceControl, BuildSystem, TestRunner, SecurityScanner, Deployer, NotificationService. The orchestrator manages dependencies between steps and handles failures.
Q50. Create a UIFormWizard mediator for a multi-step form. Steps: personal info, address, payment, review. The mediator controls which step is active, validates before allowing navigation, and collects data across all steps. Support "go back" without losing data.
Q51. Build a GameMatchmaker mediator. Players join a queue with skill rating, preferred game mode, and region. The mediator groups players into balanced teams, considering skill ranges, ping requirements, and party groups (friends who want to play together). Handle edge cases like uneven teams and long wait times.
Cross-Pattern Questions (52-55)
Q52. Build a plugin system that combines Observer (plugin lifecycle events), Strategy (pluggable rendering engines), Command (plugin actions with undo), and Chain of Responsibility (plugin hooks that can intercept and modify behavior). Design the architecture and implement a minimal working version.
Q53. Design a rule engine that combines State (current rule evaluation context), Strategy (different rule evaluation strategies), Iterator (iterate through rules), and Chain of Responsibility (rule priority chain). The engine should evaluate business rules against incoming data.
Q54. Create a game engine event system that combines Observer (game events), Command (player actions with undo), State (game states: menu, playing, paused, game-over), and Mediator (coordinating game entities). Implement a simple turn-based game.
Q55. Build a microservice orchestrator that combines Mediator (service coordination), Chain of Responsibility (request processing pipeline), Observer (event propagation), and Command (saga pattern for distributed transactions). Handle service failures and compensating transactions.