Online Book Store Using OOP in LLD

Last Updated : 24 Sep, 2025

Here we discussed An Online Book Store allows users to search, browse, and purchase books online Using OOP in LLD, we break the system into classes (Book, User, Cart, Order, Payment, etc.), each handling a clear responsibility.

Let's understand this with the help of Diagram:

online-book-store--

We used OOP principles in the Online Bookstore with the help of LLD concept:

  • Encapsulation - Each class (Book, User, CartItem, ShoppingCart, etc.) bundles its data and methods together, hiding internal details.
  • Abstraction - Payment class hides the complexity of processing payments, exposing only a simple processPayment() method.
  • Composition - Larger objects are built using smaller ones (e.g., ShoppingCart contains CartItems, Order contains CartItems and User).
  • Separation of Concerns (Single Responsibility Principle) - Every class has one clear purpose (e.g., Book for book info, ShoppingCart for managing cart, Order for handling purchases).
  • Reusability - Classes like Book, User, and Payment can be reused in other contexts without changes.

Below we will discuss step-by-step:

1. Book Class-Represent entity book

Represents a book with details like title, author, ISBN, and price.

C++
#include <string>
class Book {
private:
    std::string title;
    std::string author;
    std::string isbn;
    double price;

public:
    Book(std::string title, std::string author, std::string isbn, double price) {
        this->title = title;
        this->author = author;
        this->isbn = isbn;
        this->price = price;
    }

    std::string getTitle() { return title; }
    std::string getAuthor() { return author; }
    std::string getIsbn() { return isbn; }
    double getPrice() { return price; }
};
Java
class Book {
    private String title;
    private String author;
    private String isbn;
    private double price;

    // Constructor
    public Book(String title, String author, String isbn, double price) {
        this.title = title;
        this.author = author;
        this->isbn = isbn;
        this->price = price;
    }

    // Getter methods
    public String getTitle() { return title; }
    public String getAuthor() { return author; }
    public String getIsbn() { return isbn; }
    public double getPrice() { return price; }
}
Python
class Book:
    def __init__(self, title, author, isbn, price):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.price = price

    # Getter methods
    def get_title(self):
        return self.title
    def get_author(self):
        return self.author
    def get_isbn(self):
        return self.isbn
    def get_price(self):
        return self.price
JavaScript
class Book {
    constructor(title, author, isbn, price) {
        this.title = title;
        this.author = author;
        this.isbn = isbn;
        this.price = price;
    }

    // Getter methods
    getTitle() { return this.title; }
    getAuthor() { return this.author; }
    getIsbn() { return this.isbn; }
    getPrice() { return this.price; }
}

2. User Class – Represents a customer

Represents a user with basic details like name and email.

C++
#include <string>

class User {
private:
    std::string name;
    std::string email;

public:
    // Constructor
    User(const std::string& name, const std::string& email) {
        this->name = name;
        this->email = email;
    }

    // Getter methods
    std::string getName() { return name; }
    std::string getEmail() { return email; }
};
C
#include <stdio.h>
#include <string.h>

typedef struct {
    char name[50];
    char email[50];
} User;

// Constructor
void createUser(User *user, const char *name, const char *email) {
    strcpy(user->name, name);
    strcpy(user->email, email);
}

// Getter methods
const char *getName(User *user) { return user->name; }
const char *getEmail(User *user) { return user->email; }
Java
class User {
    private String name;
    private String email;

    // Constructor
    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }

    // Getter methods
    public String getName() { return name; }
    public String getEmail() { return email; }
}
JavaScript
class User {
    constructor(name, email) {
        this.name = name;
        this.email = email;
    }

    // Getter methods
    getName() { return this.name; }
    getEmail() { return this.email; }
}

3. CartItem Class – Represents one book in the cart

A single book item inside the shopping cart with quantity.

C++
#include <iostream>
#include <string>

