Object-Oriented Design for a Coffee Shop
thought-works: OO design for a coffee shop
thought-works: OO design for a coffee shop Let us do the design for a coffee shop today. Let me start with the description of how the coffee shop we want to design works first. There are three different actors in our scenario and i have listed the different actions they do also below * Customer - Pays the cash to the cashier and places his order, get a token number back - Waits for the intimation that order for his token is ready - Upon intimation/notification he collects the coffee and enjoys his drink ( Assumption: Customer waits till the coffee is done, he wont timeout and cancel the order. Customer always likes the drink served. Exceptions like he not liking his coffee, he getting wrong coffee are not considered to keep the design simple.) * Cashier - Takes an order and payment from the customer - Upon payment, creates an order and places it into the order queue - Intimates the customer that he has to wait for his token and gives him his token ( Assumption: Token returned to the customer is the order id. Order queue is unlimited. With a simple modification, we can design for a limited queue size) * Barista - Gets the next order from the queue - Prepares the coffee - Places the coffee in the completed order queue - Places a notification that order for token is ready
Problem
Design an object-oriented system for a coffee shop where customers place orders at a cashier, baristas prepare orders from a queue, and customers are notified when their order is ready. The design should model the actors (Customer, Cashier, Barista), the order queueing behavior, and the notification flow.
Solution
1. Requirements Analysis
Functional requirements:
- Customers can place orders and provide payment.
- The cashier creates an Order and enqueues it; a token (order id) is returned to the customer.
- Baristas consume orders from the queue, prepare drinks, and publish notifications when ready.
- Customers receive notifications and collect completed orders.
Non-functional requirements:
- Asynchronous processing: order creation and preparation should be decoupled (supports scaling baristas independently).
- Fault tolerance for worker failures (barista) and robust queue handling.
- Configurable queue capacity and monitoring for backlog.
Assumptions (from source):
- Token returned to the customer is the order id. Queue is assumed unlimited in the simplified design.
2. Use Case Diagram
Actors: Customer, Cashier, Barista, Administrator
graph TD subgraph Coffee Shop UC1(Place Order) UC2(Prepare Order) UC3(Notify Customer) UC4(Manage Menu) end Customer --> UC1 Cashier --> UC1 Barista --> UC2 Barista --> UC3 Admin --> UC4
3. Class Diagram
Core classes and responsibilities:
- Customer: places orders and receives notifications.
- Cashier: accepts payments, creates orders, and enqueues them.
- Order: contains order id, items, status, and customer contact/token.
- OrderQueue: thread-safe queue abstraction holding pending orders.
- Barista (Worker): dequeues orders, prepares them, and publishes completion events.
- NotificationService: notifies customers (announcement/SMS) when orders are ready.
classDiagram class Customer { +String name +String contact } class Cashier { +Order createOrder(Customer, List<Item>) } class Order { +String orderId +List<Item> items +OrderStatus status } class OrderQueue { +void enqueue(Order) +Order dequeue() } class Barista { +void processOrder() } class NotificationService { +void notify(Order) } Cashier --> OrderQueue : enqueue Barista --> OrderQueue : dequeue Barista --> NotificationService : notify Customer --> NotificationService : receive
4. Activity Diagrams
Activity: Place Order
graph TD A[Customer places order at Cashier] --> B[Cashier charges payment] B --> C[Cashier creates Order and enqueues it] C --> D[Cashier returns token to Customer]
Activity: Order Fulfillment
graph TD U[Barista polls OrderQueue] --> V[Dequeue Order] V --> W[Prepare drink] W --> X[Place in completed queue] X --> Y[NotificationService notifies Customer]
5. High-Level Code Implementation
Skeletons below show the main classes and method signatures in Java and Python. They are intentionally minimal and focused on structure.
Java
public class Order {
private final String orderId;
private List<Item> items;
private OrderStatus status;
}
public interface OrderQueue {
void enqueue(Order order);
Order dequeue();
}
public class Cashier {
public String takePaymentAndCreateOrder(Customer c, List<Item> items) {
// create Order, enqueue, return token
}
}
public class Barista implements Runnable {
private final OrderQueue queue;
private final NotificationService notifier;
public void run() {
while (true) { processOrder(); }
}
public void processOrder() { /* dequeue and prepare */ }
}
public class NotificationService {
public void notifyCustomer(Order order) { /* announce or SMS */ }
}
Python
from __future__ import annotations
from dataclasses import dataclass
from typing import List
@dataclass
class Order:
order_id: str
items: List[str]
status: str
class OrderQueue:
def enqueue(self, order: Order) -> None: ...
def dequeue(self) -> Order: ...
class Cashier:
def take_payment_and_create_order(self, customer, items):
pass
class Barista:
def __init__(self, queue: OrderQueue, notifier):
self.queue = queue
self.notifier = notifier
def process_order(self) -> None:
pass
class NotificationService:
def notify(self, order: Order) -> None:
pass
References
- ThoughtWorks blog: http://thought-works.blogspot.com/2013/12/oo-design-for-coffee-shop.html