Last Updated: December 19, 2025
An Online Food Delivery Service is a digital platform that connects users with nearby restaurants, allowing them to browse menus, place food orders, and have meals delivered to their doorstep by delivery partners.
Italian • Pizza
American • Burgers
Japanese • Sushi
Mexican • Tacos
Indian • Curry
The platform acts as a bridge between customers, restaurants, and delivery agents, coordinating everything from order placement to payment processing and delivery logistics.
In this chapter, we will explore the low-level design of a simplified food delivery service.
Let's start by clarifying the requirements:
Before starting the design, it's important to ask thoughtful questions to uncover hidden assumptions, clarify ambiguities, and define the system's scope more precisely.
Here is an example of how a conversation between the candidate and the interviewer might unfold:
Candidate: Should the system allow adding new restaurants and updating their menus?
Interviewer: Yes, the system should be able to onboard new restaurants and add new menu items.
Candidate: Should users be able to search for restaurants by location?
Interviewer: Yes, users should be able to search by city, menu keywords, and proximity. A simple string-based or distance-based search is sufficient for now.
Candidate: How should delivery assignment work? Should we auto-assign based on availability and proximity?
Interviewer: Yes, delivery agents should be auto-assigned based on availability and the combined proximity from agent to restaurant and from restaurant to customer.
Candidate: Do we need to support order cancellation? If yes, under what conditions?
Interviewer: Yes, users can cancel orders, but only if the order status is still "PENDING." Once the restaurant has started preparing, cancellations should not be allowed.
Candidate: Should the system notify customers, restaurants, or delivery agents when the order status changes?
Interviewer: Yes, all relevant parties should be notified whenever the order status is updated.
Candidate: Do we need to support payments as part of this design?
Interviewer: You can skip payments for this design. Assume payment is handled automatically when the order is placed.
After gathering the details, we can summarize the key system requirements.
After the requirements are clear, lets identify the core entities and their responsibilities within the system.
Core entities are the fundamental building blocks of our system. We identify them by analyzing key nouns (e.g., restaurant, user, order, item, delivery agent) and actions (e.g., browse, order, track, update, assign) from the functional requirements. These typically translate directly into classes, enums, or interfaces in an object-oriented design.
Below, we break down the functional requirements and extract the relevant entities. Related requirements are grouped together when they represent the same conceptual unit.
This introduces two key entities:
Restaurant: Represents a food provider on the platform. Stores metadata such as name, address, cuisine type, and a reference to its menu.MenuItem: Represents an individual dish offered by a restaurant. Includes attributes like name, description, price, and availability.Menu: Represents a collection of MenuItem objects for a given restaurant.Address: Represents the location of the restaurant, stored in a standardized format for filtering, searching, and delivery logistics.Restaurants will have a one-to-many relationship with menu items, and each restaurant is associated with a unique menu.
This introduces:
Customer: Represents a platform user who can browse restaurants, place orders, and track their order history.Order: Represents a food order placed by a customer. It includes details such as selected restaurant, delivery address, list of items, and order status.OrderItem: Represents a line item within an order. It references a MenuItem along with quantity and subtotal.This introduces:
DeliveryAgent: A specialized user who fulfills delivery tasks. Each agent has attributes such as name, availability, current location, and assigned orders.Assignment of delivery agents can be coordinated based on availability and proximity using a centralized service.
This requires:
OrderStatus (enum): Represents the lifecycle state of an order. Possible values include PENDING, ACCEPTED, PREPARING, OUT_FOR_DELIVERY, DELIVERED, and CANCELLED.Notifications can be sent when the order status transitions, informing the customer, restaurant, and delivery agent.
This suggests the need for a core orchestrator:
FoodDeliveryService: A high-level service responsible for coordinating the main workflows—placing orders, assigning delivery agents, updating order status, and notifying users.User: Base class representing any system user. Extended by specific roles like customer and delivery agent.Customer: A user who browses restaurants and places orders.DeliveryAgent: A user who delivers food. Has attributes like availability and current location.Restaurant: Represents a restaurant and its metadata (name, location, men).Menu: Represents a restaurant’s menu — a list of available items.MenuItem: A single dish in a restaurant’s menu, with attributes like name, price, and availability.Address: A geographic area or address used for restaurant filtering and delivery coordination.Order: Represents a placed order. Contains details about customer, restaurant, order items, status, and timestamps.OrderItem: Represents an individual menu item in an order and its quantity.OrderStatus (Enum): Enum to represent the lifecycle of an order — PENDING, ACCEPTED, PREPARING, DISPATCHED, etc.FoodDeliveryService: Core orchestrator that coordinates ordering, assignment, tracking, and status updates.These core entities define the key abstractions of the Online Food Delivery Service and will guide the structure of your low-level design and class diagrams.
This section breaks down the system's architecture into its fundamental classes, their responsibilities, and the relationships that connect them. We also explore the key design patterns that provide robustness and flexibility to the solution.
The system is composed of several types of classes, each with a distinct role.
OrderStatusRepresents the distinct stages in the lifecycle of an order, such as PENDING, PREPARING, OUT_FOR_DELIVERY, and DELIVERED.
This enables clear state management and triggers for notifications.
AddressA data class holding location information (street, city, coordinates).
It includes a utility method to calculate the distance to another address, which is crucial for proximity-based searches and delivery agent assignment.
MenuItemRepresents a single food item available at a restaurant, containing its ID, name, price, and availability.
MenuActs as a container for a collection of MenuItem objects, representing a restaurant's full menu.
OrderItemA linking class that connects a MenuItem with a specific quantity for an Order.
User (Abstract Class)A base class for all human actors in the system (Customer, DeliveryAgent).
Holds common properties like ID, name, and phone number. It also implements OrderObserver.
Customer: Represents the end-user placing an order. It holds personal details, address information, and a history of their orders. It acts as a concrete Observer.DeliveryAgent: Represents the person responsible for delivering the order. It maintains their current location and availability status (isAvailable). It also acts as a concrete Observer.RestaurantRepresents a food establishment.
It contains its address, a Menu of items it offers, and also acts as a concrete Observer to track the status of orders placed with it.
OrderThe central and most critical class in the system.
It encapsulates all details of a single transaction: the Customer, Restaurant, OrderItems, and assigned DeliveryAgent. It acts as the Subject in the Observer pattern, maintaining a list of observers and notifying them whenever its status changes.
FoodDeliveryService (Singleton & Facade)The main entry point for all client interactions.
It manages all the core entities (customers, restaurants, agents, orders) and orchestrates the entire workflow from searching and placing an order to assigning a delivery agent. It provides a simple, unified API to the complex underlying system.
The relationships between classes define the system's structure and data flow.
FoodDeliveryService has collections of Customer, Restaurant, DeliveryAgent, and Order. These entities are managed within and have their lifecycle controlled by the service.Restaurant has a Menu.Menu has a collection of MenuItems.Order is composed of a list of OrderItems.Order is associated with one Customer, one Restaurant, and one DeliveryAgent.FoodDeliveryService is associated with a DeliveryAssignmentStrategy to decide how to assign agents.FoodDeliveryService uses one or more RestaurantSearchStrategy objects to filter restaurants.Order (Subject) is associated with multiple OrderObservers.Customer and DeliveryAgent are specialized types of User and inherit from it.NearestAvailableAgentStrategy, SearchByCityStrategy, etc.) implement their respective strategy interfaces.FoodDeliveryService depends on the strategy interfaces to perform its core functions of searching and assignment.Order class depends on the OrderObserver interface to notify participants.FoodDeliveryServiceDemo) depends on the FoodDeliveryService facade to interact with the system.The FoodDeliveryService class serves as a facade. It provides a simple, high-level API (placeOrder, searchRestaurants, updateOrderStatus) that hides the complex internal interactions between orders, users, strategies, and notifications.
FoodDeliveryService is implemented as a singleton to ensure there is only one instance coordinating the entire system. This provides a single, global point of access and prevents state inconsistencies.
This pattern is used extensively to provide flexibility for core business logic.
RestaurantSearchStrategy allows the system to use different algorithms (by city, proximity, menu keyword) to filter restaurants without changing the FoodDeliveryService class. These strategies can even be chained together.
DeliveryAssignmentStrategy allows the logic for assigning delivery agents to be swapped out easily.
This pattern is crucial for real-time notifications. The Order object is the Subject, and the Customer, Restaurant, and DeliveryAgent are Observers.
When the order's status changes (e.g., from PREPARING to READY_FOR_PICKUP), the Order automatically notifies all its registered observers, keeping them in sync.
Defines the stages of an order’s lifecycle, enabling status transitions, validations, and notification triggers.
1class OrderStatus(Enum):
2 PENDING = "PENDING"
3 CONFIRMED = "CONFIRMED"
4 PREPARING = "PREPARING"
5 READY_FOR_PICKUP = "READY_FOR_PICKUP"
6 OUT_FOR_DELIVERY = "OUT_FOR_DELIVERY"
7 DELIVERED = "DELIVERED"
8 CANCELLED = "CANCELLED"Represents the physical location of users, restaurants, and delivery agents.
1class Address:
2 def __init__(self, street: str, city: str, zip_code: str, latitude: float, longitude: float):
3 self.street = street
4 self.city = city
5 self.zip_code = zip_code
6 self.latitude = latitude
7 self.longitude = longitude
8
9 def get_city(self) -> str:
10 return self.city
11
12 def distance_to(self, other: 'Address') -> float:
13 lat_diff = self.latitude - other.latitude
14 lon_diff = self.longitude - other.longitude
15 return math.sqrt(lat_diff * lat_diff + lon_diff * lon_diff)
16
17 def __str__(self) -> str:
18 return f"{self.street}, {self.city}, {self.zip_code} @({self.latitude}, {self.longitude})"Distance computation is used for proximity-based search and agent assignment.
Abstract contract for all order participants (Customer, Restaurant, DeliveryAgent) to receive live order updates.
1class OrderObserver(ABC):
2 @abstractmethod
3 def on_update(self, order: 'Order'):
4 pass1class User(OrderObserver):
2 def __init__(self, name: str, phone: str):
3 self.id = str(uuid.uuid4())
4 self.name = name
5 self.phone = phone
6
7 def get_id(self) -> str:
8 return self.id
9
10 def get_name(self) -> str:
11 return self.name1class Customer(User):
2 def __init__(self, name: str, phone: str, address: Address):
3 super().__init__(name, phone)
4 self.address = address
5 self.order_history: List['Order'] = []
6
7 def add_order_to_history(self, order: 'Order'):
8 self.order_history.append(order)
9
10 def get_address(self) -> Address:
11 return self.address
12
13 def on_update(self, order: 'Order'):
14 print(f"--- Notification for Customer {self.get_name()} ---")
15 print(f" Order {order.get_id()} is now {order.get_status().value}.")
16 print("-------------------------------------\n")1class DeliveryAgent(User):
2 def __init__(self, name: str, phone: str, current_location: Address):
3 super().__init__(name, phone)
4 self.is_available = True
5 self.current_location = current_location
6 self._lock = threading.Lock()
7
8 def set_available(self, available: bool):
9 with self._lock:
10 self.is_available = available
11
12 def is_available_agent(self) -> bool:
13 with self._lock:
14 return self.is_available
15
16 def set_current_location(self, current_location: Address):
17 self.current_location = current_location
18
19 def get_current_location(self) -> Address:
20 return self.current_location
21
22 def on_update(self, order: 'Order'):
23 print(f"--- Notification for Delivery Agent {self.get_name()} ---")
24 print(f" Order {order.get_id()} update: Status is {order.get_status().value}.")
25 print("-------------------------------------------\n")1class MenuItem:
2 def __init__(self, item_id: str, name: str, price: float):
3 self.id = item_id
4 self.name = name
5 self.price = price
6 self.available = True
7
8 def get_id(self) -> str:
9 return self.id
10
11 def set_available(self, available: bool):
12 self.available = available
13
14 def get_name(self) -> str:
15 return self.name
16
17 def get_price(self) -> float:
18 return self.price
19
20 def get_menu_item(self) -> str:
21 return f"Name: {self.name}, Price: {self.price}"1class Menu:
2 def __init__(self):
3 self.items: Dict[str, MenuItem] = {}
4
5 def add_item(self, item: MenuItem):
6 self.items[item.get_id()] = item
7
8 def get_item(self, item_id: str) -> MenuItem:
9 return self.items.get(item_id)
10
11 def get_items(self) -> Dict[str, MenuItem]:
12 return self.items1class Restaurant(OrderObserver):
2 def __init__(self, name: str, address: Address):
3 self.id = str(uuid.uuid4())
4 self.name = name
5 self.address = address
6 self.menu = Menu()
7
8 def get_id(self) -> str:
9 return self.id
10
11 def get_name(self) -> str:
12 return self.name
13
14 def get_address(self) -> Address:
15 return self.address
16
17 def get_menu(self) -> Menu:
18 return self.menu
19
20 def add_to_menu(self, item: MenuItem):
21 self.menu.add_item(item)
22
23 def on_update(self, order: 'Order'):
24 print(f"--- Notification for Restaurant {self.name} ---")
25 print(f" Order {order.get_id()} has been updated to {order.get_status().value}.")
26 print("----------------------------------------\n")1class OrderItem:
2 def __init__(self, item: MenuItem, quantity: int):
3 self.item = item
4 self.quantity = quantity
5
6 def get_item(self) -> MenuItem:
7 return self.item
8
9 def get_quantity(self) -> int:
10 return self.quantity1class Order:
2 def __init__(self, customer: Customer, restaurant: Restaurant, items: List[OrderItem]):
3 self.id = str(uuid.uuid4())
4 self.customer = customer
5 self.restaurant = restaurant
6 self.items = items
7 self.status = OrderStatus.PENDING
8 self.delivery_agent: Optional[DeliveryAgent] = None
9 self.observers: List[OrderObserver] = []
10 self.add_observer(customer)
11 self.add_observer(restaurant)
12
13 def add_observer(self, observer: OrderObserver):
14 self.observers.append(observer)
15
16 def notify_observers(self):
17 for observer in self.observers:
18 observer.on_update(self)
19
20 def set_status(self, new_status: OrderStatus):
21 if self.status != new_status:
22 self.status = new_status
23 self.notify_observers()
24
25 def cancel(self) -> bool:
26 if self.status == OrderStatus.PENDING:
27 self.set_status(OrderStatus.CANCELLED)
28 return True
29 return False
30
31 def assign_delivery_agent(self, agent: DeliveryAgent):
32 self.delivery_agent = agent
33 self.add_observer(agent)
34 agent.set_available(False)
35
36 def get_id(self) -> str:
37 return self.id
38
39 def get_status(self) -> OrderStatus:
40 return self.status
41
42 def get_customer(self) -> Customer:
43 return self.customer
44
45 def get_restaurant(self) -> Restaurant:
46 return self.restaurant
47
48 def get_delivery_agent(self) -> Optional[DeliveryAgent]:
49 return self.delivery_agent1class DeliveryAssignmentStrategy(ABC):
2 @abstractmethod
3 def find_agent(self, order: Order, agents: List[DeliveryAgent]) -> Optional[DeliveryAgent]:
4 pass
5
6class NearestAvailableAgentStrategy(DeliveryAssignmentStrategy):
7 def find_agent(self, order: Order, available_agents: List[DeliveryAgent]) -> Optional[DeliveryAgent]:
8 restaurant_address = order.get_restaurant().get_address()
9 customer_address = order.get_customer().get_address()
10
11 available_agents_filtered = [agent for agent in available_agents if agent.is_available_agent()]
12
13 if not available_agents_filtered:
14 return None
15
16 min_distance = float('inf')
17 best_agent = None
18
19 for agent in available_agents_filtered:
20 total_distance = self.calculate_total_distance(agent, restaurant_address, customer_address)
21 if total_distance < min_distance:
22 min_distance = total_distance
23 best_agent = agent
24
25 return best_agent
26
27 def calculate_total_distance(self, agent: DeliveryAgent, restaurant_address: Address, customer_address: Address) -> float:
28 agent_to_restaurant_dist = agent.get_current_location().distance_to(restaurant_address)
29 restaurant_to_customer_dist = restaurant_address.distance_to(customer_address)
30 return agent_to_restaurant_dist + restaurant_to_customer_distThe system's core business logic—how to search for restaurants and how to assign a delivery agent—can have many variations. The Strategy pattern makes these algorithms interchangeable.
1class RestaurantSearchStrategy(ABC):
2 @abstractmethod
3 def filter(self, all_restaurants: List[Restaurant]) -> List[Restaurant]:
4 pass
5
6class SearchByCityStrategy(RestaurantSearchStrategy):
7 def __init__(self, city: str):
8 self.city = city
9
10 def filter(self, all_restaurants: List[Restaurant]) -> List[Restaurant]:
11 return [r for r in all_restaurants if r.get_address().get_city().lower() == self.city.lower()]
12
13class SearchByMenuKeywordStrategy(RestaurantSearchStrategy):
14 def __init__(self, keyword: str):
15 self.keyword = keyword.lower()
16
17 def filter(self, all_restaurants: List[Restaurant]) -> List[Restaurant]:
18 result = []
19 for r in all_restaurants:
20 for item in r.get_menu().get_items().values():
21 if self.keyword in item.get_name().lower():
22 result.append(r)
23 break
24 return result
25
26class SearchByProximityStrategy(RestaurantSearchStrategy):
27 def __init__(self, user_location: Address, max_distance: float):
28 self.user_location = user_location
29 self.max_distance = max_distance
30
31 def filter(self, all_restaurants: List[Restaurant]) -> List[Restaurant]:
32 filtered = [r for r in all_restaurants if self.user_location.distance_to(r.get_address()) <= self.max_distance]
33 filtered.sort(key=lambda r: self.user_location.distance_to(r.get_address()))
34 return filteredThis class is a Singleton that provides a simplified, high-level API to the entire complex subsystem.
1class FoodDeliveryService:
2 _instance = None
3 _lock = threading.Lock()
4
5 def __init__(self):
6 if FoodDeliveryService._instance is not None:
7 raise Exception("This class is a singleton!")
8 self.customers: Dict[str, Customer] = {}
9 self.restaurants: Dict[str, Restaurant] = {}
10 self.delivery_agents: Dict[str, DeliveryAgent] = {}
11 self.orders: Dict[str, Order] = {}
12 self.assignment_strategy: Optional[DeliveryAssignmentStrategy] = None
13
14 @staticmethod
15 def get_instance():
16 if FoodDeliveryService._instance is None:
17 with FoodDeliveryService._lock:
18 if FoodDeliveryService._instance is None:
19 FoodDeliveryService._instance = FoodDeliveryService()
20 return FoodDeliveryService._instance
21
22 def set_assignment_strategy(self, assignment_strategy: DeliveryAssignmentStrategy):
23 self.assignment_strategy = assignment_strategy
24
25 def register_customer(self, name: str, phone: str, address: Address) -> Customer:
26 customer = Customer(name, phone, address)
27 self.customers[customer.get_id()] = customer
28 return customer
29
30 def register_restaurant(self, name: str, address: Address) -> Restaurant:
31 restaurant = Restaurant(name, address)
32 self.restaurants[restaurant.get_id()] = restaurant
33 return restaurant
34
35 def register_delivery_agent(self, name: str, phone: str, initial_location: Address) -> DeliveryAgent:
36 delivery_agent = DeliveryAgent(name, phone, initial_location)
37 self.delivery_agents[delivery_agent.get_id()] = delivery_agent
38 return delivery_agent
39
40 def place_order(self, customer_id: str, restaurant_id: str, items: List[OrderItem]) -> Order:
41 customer = self.customers.get(customer_id)
42 restaurant = self.restaurants.get(restaurant_id)
43 if customer is None or restaurant is None:
44 raise KeyError("Customer or Restaurant not found.")
45
46 order = Order(customer, restaurant, items)
47 self.orders[order.get_id()] = order
48 customer.add_order_to_history(order)
49 print(f"Order {order.get_id()} placed by {customer.get_name()} at {restaurant.get_name()}.")
50 order.set_status(OrderStatus.PENDING)
51 return order
52
53 def update_order_status(self, order_id: str, new_status: OrderStatus):
54 order = self.orders.get(order_id)
55 if order is None:
56 raise KeyError("Order not found.")
57
58 order.set_status(new_status)
59
60 if new_status == OrderStatus.READY_FOR_PICKUP:
61 self.assign_delivery(order)
62
63 def cancel_order(self, order_id: str):
64 order = self.orders.get(order_id)
65 if order is None:
66 print(f"ERROR: Order with ID {order_id} not found.")
67 return
68
69 if order.cancel():
70 print(f"SUCCESS: Order {order_id} has been successfully canceled.")
71 else:
72 print(f"FAILED: Order {order_id} could not be canceled. Its status is: {order.get_status().value}")
73
74 def assign_delivery(self, order: Order):
75 available_agents = list(self.delivery_agents.values())
76
77 best_agent = self.assignment_strategy.find_agent(order, available_agents)
78 if best_agent:
79 order.assign_delivery_agent(best_agent)
80 distance = best_agent.get_current_location().distance_to(order.get_restaurant().get_address())
81 print(f"Agent {best_agent.get_name()} (dist: {distance:.2f}) assigned to order {order.get_id()}.")
82 order.set_status(OrderStatus.OUT_FOR_DELIVERY)
83 else:
84 print(f"No available delivery agents found for order {order.get_id()}")
85
86 def search_restaurants(self, strategies: List[RestaurantSearchStrategy]) -> List[Restaurant]:
87 results = list(self.restaurants.values())
88
89 for strategy in strategies:
90 results = strategy.filter(results)
91
92 return results
93
94 def get_restaurant_menu(self, restaurant_id: str) -> Menu:
95 restaurant = self.restaurants.get(restaurant_id)
96 if restaurant is None:
97 raise KeyError(f"Restaurant with ID {restaurant_id} not found.")
98 return restaurant.get_menu()The demo class validates the end-to-end functionality by simulating a customer's journey from searching to receiving an order.
1class FoodDeliveryServiceDemo:
2 @staticmethod
3 def main():
4 # 1. Setup the system
5 service = FoodDeliveryService.get_instance()
6 service.set_assignment_strategy(NearestAvailableAgentStrategy())
7
8 # 2. Define Addresses
9 alice_address = Address("123 Maple St", "Springfield", "12345", 40.7128, -74.0060)
10 pizza_address = Address("456 Oak Ave", "Springfield", "12345", 40.7138, -74.0070)
11 burger_address = Address("789 Pine Ln", "Springfield", "12345", 40.7108, -74.0050)
12 taco_address = Address("101 Elm Ct", "Shelbyville", "54321", 41.7528, -75.0160)
13
14 # 3. Register entities
15 alice = service.register_customer("Alice", "123-4567-890", alice_address)
16 pizza_palace = service.register_restaurant("Pizza Palace", pizza_address)
17 burger_barn = service.register_restaurant("Burger Barn", burger_address)
18 taco_town = service.register_restaurant("Taco Town", taco_address)
19 service.register_delivery_agent("Bob", "321-4567-880", Address("1 B", "Springfield", "12345", 40.71, -74.00))
20
21 # 4. Setup menus
22 pizza_palace.add_to_menu(MenuItem("P001", "Margherita Pizza", 12.99))
23 pizza_palace.add_to_menu(MenuItem("P002", "Veggie Pizza", 11.99))
24 burger_barn.add_to_menu(MenuItem("B001", "Classic Burger", 8.99))
25 taco_town.add_to_menu(MenuItem("T001", "Crunchy Taco", 3.50))
26
27 # 5. Demonstrate Search Functionality
28 print("\n--- 1. Searching for Restaurants ---")
29
30 # (A) Search by City
31 print("\n(A) Restaurants in 'Springfield':")
32 city_search = [SearchByCityStrategy("Springfield")]
33 springfield_restaurants = service.search_restaurants(city_search)
34 for r in springfield_restaurants:
35 print(f" - {r.get_name()}")
36
37 # (B) Search for restaurants near Alice
38 print("\n(B) Restaurants near Alice (within 0.01 distance units):")
39 proximity_search = [SearchByProximityStrategy(alice_address, 0.01)]
40 nearby_restaurants = service.search_restaurants(proximity_search)
41 for r in nearby_restaurants:
42 distance = alice_address.distance_to(r.get_address())
43 print(f" - {r.get_name()} (Distance: {distance:.4f})")
44
45 # (C) Search for restaurants that serve 'Pizza'
46 print("\n(C) Restaurants that serve 'Pizza':")
47 menu_search = [SearchByMenuKeywordStrategy("Pizza")]
48 pizza_restaurants = service.search_restaurants(menu_search)
49 for r in pizza_restaurants:
50 print(f" - {r.get_name()}")
51
52 # (D) Combined Search: Find restaurants near Alice that serve 'Burger'
53 print("\n(D) Burger joints near Alice:")
54 combined_search = [
55 SearchByProximityStrategy(alice_address, 0.01),
56 SearchByMenuKeywordStrategy("Burger")
57 ]
58 burger_joints_near_alice = service.search_restaurants(combined_search)
59 for r in burger_joints_near_alice:
60 print(f" - {r.get_name()}")
61
62 # 6. Demonstrate Browsing a Menu
63 print("\n--- 2. Browsing a Menu ---")
64 print("\nMenu for 'Pizza Palace':")
65 pizza_menu = service.get_restaurant_menu(pizza_palace.get_id())
66 for item in pizza_menu.get_items().values():
67 print(f" - {item.get_name()}: ${item.get_price():.2f}")
68
69 # 7. Alice places an order from a searched restaurant
70 print("\n--- 3. Placing an Order ---")
71 if pizza_restaurants:
72 chosen_restaurant = pizza_restaurants[0]
73 chosen_item = chosen_restaurant.get_menu().get_item("P001")
74
75 print(f"\nAlice is ordering '{chosen_item.get_name()}' from '{chosen_restaurant.get_name()}'.")
76 order = service.place_order(alice.get_id(), chosen_restaurant.get_id(), [OrderItem(chosen_item, 1)])
77
78 print("\n--- Restaurant starts preparing the order ---")
79 service.update_order_status(order.get_id(), OrderStatus.PREPARING)
80
81 print("\n--- Order is ready for pickup ---")
82 print("System will now find the nearest available delivery agent...")
83 service.update_order_status(order.get_id(), OrderStatus.READY_FOR_PICKUP)
84
85 print("\n--- Agent delivers the order ---")
86 service.update_order_status(order.get_id(), OrderStatus.DELIVERED)
87
88
89if __name__ == "__main__":
90 FoodDeliveryServiceDemo.main()Which entity should maintain the collection of offered dishes for each restaurant in an online food delivery platform?
No comments yet. Be the first to comment!