class Book {
public:
    double getPrice() { return price; }
    std::string getTitle() { return title; }
    Book(double p, std::string t) : price(p), title(t) {}
private:
    double price;
    std::string title;
};

class CartItem {
private:
    Book book;
    int quantity;
public:
    CartItem(Book b, int q) : book(b), quantity(q) {}
    double getTotalPrice() { return book.getPrice() * quantity; }
    Book getBook() { return book; }
    int getQuantity() { return quantity; }
};
Java
class Book {
    private double price;
    private String title;

    public Book(double price, String title) {
        this.price = price;
        this.title = title;
    }

    public double getPrice() {
        return price;
    }

    public String getTitle() {
        return title;
    }
}

class CartItem {
    private Book book;
    private int quantity;

    public CartItem(Book book, int quantity) {
        this.book = book;
        this.quantity = quantity;
    }

    public double getTotalPrice() {
        return book.getPrice() * quantity;
    }

    public Book getBook() { return book; }
    public int getQuantity() { return quantity; }
}
Python
class Book:
    def __init__(self, price, title):
        self.price = price
        self.title = title

    def get_price(self):
        return self.price

    def get_title(self):
        return self.title

class CartItem:
    def __init__(self, book, quantity):
        self.book = book
        self.quantity = quantity

    def get_total_price(self):
        return self.book.get_price() * self.quantity

    def get_book(self):
        return self.book

    def get_quantity(self):
        return self.quantity
JavaScript
class Book {
    constructor(price, title) {
        this.price = price;
        this.title = title;
    }

    getPrice() {
        return this.price;
    }

    getTitle() {
        return this.title;
    }
}

class CartItem {
    constructor(book, quantity) {
        this.book = book;
        this.quantity = quantity;
    }

    getTotalPrice() {
        return this.book.getPrice() * this.quantity;
    }

    getBook() {
        return this.book;
    }

    getQuantity() {
        return this.quantity;
    }
}

4. ShoppingCart Class – Holds multiple books

Represents the shopping cart where users add/remove books and calculate total.

C++
#include <vector>
#include <string>
#include <algorithm>

class Book {
public:
    std::string isbn;
    double price;
};

class CartItem {
public:
    Book book;
    int quantity;
    double getTotalPrice() {
        return book.price * quantity;
    }
};

class ShoppingCart {
private:
    std::vector<CartItem> items;
public:
    ShoppingCart() {}

    // Add book to cart
    void addBook(Book book, int quantity) {
        items.push_back(CartItem{book, quantity});
    }

    // Remove book from cart
    void removeBook(const Book& book) {
        items.erase(std::remove_if(items.begin(), items.end(), [&](const CartItem& item) {
            return item.book.isbn == book.isbn;
        }), items.end());
    }

    // Calculate total price
    double calculateTotal() {
        return std::accumulate(items.begin(), items.end(), 0.0, [](double sum, const CartItem& item) {
            return sum + item.getTotalPrice();
        });
    }

    std::vector<CartItem> getItems() {
        return items;
    }
};
C
#include <stdio.h>
#include <stdlib.h>

typedef struct Book {
    char* isbn;
    double price;
} Book;

typedef struct CartItem {
    Book book;
    int quantity;
} CartItem;

typedef struct ShoppingCart {
    CartItem* items;
    int itemCount;
} ShoppingCart;

ShoppingCart* createShoppingCart() {
    ShoppingCart* cart = (ShoppingCart*)malloc(sizeof(ShoppingCart));
    cart->items = NULL;
    cart->itemCount = 0;
    return cart;
}

void addBook(ShoppingCart* cart, Book book, int quantity) {
    cart->itemCount++;
    cart->items = (CartItem*)realloc(cart->items, cart->itemCount * sizeof(CartItem));
    cart->items[cart->itemCount - 1].book = book;
    cart->items[cart->itemCount - 1].quantity = quantity;
}

