🎯 Breakout Exercise 1

Design Pattern Recognition Challenge
Week 4, Day 1 | Time: 15 minutes | Group Activity

🎯 Your Mission

Read each real-world scenario and identify: What's the problem? Which design pattern solves it? Why?

No coding required - focus on understanding which pattern fits which problem!

📋 How to Complete This Exercise

  1. Form groups of 3-4 students in your breakout room
  2. Read each scenario carefully - understand the problem first
  3. Discuss as a group:
    • What's the core problem being described?
    • Which pattern would help solve it?
    • Why is that pattern the right choice?
  4. Fill out the worksheet for each scenario
  5. Be ready to share your reasoning with the class

🔍 Quick Pattern Reference

🏭 Factory
Creates different types of things
🔄 Strategy
Switches between different methods
📢 Observer
Notifies multiple listeners
Singleton
Ensures only one instance
Scenario 1: The Smartphone Production Line 📱

The Situation:

TechCo manufactures smartphones. Their production system code looks like this:

def manufacture_phone(model_name): if model_name == "budget_basic": screen = "LCD 5.5 inch" camera = "8MP single" processor = "Quad-core 2.0GHz" memory = "32GB" # 15 lines of assembly code... elif model_name == "mid_range": screen = "OLED 6.1 inch" camera = "48MP dual" processor = "Octa-core 2.4GHz" memory = "128GB" # 15 lines of assembly code... elif model_name == "flagship_pro": screen = "AMOLED 6.7 inch" camera = "108MP triple with telephoto" processor = "Snapdragon 888" memory = "512GB" # 20 lines of assembly code... # ... 12 more phone models
Problem: Every time TechCo releases a new phone model (quarterly!), engineers must modify this massive production function. The function is now 800+ lines long. Different assembly lines need different phone configurations, but they all go through this one gigantic if/else chain. Adding the new "gaming edition" model means scrolling through all existing models and hoping nothing breaks.

📝 Your Analysis

1. What's the core problem TechCo faces with their production system?
2. Which design pattern would help?
3. Why is that pattern the right choice?

💡 Discussion Tips

  • Think about: Is this about creating different products, switching behaviors, notifying systems, or sharing one instance?
  • Consider: What makes adding new phone models so painful?
  • Ask: How could you organize phone creation to avoid this massive function?
Scenario 2: The Package Shipping Chaos 📦

The Situation:

ShipFast provides multiple shipping options. Their cost calculation system looks like this:

def calculate_shipping(package_weight, method): if method == "ground": if package_weight < 5: cost = package_weight * 2.50 else: cost = package_weight * 2.00 days = 7 tracking = False elif method == "express": if package_weight < 5: cost = package_weight * 8.00 else: cost = package_weight * 7.50 days = 3 tracking = True elif method == "overnight": cost = package_weight * 15.00 + 10.00 days = 1 tracking = True signature = True # ... more shipping methods return cost, days
Problem: Customers want to compare shipping options in real-time and switch between them easily. ShipFast wants to add "weekend delivery" and "drone delivery" options, but the calculation logic is rigid. During checkout, users should be able to switch between shipping methods dynamically, but the current code makes this difficult. Each shipping method has different pricing rules, delivery times, and features, but they're all jumbled together.

📝 Your Analysis

1. What flexibility is ShipFast's system missing?
2. Which design pattern would help?
3. How would this pattern let users switch shipping methods easily?

💡 Discussion Tips

  • Key word: "switch" between different shipping methods
  • Think: Same goal (ship package), different approaches (ground, express, overnight)
  • Consider: What if each shipping method was its own independent calculation?
Scenario 3: The Smart Home Security Alert 🏠

The Situation:

Sarah has a smart home security system. When a motion sensor detects movement, she needs multiple systems to respond:

  • Turn on outdoor lights
  • Start recording on all cameras
  • Send alert to her phone
  • Send alert to her husband's phone
  • Log the event in the security database
  • If nighttime: trigger alarm

Her current code:

def motion_detected(sensor_id, location): # Turn on lights light_system.turn_on_outdoor() # Start all cameras camera1.start_recording() camera2.start_recording() camera3.start_recording() camera4.start_recording() # Send alerts phone_app.send_alert_sarah() phone_app.send_alert_husband() # Log it database.log_motion_event() # Check time and trigger alarm if is_nighttime(): alarm_system.trigger() # Want to add smartwatch alerts? Modify this function! # Want daughter to get alerts? Modify this function!
Problem: Every time Sarah wants to add or remove an alert destination, she modifies this core motion detection function. She wants to add her smartwatch, her daughter's phone, and her smart doorbell to the alert system. She also wants her neighbor to get alerts when she's on vacation. But each addition means changing this critical security function - one mistake could disable the entire system!

📝 Your Analysis

1. What's fragile and hard to maintain about Sarah's security system?
2. Which design pattern would help?
3. How could devices "subscribe" to motion detection events?

💡 Discussion Tips

  • Think about: One event (motion detected) → Many responses (lights, cameras, alerts)
  • Key insight: Motion sensor shouldn't know about every alert destination
  • Consider: How do fire alarms work? One trigger, multiple alarms respond
Scenario 4: The Online Shopping Cart Disaster 🛒

The Situation:

EcomSite has an online store. They have a ShoppingCart class for user purchases:

# In product_page.py cart1 = ShoppingCart() cart1.add_item("Laptop", 999.99) # In checkout.py cart2 = ShoppingCart() # Creates NEW cart! cart2.add_item("Mouse", 29.99) # In header.py (showing cart count) cart3 = ShoppingCart() # Another NEW cart! item_count = cart3.get_item_count() # Shows 0! # User sees: 0 items in cart indicator # But they added a laptop! # Cart contents don't sync across pages!
Problem: Every page component creates its own ShoppingCart instance. When a user adds an item on the product page, the cart indicator in the header still shows 0 items. When they go to checkout, their cart appears empty! The cart contents aren't shared across the application. Users add items but then can't find them at checkout. Customer support is flooded with "my cart is empty!" complaints.

📝 Your Analysis

1. Why don't cart contents sync across EcomSite's pages?
2. Which design pattern would help?
3. What if there was only ONE shopping cart for the entire session?

💡 Discussion Tips

  • Think about: Multiple cart instances vs. one shared cart instance
  • Key problem: cart1, cart2, and cart3 are completely different objects
  • Consider: What if every part of the app referenced the SAME cart?

💬 Group Discussion Questions

After completing all four scenarios, discuss these questions as a group:

  1. Which scenario was easiest to identify? Why?
  2. Which scenario was hardest? What made it tricky?
  3. What's the key difference between Factory and Strategy?
  4. Can you think of an app you use daily that might use these patterns?
  5. When might using a pattern make things MORE complicated instead of simpler?

🎯 Pattern Recognition Cheat Sheet

Use this AFTER you've made your guesses!

🏭 Factory Pattern

When you need to create different types of similar products without massive if/else chains

🔄 Strategy Pattern

When you need to switch between different methods for accomplishing the same goal

📢 Observer Pattern

When one event needs to notify many systems automatically

⭐ Singleton Pattern

When you need exactly ONE shared instance that everyone accesses

Remember: Patterns solve problems. Focus on understanding WHICH pattern solves WHICH problem!

You'll see the code implementations after the breakout. Concepts first! 🎯