Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
An online shopping system like Amazon is a software application that allows customers to purchase goods and services over the internet. The system typically includes a user-friendly interface for browsing and searching products, a shopping cart for adding and removing items, and a checkout process for placing an order and making a payment. The system also includes features for tracking order history and status, managing account information, and tracking shipping status.
To ensure a successful implementation, the system must meet both functional and non-functional requirements, such as performance, security, scalability, usability, reliability, compatibility, and maintainability. The system can be built using various programming languages, C++ being one of them.
System Requirements
Software development relies on system requirements to guide the development process. These requirements give us a complete understanding of what the system should do and how it should perform. There are two main types of requirements - functional and non-functional.
Functional requirements outline the core functionality of the system. They tell us what tasks the system should perform and describe the user interactions. These requirements must be specific, measurable, and achievable.
On the other hand, non-functional requirements deal with the system's operational characteristics, such as performance, security, reliability, and usability. These requirements ensure the system performs optimally and meets the user's expectations in different situations.
Functional Requirements for Online Shopping System
Some examples of functional requirements for an online shopping system include the following:
The ability to browse and search for products
The ability to add items to a shopping cart
The ability to place an order
The ability to make a payment
The ability to view order history and status
The ability to manage account information
The ability to track the shipping status of an order
The ability to receive an order confirmation
Non-Functional Requirements for Online Shopping System
Some examples of non-functional requirements for an online shopping system include the following:
Performance: The system should be able to handle a high volume of traffic and transactions without significant delays.
Security: The system should protect customer data and transactions from unauthorized access.
Scalability: The system should be able to handle an increase in traffic and transactions without significant degradation in performance.
Usability: The system should be easy to navigate and use for customers.
Reliability: The system should be reliable and always up and running with minimal downtime
Compatibility: The system should be compatible with different web browsers and devices.
Maintainability: The system should be easily maintainable and adaptable to changing requirements.
Functional and non-functional requirements work together to define the complete picture of a system, and their satisfaction is necessary for the system to be successful.
Entities and Relationships in an Online Shopping System
Entities and relationships are fundamental concepts in system design that help to model the real-world objects and their relationships with each other.
Entities are objects or concepts in the real world that we want to model in the system.
Relationships describe the interactions and connections between entities.
Think of entities as nouns and relationships as verbs. The goal of modeling entities and relationships is to capture the essence of real-world objects and their interactions and to represent them in an easy way to understand and maintain.
In an online shopping system, there are several entities and their relationships that are important to consider:
Product: This entity represents the products that are available for purchase in the online store. It would have properties such as a name, description, price, and stock level.
Customer: This entity represents the online store's customers and would have properties such as a name, address, and email address.
Order: This entity represents an order placed by a customer and would have properties such as the customer's information, the products ordered, and the total cost.
Shopping Cart: This entity represents a customer's shopping cart and would have a relationship with the Product entity, allowing customers to add and remove products from their cart.
Payment: This entity represents the payment process and would have a relationship with the Order entity, allowing customers to make a payment for their order.
Shipping: This entity represents the shipping process and would have a relationship with the Order entity, allowing customers to track the shipping status of their order.
Admin: This entity represents the admin tasks; it would have a relationship with the Product, Order, and Customer entities, allowing them to add new products, update stock levels, manage orders, and manage customer data.
Inventory: This entity represents the store's inventory and would have a relationship with the Product entity, allowing it to have information about the products available in the store and the stock level of each product.
These entities and their relationships form the foundation of the online shopping system and must be carefully designed and implemented to ensure the system's functionality and scalability.
Class Diagram
A class diagram is a type of UML (Unified Modeling Language) diagram that represents the object-oriented structure of a system. It is used to model the static aspects of an object-oriented software system and the relationships between classes and their objects.
In a class diagram, each class is represented by a rectangle that contains its name, attributes, and operations. Classes can be related to each other using various types of relationships such as inheritance, aggregation, and association.
This code defines several classes that represent different aspects of a retail store.
The Product class represents a product sold in the store, and it has various properties such as name, description, price, and stock level.
The ShoppingCart class represents a customer's shopping cart, and it provides functionality for adding and removing products from the cart, and calculating the total cost of the items in the cart.
The Customer class represents a customer and has properties such as name, address, and email.
The Inventory class represents the store's inventory and provides functionality for adding products to the inventory, updating the stock level of a product, checking if a product is in stock, and restocking a product.
The Payment class represents a payment made by a customer and has properties such as the payment amount and payment method.
For a comprehensive understanding of class diagrams, including what they are and how they are created, please refer to this article.
Use Case Diagram
A Use Case diagram is a type of Unified Modeling Language (UML) diagram that represents the interactions between a system, its users, and external actors with the goal of achieving specific business goals or objectives. The main purpose of use case diagrams is to capture the requirements of a system and to describe the interactions between the system and its users.
Code in C++
#include<bits/stdc++.h>
using namespace std;
class Product {
private:
string name;
string description;
double price;
int stockLevel;
public:
// constructor
Product(string name, string description, double price, int stockLevel) {
this->name = name;
this->description = description;
this->price = price;
this->stockLevel = stockLevel;
}
// getters and setters
const string& getName() const { return name; }
const string& getDescription() const { return description; }
double getPrice() const { return price; }
int getStockLevel() const { return stockLevel; }
void setName(string name) { this->name = name; }
void setDescription(string description) { this->description = description; }
void setPrice(double price) { this->price = price; }
void setStockLevel(int stockLevel) { this->stockLevel = stockLevel; }
// operator overloading
bool operator==(const Product& p) const {
return (getName() == p.getName() && getDescription() == p.getDescription() && getPrice() == p.getPrice() && getStockLevel() == p.getStockLevel());
}
};
namespace std {
template<>
struct hash<Product> {
size_t operator()(const Product& p) const {
size_t h1 = hash<string>()(p.getName());
size_t h2 = hash<string>()(p.getDescription());
size_t h3 = hash<double>()(p.getPrice());
size_t h4 = hash<int>()(p.getStockLevel());
return h1 ^ h2 ^ h3 ^ h4;
}
};
template<>
struct equal_to<Product> {
bool operator()(const Product& p1, const Product& p2) const {
return p1 == p2;
}
};
}
class ShoppingCart {
private:
std::vector<Product> products;
public:
// constructor
ShoppingCart() {}
// add product to cart
void addProduct(Product product) { products.push_back(product); }
// remove product from cart
void removeProduct(Product product) {
for (auto it = products.begin(); it != products.end(); it++) {
if (*it == product) {
products.erase(it);
break;
}
}
}
// calculate total cost of items in cart
double totalCost(){
double total = 0;
for (const Product& p : products) {
total += p.getPrice();
}
return total;
}
};
class Customer {
private:
std::string name;
std::string address;
std::string email;
public:
Customer() : name(""), address(""), email("") { }
Customer(std::string name, std::string address, std::string email) :
name(name), address(address), email(email) { }
std::string getName() const { return name; }
std::string getAddress() const { return address; }
std::string getEmail() const { return email; }
void setName(std::string name) { this->name = name; }
void setAddress(std::string address) { this->address = address; }
void setEmail(std::string email) { this->email = email; }
bool operator==(const Customer& other) const {
return name == other.name && address == other.address && email == other.email;
}
};
class Inventory {
private:
std::unordered_map<Product, int> products;
public:
// constructor
Inventory(){};
// method to add a product to the inventory
void addProduct(Product product, int stock) {
products[product] = stock;
}
// method to update the stock level of a product
void updateStock(Product product, int stock) {
products[product] = stock;
}
// method to check if a product is in stock
bool isInStock(Product product) {
return products[product] > 0;
}
// method to restock a product
void restock(Product product, int quantity) {
products[product] += quantity;
}
};
class Payment {
private:
double amount;
string paymentMethod;
public:
// constructor
Payment() : paymentMethod(""), amount(0) { }
Payment(double amount, string paymentMethod) {
this->amount = amount;
this->paymentMethod = paymentMethod;
}
// getters and setters
double getAmount() const { return amount; }
string getPaymentMethod() const { return paymentMethod; }
void setAmount(double amount) { this->amount = amount; }
void setPaymentMethod(string paymentMethod) { this->paymentMethod = paymentMethod; }
// payment method functions
void payWithCreditCard() { /* code to process credit card payment */ }
void payWithDebitCard() { /* code to process debit card payment */ }
void payWithNetBanking() { /* code to process net banking payment */ }
};
class Shipping {
private:
string shippingMethod;
double shippingCost;
public:
// constructor
Shipping() : shippingMethod(""), shippingCost(0.0) { }
Shipping(string shippingMethod, double shippingCost) {
this->shippingMethod = shippingMethod;
this->shippingCost = shippingCost;
}
// getters and setters
string getShippingMethod() { return shippingMethod; }
double getShippingCost() { return shippingCost; }
void setShippingMethod(string shippingMethod) { this->shippingMethod = shippingMethod; }
void setShippingCost(double shippingCost) { this->shippingCost = shippingCost; }
};
class Order {
private:
Customer customer;
vector<Product> products;
double totalCost;
Payment payment;
Shipping shipping;
public:
// constructor
Order(Customer customer, vector<Product> products, double totalCost, Payment payment, Shipping shipping) {
this->customer = customer;
this->products = products;
this->totalCost = totalCost;
this->payment = payment;
this->shipping = shipping;
}
// getters and setters
Customer getCustomer() { return customer; }
vector<Product> getProducts() { return products; }
double getTotalCost() { return totalCost; }
Payment getPayment() { return payment; }
Shipping getShipping() { return shipping; }
void setCustomer(Customer customer) { this->customer = customer; }
void setProducts(vector<Product> products) { this->products = products; }
void setTotalCost(double totalCost) { this->totalCost = totalCost; }
void setPayment(Payment payment) { this->payment = payment; }
void setShipping(Shipping shipping) { this->shipping = shipping; }
// operator overloading for comparing two orders
bool operator==(const Order& o) {
return (customer == o.customer && products == o.products && totalCost == o.totalCost);
}
};
class Admin {
private:
Inventory inventory;
vector<Product> products;
vector<Customer> customers;
vector<Order> orders;
public:
// constructor
Admin() {}
// methods for adding and updating products
void addProduct(Product product) { products.push_back(product); }
void updateProduct(Product product) {
for (int i = 0; i < products.size(); i++) {
if (products[i] == product) {
products[i] = product;
break;
}
}
}
// methods for managing stock level
void updateStockLevel(Product product, int stockLevel) {
for (int i = 0; i < products.size(); i++) {
if (products[i] == product) {
products[i].setStockLevel(stockLevel);
break;
}
}
}
// methods for managing orders
void addOrder(Order order) { orders.push_back(order); }
void updateOrder(Order order) {
for (int i = 0; i < orders.size(); i++) {
if (orders[i] == order) {
orders[i] = order;
break;
}
}
}
// methods for managing customer data
void addCustomer(Customer customer) { customers.push_back(customer); }
void updateCustomer(Customer customer) {
for (int i = 0; i < customers.size(); i++) {
if (customers[i] == customer) {
customers[i] = customer;
break;
}
}
}
};
int main() {
// Create a new product
Product p1("iPhone", "New iPhone", 999.99, 10);
// Create a new inventory
Inventory inventory;
// Add the product to the inventory
inventory.addProduct(p1, 10);
// Create a new customer
Customer c1("John Smith", "123 Main St", "johnsmith@email.com");
// Create a new shopping cart
ShoppingCart cart;
// Add the product to the cart
cart.addProduct(p1);
// Check if the product is in stock
if (inventory.isInStock(p1)) {
cout << "Product is in stock" << endl;
} else {
cout << "Product is out of stock" << endl;
}
// Print the total cost of items in the cart
cout << "Total cost: Rs" << cart.totalCost() << endl;
// Create a new payment
Payment payment(cart.totalCost(), "Credit Card");
// Print the payment details
cout << "Payment amount: Rs" << payment.getAmount() << endl;
cout << "Payment method: " << payment.getPaymentMethod() << endl;
return 0;
}
You can also try this code with Online C++ Compiler
Product is in stock
Total cost: Rs999.99
Payment amount: Rs999.99
Payment method: Credit Card
Code Explanation
This code defines a few classes that are used to model a simple e-commerce application. The classes include:
Product: A class representing a product with a name, description, price, and stock level. It has a constructor, getters, and setters for its properties and an operator overload for equality comparison.
ShoppingCart: A class that represents a shopping cart. It has a vector of products, a constructor, methods to add and remove products, and a method to calculate the total cost of the items in the cart.
Customer: A class representing a customer with a name, address, and email. It has a constructor, getters, and setters for its properties and also an operator overload for equality comparison.
Inventory: A class that represents an inventory. It has an unordered map of products with an integer representing the stock level. It has methods to add and update products and check if a product is in stock, and a method to restock a product.
Payment: A class that represents a payment with an amount and a payment method. It has a constructor, getters, and setters for its properties.
The code also defines some customizations to the standard library, like the hash function and equal_to function for the Product class, that allows it to be used as a key in unordered_map.
The code uses several data structures and algorithms:
Class Product: This class represents a product and contains its name, description, price, and stock level. It also overloads the == operator and defines a hash function and an equal_to function in the std namespace to enable it to be used as a key in an unordered_map.
std::vector in class ShoppingCart: This class uses a vector to store the products in the cart. The addProduct method adds a product to the vector, and the removeProduct method removes a product from the vector.
std::unordered_map in class Inventory: This class uses an unordered_map to store the products in the inventory, with the product as the key and the stock level as the value. The addProduct method adds a product to the map, the updateStock method updates the stock level of a product, the isInStock method checks if a product is in stock, and the restock method restocks a product.
STL Iterator in class ShoppingCart: removeProduct method uses an iterator (auto it) to traverse the products in the vector and find the product to be removed.
Overloading the operator in class Customer, Product: Both classes overload the == operator to compare the equality of two objects.
Frequently Asked Questions
What is Monolithic Architecture?
Monolithic architecture is a software design pattern in which an application is built as a single, integrated, self-contained unit. In this architecture, all the application components, such as the user interface, business logic, and data storage, are combined into a single executable. The monolithic architecture is simple and straightforward to design, develop, and deploy, as all the components are tightly coupled and share a common runtime environment.
What is Availability?
Availability in system design refers to the proportion of time that a system is operational and able to serve user requests. It measures the reliability and robustness of a system and indicates how often a system is expected to be available for use.
What is Consistency?
Consistency in system design refers to the state of data in a system, where all clients accessing the system see the same data at a given point in time. This means that any changes made to the data by one client are immediately visible to all other clients accessing the system.
Conclusion
In conclusion, an online shopping system is a software application that enables customers to purchase goods and services over the internet. The system is designed to meet both functional and non-functional requirements, such as performance, security, scalability, usability, reliability, compatibility, and maintainability.
The system is built using various programming languages, and C++ is one of them. The system comprises several entities and their relationships, such as Product, Customer, Order, Shopping Cart, Payment, Shipping, Admin, and Inventory, which are crucial for the system's functionality and scalability. In order to ensure a successful implementation, these entities and their relationships must be carefully designed and implemented.
Now that you know the Online Shopping system's low-level design, go ahead and try out various system design related problems asked by various product-based companies.
Don't stop here. Check out our System Design-guided path to learn System Design from scratch. You can also consider our System Design Course to give your career an edge over others.
We hope you found this blog useful. Feel free to let us know your thoughts in the comments section.