void removeBook(ShoppingCart* cart, char* isbn) {
    int i, j;
    for (i = 0; i < cart->itemCount; i++) {
        if (strcmp(cart->items[i].book.isbn, isbn) == 0) {
            for (j = i; j < cart->itemCount - 1; j++) {
                cart->items[j] = cart->items[j + 1];
            }
            cart->itemCount--;
            cart->items = (CartItem*)realloc(cart->items, cart->itemCount * sizeof(CartItem));
            break;
        }
    }
}

double calculateTotal(ShoppingCart* cart) {
    double total = 0;
    for (int i = 0; i < cart->itemCount; i++) {
        total += cart->items[i].book.price * cart->items[i].quantity;
    }
    return total;
}
Java
import java.util.*;

class ShoppingCart {
    private List<CartItem> items;

    public ShoppingCart() {
        this.items = new ArrayList<>();
    }

    // Add book to cart
    public void addBook(Book book, int quantity) {
        items.add(new CartItem(book, quantity));
    }

    // Remove book from cart
    public void removeBook(Book book) {
        items.removeIf(item -> item.getBook().getIsbn().equals(book.getIsbn()));
    }

    // Calculate total price
    public double calculateTotal() {
        return items.stream().mapToDouble(CartItem::getTotalPrice).sum();
    }

    public List<CartItem> getItems() {
        return items;
    }
}
JavaScript
class Book {
    constructor(isbn, price) {
        this.isbn = isbn;
        this.price = price;
    }
}

class CartItem {
    constructor(book, quantity) {
        this.book = book;
        this.quantity = quantity;
    }

    getTotalPrice() {
        return this.book.price * this.quantity;
    }
}

class ShoppingCart {
    constructor() {
        this.items = [];
    }

    // Add book to cart
    addBook(book, quantity) {
        this.items.push(new CartItem(book, quantity));
    }

    // Remove book from cart
    removeBook(book) {
        this.items = this.items.filter(item => item.book.isbn !== book.isbn);
    }

    // Calculate total price
    calculateTotal() {
        return this.items.reduce((sum, item) => sum + item.getTotalPrice(), 0);
    }

    getItems() {
        return this.items;
    }
}

5. Order Class – Represents an order

Represents an order placed by a user with books, total price, and order status.

C++
#include <vector>
#include <string>
#include <numeric>

class User {};
class CartItem { public: double getTotalPrice() { return 0.0; } };

class Order {
private:
    User user;
    std::vector<CartItem> items;
    double totalAmount;
    std::string status;

public:
    Order(User user, std::vector<CartItem> items) : user(user), items(items), status("Pending") {
        totalAmount = std::accumulate(items.begin(), items.end(), 0.0, [](double sum, const CartItem& item) {
            return sum + item.getTotalPrice();
        });
    }

    void setStatus(std::string status) { this->status = status; }
    double getTotalAmount() { return totalAmount; }
    std::string getStatus() { return status; }
    User getUser() { return user; }
};
Java
import java.util.*;

class Order {
    private User user;
    private List<CartItem> items;
    private double totalAmount;
    private String status;

    public Order(User user, List<CartItem> items) {
        this.user = user;
        this.items = items;
        this.totalAmount = items.stream().mapToDouble(CartItem::getTotalPrice).sum();
        this.status = "Pending";
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public double getTotalAmount() { return totalAmount; }
    public String getStatus() { return status; }
    public User getUser() { return user; }
}
Python
from typing import List

class User: pass
class CartItem:
    def get_total_price(self) -> float:
        return 0.0

class Order:
    def __init__(self, user: User, items: List[CartItem]):
        self.user = user
        self.items = items
        self.total_amount = sum(item.get_total_price() for item in items)
        self.status = 'Pending'

    def set_status(self, status: str):
        self.status = status

    def get_total_amount(self) -> float:
        return self.total_amount

    def get_status(self) -> str:
        return self.status

    def get_user(self) -> User:
        return self.user
JavaScript
class User {}
class CartItem {
    getTotalPrice() {
        return 0.0;
    }
}

class Order {
    constructor(user, items) {
        this.user = user;
        this.items = items;
        this.totalAmount = items.reduce((sum, item) => sum + item.getTotalPrice(), 0);
        this.status = 'Pending';
    }

    setStatus(status) {
        this.status = status;
    }

    getTotalAmount() {
        return this.totalAmount;
    }

    getStatus() {
        return this.status;
    }

    getUser() {
        return this.user;
    }
}

6. Payment Class – Handles payment processing

Simulates a payment process for an order.

C++
#include <iostream>
#include <string>

class User {
public:
    std::string getName() { return "John Doe"; }
};

class Payment {
public:
    bool processPayment(User user, double amount) {
        std::cout << "Processing payment of $" << amount << " for " << user.getName() << std::endl;
        return true; // always successful in this demo
    }
};
Java
class User {
    public String getName() {
        return "John Doe";
    }
}

class Payment {
    public boolean processPayment(User user, double amount) {
        System.out.println("Processing payment of $" + amount + " for " + user.getName());
        return true; // always successful in this demo
    }
}
Python
class User:
    def getName(self):
        return "John Doe"

class Payment:
    def processPayment(self, user, amount):
        print(f'Processing payment of ${amount} for {user.getName()}')
        return True  # always successful in this demo
JavaScript
class User {
    getName() {
        return "John Doe";
    }
}

class Payment {
    processPayment(user, amount) {
        console.log(`Processing payment of $${amount} for ${user.getName()}`);
        return true; // always successful in this demo
    }
}

7. BookStore Class – main controller

Maintains the catalog of books, allows searching and displaying available books.

C++
#include <iostream>
#include <vector>
#include <string>

class Book {
public:
    std::string title;
    std::string author;
    double price;

    Book(std::string t, std::string a, double p) : title(t), author(a), price(p) {}
    std::string getTitle() { return title; }
    std::string getAuthor() { return author; }
    double getPrice() { return price; }
};

class BookStore {
private:
    std::vector<Book> catalog;

public:
    BookStore() {}

    void addBook(Book book) {
        catalog.push_back(book);
    }

    Book* searchByTitle(std::string title) {
        for (Book& b : catalog) {
            if (b.getTitle() == title) {
                return &b;
            }
        }
        return nullptr;
    }

    void displayBooks() {
        std::cout << "Available Books:\n";
        for (Book& b : catalog) {
            std::cout << b.getTitle() << " by " << b.getAuthor() << " - $" << b.getPrice() << "\n";
        }
    }
};
Java
import java.util.ArrayList;
import java.util.List;

class Book {
    private String title;
    private String author;
    private double price;

    public Book(String title, String author, double price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public double getPrice() {
        return price;
    }
}

class BookStore {
    private List<Book> catalog;

    public BookStore() {
        catalog = new ArrayList<>();
    }

    public void addBook(Book book) {
        catalog.add(book);
    }

    public Book searchByTitle(String title) {
        for (Book b : catalog) {
            if (b.getTitle().equalsIgnoreCase(title)) {
                return b;
            }
        }
        return null;
    }

    public void displayBooks() {
        System.out.println("Available Books:");
        for (Book b : catalog) {
            System.out.println(b.getTitle() + " by " + b.getAuthor() + " - $" + b.getPrice());
        }
    }
}
Python
class Book:
    def __init__(self, title, author, price):
        self.title = title
        self.author = author
        self.price = price

    def get_title(self):
        return self.title

    def get_author(self):
        return self.author

    def get_price(self):
        return self.price

class BookStore:
    def __init__(self):
        self.catalog = []

    def add_book(self, book):
        self.catalog.append(book)

    def search_by_title(self, title):
        for b in self.catalog:
            if b.get_title().lower() == title.lower():
                return b
        return None

    def display_books(self):
        print('Available Books:')
        for b in self.catalog:
            print(f'{b.get_title()} by {b.get_author()} - ${b.get_price()}')
JavaScript
class Book {
    constructor(title, author, price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }

    getTitle() {
        return this.title;
    }

    getAuthor() {
        return this.author;
    }

    getPrice() {
        return this.price;
    }
}

class BookStore {
    constructor() {
        this.catalog = [];
    }

    addBook(book) {
        this.catalog.push(book);
    }

    searchByTitle(title) {
        for (let b of this.catalog) {
            if (b.getTitle().toLowerCase() === title.toLowerCase()) {
                return b;
            }
        }
        return null;
    }

    displayBooks() {
        console.log('Available Books:')
        for (let b of this.catalog) {
            console.log(`${b.getTitle()} by ${b.getAuthor()} - $${b.getPrice()}`);
        }
    }
}

Complete code:

Here Runs the flow user browses books, adds to cart, places an order, and processes payment

C++
#include <iostream>
#include <vector>
#include <string>
using namespace std;

// ---- Book Class ----
class Book {
    string title, author, isbn;
    double price;
public:
    Book(string t, string a, string i, double p) : title(t), author(a), isbn(i), price(p) {}
    string getTitle() { return title; }
    double getPrice() { return price; }
    string toString() {
        return title + " by " + author + " (ISBN: " + isbn + ") - $" + to_string(price);
    }
};

// ---- User Class ----
class User {
    string name, email;
public:
    User(string n, string e) : name(n), email(e) {}
    string getName() { return name; }
};

// ---- CartItem Class ----
class CartItem {
    Book book;
    int quantity;
public:
    CartItem(Book b, int q) : book(b), quantity(q) {}
    double getTotalPrice() { return book.getPrice() * quantity; }
    Book getBook() { return book; }
};

// ---- ShoppingCart Class ----
class ShoppingCart {
    vector<CartItem> items;
public:
    void addBook(Book book, int qty) { items.push_back(CartItem(book, qty)); }
    vector<CartItem> getItems() { return items; }
    double calculateTotal() {
        double total = 0;
        for (auto &i : items) total += i.getTotalPrice();
        return total;
    }
};

// ---- Order Class ----
class Order {
    User user;
    vector<CartItem> items;
    double totalAmount;
    string status;
public:
    Order(User u, vector<CartItem> it) : user(u), items(it), status("Pending") {
        totalAmount = 0;
        for (auto &i : items) totalAmount += i.getTotalPrice();
    }
    double getTotalAmount() { return totalAmount; }
    string getStatus() { return status; }
    void setStatus(string s) { status = s; }
};

// ---- Payment Class ----
class Payment {
public:
    bool processPayment(User user, double amount) {
        cout << "Processing payment of $" << amount << " for " << user.getName() << endl;
        return true;
    }
};

// ---- BookStore Class ----
class BookStore {
    vector<Book> books;
public:
    void addBook(Book book) { books.push_back(book); }
    void displayBooks() {
        cout << "Available Books:\n";
        for (auto &b : books) cout << b.toString() << endl;
    }
    Book* searchByTitle(string title) {
        for (auto &b : books) {
            if (b.getTitle() == title) return &b;
        }
        return nullptr;
    }
};

// ---- Main ----
int main() {
    BookStore store;
    store.addBook(Book("Clean Code", "Robert C. Martin", "111", 40.0));
    store.addBook(Book("Design Patterns", "GoF", "222", 50.0));

    User user("Alice", "alice@email.com");

    store.displayBooks();
    ShoppingCart cart;
    Book* book1 = store.searchByTitle("Clean Code");
    if (book1) cart.addBook(*book1, 2);

    Order order(user, cart.getItems());
    Payment payment;
    if (payment.processPayment(user, order.getTotalAmount())) {
        order.setStatus("Paid");
    }

    cout << "Order Status: " << order.getStatus() << endl;
    return 0;
}
Java
import java.util.*;

// ---- Book Class ----
class Book {
    private String title;
    private String author;
    private String isbn;
    private double price;

    public Book(String title, String author, String isbn, double price) {
        this.title = title;
        this.author = author;
        this.isbn = isbn;
        this.price = price;
    }

    public String getTitle() { return title; }
    public double getPrice() { return price; }

    @Override
    public String toString() {
        return title + " by " + author + " (ISBN: " + isbn + ") - $" + price;
    }
}

// ---- User Class ----
class User {
    private String name;
    private String email;
    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }
    public String getName() { return name; }
}

// ---- CartItem Class ----
class CartItem {
    private Book book;
    private int quantity;

    public CartItem(Book book, int quantity) {
        this.book = book;
        this.quantity = quantity;
    }

    public double getTotalPrice() { return book.getPrice() * quantity; }
    public Book getBook() { return book; }
    public int getQuantity() { return quantity; }
}

// ---- ShoppingCart Class ----
class ShoppingCart {
    private List<CartItem> items = new ArrayList<>();

    public void addBook(Book book, int quantity) {
        items.add(new CartItem(book, quantity));
    }

    public List<CartItem> getItems() { return items; }

    public double calculateTotal() {
        double total = 0;
        for (CartItem item : items) {
            total += item.getTotalPrice();
        }
        return total;
    }
}

// ---- Order Class ----
class Order {
    private User user;
    private List<CartItem> items;
    private double totalAmount;
    private String status;

    public Order(User user, List<CartItem> items) {
        this.user = user;
        this.items = items;
        this.totalAmount = calculateTotal();
        this.status = "Pending";
    }

    private double calculateTotal() {
        double total = 0;
        for (CartItem item : items) {
            total += item.getTotalPrice();
        }
        return total;
    }

    public double getTotalAmount() { return totalAmount; }
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
}

// ---- Payment Class ----
class Payment {
    public boolean processPayment(User user, double amount) {
        System.out.println("Processing payment of $" + amount + " for " + user.getName());
        return true; // mock success
    }
}

// ---- BookStore Class ----
class BookStore {
    private List<Book> books = new ArrayList<>();

    public void addBook(Book book) { books.add(book); }

    public void displayBooks() {
        System.out.println("Available Books:");
        for (Book b : books) System.out.println(b);
    }

    public Book searchByTitle(String title) {
        for (Book b : books) {
            if (b.getTitle().equalsIgnoreCase(title)) return b;
        }
        return null;
    }
}

// ---- Main Class ----
public class Main {
    public static void main(String[] args) {
        BookStore store = new BookStore();
        store.addBook(new Book("Clean Code", "Robert C. Martin", "111", 40.0));
        store.addBook(new Book("Design Patterns", "GoF", "222", 50.0));

        User user = new User("Alice", "alice@email.com");

        store.displayBooks();
        ShoppingCart cart = new ShoppingCart();
        Book book1 = store.searchByTitle("Clean Code");
        if (book1 != null) cart.addBook(book1, 2);

        Order order = new Order(user, cart.getItems());
        Payment payment = new Payment();
        if (payment.processPayment(user, order.getTotalAmount())) {
            order.setStatus("Paid");
        }

        System.out.println("Order Status: " + order.getStatus());
    }
}
Python
# ---- Book Class ----
class Book:
    def __init__(self, title, author, isbn, price):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.price = price

    def __str__(self):
        return f"{self.title} by {self.author} (ISBN: {self.isbn}) - ${self.price}"

# ---- User Class ----
class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email

# ---- CartItem Class ----
class CartItem:
    def __init__(self, book, qty):
        self.book = book
        self.qty = qty

    def total_price(self):
        return self.book.price * self.qty

# ---- ShoppingCart Class ----
class ShoppingCart:
    def __init__(self):
        self.items = []

    def add_book(self, book, qty):
        self.items.append(CartItem(book, qty))

    def calculate_total(self):
        return sum(i.total_price() for i in self.items)

# ---- Order Class ----
class Order:
    def __init__(self, user, items):
        self.user = user
        self.items = items
        self.total_amount = sum(i.total_price() for i in items)
        self.status = "Pending"

    def set_status(self, status):
        self.status = status

# ---- Payment Class ----
class Payment:
    def process_payment(self, user, amount):
        print(f"Processing payment of ${amount} for {user.name}")
        return True

# ---- BookStore Class ----
class BookStore:
    def __init__(self):
        self.books = []

    def add_book(self, book):
        self.books.append(book)

    def display_books(self):
        print("Available Books:")
        for b in self.books:
            print(b)

    def search_by_title(self, title):
        for b in self.books:
            if b.title.lower() == title.lower():
                return b
        return None

# ---- Main ----
if __name__ == "__main__":
    store = BookStore()
    store.add_book(Book("Clean Code", "Robert C. Martin", "111", 40.0))
    store.add_book(Book("Design Patterns", "GoF", "222", 50.0))

    user = User("Alice", "alice@email.com")

    store.display_books()
    cart = ShoppingCart()
    book1 = store.search_by_title("Clean Code")
    if book1:
        cart.add_book(book1, 2)

    order = Order(user, cart.items)
    payment = Payment()
    if payment.process_payment(user, order.total_amount):
        order.set_status("Paid")

    print("Order Status:", order.status)
JavaScript
// ---- Book Class ----
class Book {
  constructor(title, author, isbn, price) {
    this.title = title;
    this.author = author;
    this.isbn = isbn;
    this.price = price;
  }
  toString() {
    return `${this.title} by ${this.author} (ISBN: ${this.isbn}) - $${this.price}`;
  }
}

// ---- User Class ----
class User {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }
}

// ---- CartItem Class ----
class CartItem {
  constructor(book, qty) {
    this.book = book;
    this.qty = qty;
  }
  totalPrice() {
    return this.book.price * this.qty;
  }
}

// ---- ShoppingCart Class ----
class ShoppingCart {
  constructor() {
    this.items = [];
  }
  addBook(book, qty) {
    this.items.push(new CartItem(book, qty));
  }
  calculateTotal() {
    return this.items.reduce((acc, i) => acc + i.totalPrice(), 0);
  }
}

// ---- Order Class ----
class Order {
  constructor(user, items) {
    this.user = user;
    this.items = items;
    this.totalAmount = this.calculateTotal();
    this.status = "Pending";
  }
  calculateTotal() {
    return this.items.reduce((acc, i) => acc + i.totalPrice(), 0);
  }
  setStatus(status) {
    this.status = status;
  }
}

// ---- Payment Class ----
class Payment {
  processPayment(user, amount) {
    // lightweight output
    console.log(`Payment processed: $${amount} for ${user.name}`);
    return true;
  }
}

// ---- BookStore Class ----
class BookStore {
  constructor() {
    this.books = [];
  }
  addBook(book) {
    this.books.push(book);
  }
  displayBooks() {
    return this.books.map((b) => b.toString()).join("\n");
  }
  searchByTitle(title) {
    return this.books.find(
      (b) => b.title.toLowerCase() === title.toLowerCase()
    );
  }
}

// ---- Main (wrapped in function to avoid timeouts) ----
(function main() {
  const store = new BookStore();
  store.addBook(new Book("Clean Code", "Robert C. Martin", "111", 40.0));
  store.addBook(new Book("Design Patterns", "GoF", "222", 50.0));

  const user = new User("Alice", "alice@email.com");

  console.log("Available Books:");
  console.log(store.displayBooks());

  const cart = new ShoppingCart();
  const book1 = store.searchByTitle("Clean Code");
  if (book1) cart.addBook(book1, 2);

  const order = new Order(user, cart.items);
  const payment = new Payment();
  if (payment.processPayment(user, order.totalAmount)) {
    order.setStatus("Paid");
  }

  console.log("Order Status:", order.status);
})();

Output:

book-store-
Book Store
Comment
Article Tags:

Explore