Friday, November 15, 2024
Google search engine
HomeGuest BlogsDesign an online book reader system

Design an online book reader system

Design an online book reader system (Object-Oriented Design). 

Asked In: Amazon, Microsoft, and many more interviews 

Solution: Let’s assume we want to design a basic online reading system that provides the following functionality: • Searching the database of books and reading a book. • User membership creation and extension. • Only one active user at a time and only one active book by this user The class OnlineReaderSystem represents the body of our program. We could implement the class such that it stores information about all the books dealing with user management and refreshes the display, but that would make this class rather hefty. Instead, we’ve chosen to tear off these components into Library, UserManager, and Display classes. 

The classes:

  1. User
  2. Book
  3. Library
  4. UserManager
  5. Display
  6. OnlineReaderSystem 

The full code is given below : 

Java

import java.util.HashMap;

/*
* This class represents the system
*/

class OnlineReaderSystem {
    private Library library;
    private UserManager userManager;
    private Display display;
    private Book activeBook;
    private User activeUser;

    public OnlineReaderSystem()
    {
        userManager = new UserManager();
        library = new Library();
        display = new Display();
    }

    public Library getLibrary()
    {
        return library;
    }

    public UserManager getUserManager()
    {
        return userManager;
    }

    public Display getDisplay()
    {
        return display;
    }

    public Book getActiveBook()
    {
        return activeBook;
    }

    public void setActiveBook(Book book)
    {
        activeBook = book;
        display.displayBook(book);
    }

    public User getActiveUser()
    {
        return activeUser;
    }

    public void setActiveUser(User user)
    {
        activeUser = user;
        display.displayUser(user);
    }
}

/*
* We then implement separate classes to handle the user
* manager, the library, and the display components 
*/

/*
* This class represents the Library which is responsible
* for storing and searching the books.
*/
class Library {
    private HashMap<Integer, Book> books;

    public Library()
    {
        books = new HashMap<Integer, Book>();
    }

    public Boolean addBook(int id, String details, String title)
    {
        if (books.containsKey(id)) {
            return false;
        }
        Book book = new Book(id, details, title);
        books.put(id, book);
        return true;
    }

    public Boolean addBook(Book book)
    {
        if (!books.containsKey(book.getId())) {
            return false;
        }

        books.put(book.getId(), book);
        return true;
    }

    public boolean remove(Book b)
    {
        return remove(b.getId());
    }

    public boolean remove(int id)
    {
        if (!books.containsKey(id)) {
            return false;
        }
        books.remove(id);
        return true;
    }

    public Book find(int id)
    {
        return books.get(id);
    }
}

/*
* This class represents the UserManager which is responsible 
* for managing the users, their membership etc.
*/

class UserManager {
    private HashMap<Integer, User> users;

    public UserManager()
    {
        users = new HashMap<Integer, User>();
    }
    public Boolean addUser(int id, String details, String name)
    {
        if (users.containsKey(id)) {
            return false;
        }
        User user = new User(id, details, name);
        users.put(id, user);
        return true;
    }

    public Boolean addUser(User user)
    {
        if (users.containsKey(user.getId())) {
            return false;
        }

        users.put(user.getId(), user);
        return true;
    }

    public boolean remove(User u)
    {
        return remove(u.getId());
    }

    public boolean remove(int id)
    {
        if (users.containsKey(id)) {
            return false;
        }
        users.remove(id);
        return true;
    }

    public User find(int id)
    {
        return users.get(id);
    }
}

/*
* This class represents the Display, which is responsible 
* for displaying the book, it's pages and contents. It also 
* shows the current user. * It provides the method
* turnPageForward, turnPageBackward, refreshPage etc.
*/

class Display {
    private Book activeBook;
    private User activeUser;
    private int pageNumber = 0;

    public void displayUser(User user)
    {
        activeUser = user;
        refreshUsername();
    }

    public void displayBook(Book book)
    {
        pageNumber = 0;
        activeBook = book;

        refreshTitle();
        refreshDetails();
        refreshPage();
    }

    public void turnPageForward()
    {
        pageNumber++;
        System.out.println("Turning forward to page no " +
                   pageNumber + " of book having title " +
                                     activeBook.getTitle());
        refreshPage();
    }

    public void turnPageBackward()
    {
        pageNumber--;
        System.out.println("Turning backward to page no " +
                    pageNumber + " of book having title " + 
                                    activeBook.getTitle());
        refreshPage();
    }

    public void refreshUsername()
    {
        /* updates username display */
        System.out.println("User name " + activeUser.getName() + 
                                             " is refreshed");
    }

    public void refreshTitle()
    {
        /* updates title display */
        System.out.println("Title of the book " +
                        activeBook.getTitle() + " refreshed");
    }

    public void refreshDetails()
    {
        /* updates details display */
        System.out.println("Details of the book " +
                        activeBook.getTitle() + " refreshed");
    }

    public void refreshPage()
    {
        /* updated page display */
        System.out.println("Page no " + pageNumber + " refreshed");
    }
}

/* 
* The classes for User and Book simply hold data and 
* provide little functionality.
* This class represents the Book which is a simple POJO
*/

class Book {
    private int bookId;
    private String details;
    private String title;

    public Book(int id, String details, String title)
    {
        bookId = id;
        this.details = details;
        this.title = title;
    }

    public int getId()
    {
        return bookId;
    }

    public void setId(int id)
    {
        bookId = id;
    }

    public String getDetails()
    {
        return details;
    }

    public void setDetails(String details)
    {
        this.details = details;
    }

    public String getTitle()
    {
        return title;
    }

    public void setTitle(String title)
    {
        this.title = title;
    }
}

/*
* This class represents the User which is a simple POJO
*/

class User {
    private int userId;
    private String name;
    private String details;

    public void renewMembership()
    {
    }

    public User(int id, String details, String name)
    {
        this.userId = id;
        this.details = details;
        this.name = name;
    }

    public int getId()
    {
        return userId;
    }

    public void setId(int id)
    {
        userId = id;
    }

    public String getDetails()
    {
        return details;
    }

    public void setDetails(String details)
    {
        this.details = details;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}

// This class is used to test the Application

public class AppTest {

    public static void main(String[] args)
    {

        OnlineReaderSystem onlineReaderSystem = new OnlineReaderSystem();

        Book dsBook = new Book(1, "It contains Data Structures", "Ds");
        Book algoBook = new Book(2, "It contains Algorithms", "Algo");

        onlineReaderSystem.getLibrary().addBook(dsBook);
        onlineReaderSystem.getLibrary().addBook(algoBook);

        User user1 = new User(1, " ", "Ram");
        User user2 = new User(2, " ", "Gopal");

        onlineReaderSystem.getUserManager().addUser(user1);
        onlineReaderSystem.getUserManager().addUser(user2);

        onlineReaderSystem.setActiveBook(algoBook);
        onlineReaderSystem.setActiveUser(user1);

        onlineReaderSystem.getDisplay().turnPageForward();
        onlineReaderSystem.getDisplay().turnPageForward();
        onlineReaderSystem.getDisplay().turnPageBackward();
    }
}

C#

using System;
using System.Collections.Generic;

/*
* This class represents the system
*/

class OnlineReaderSystem
{
    private Library library;
    private UserManager userManager;
    private Display display;
    private Book activeBook;
    private User activeUser;

    public OnlineReaderSystem()
    {
        userManager = new UserManager();
        library = new Library();
        display = new Display();
    }

    public Library getLibrary()
    {
        return library;
    }

    public UserManager getUserManager()
    {
        return userManager;
    }

    public Display getDisplay()
    {
        return display;
    }

    public Book getActiveBook()
    {
        return activeBook;
    }

    public void setActiveBook(Book book)
    {
        activeBook = book;
        display.displayBook(book);
    }

    public User getActiveUser()
    {
        return activeUser;
    }

    public void setActiveUser(User user)
    {
        activeUser = user;
        display.displayUser(user);
    }
}

/*
* We then implement separate classes to handle the user
* manager, the library, and the display components 
*/

/*
* This class represents the Library which is responsible
* for storing and searching the books.
*/
class Library 
{
    private Dictionary<int, Book> books;

    public Library()
    {
        books = new Dictionary<int, Book>();
    }

    public Boolean addBook(int id, String details, 
                                   String title)
    {
        if (books.ContainsKey(id))
        {
            return false;
        }
        Book book = new Book(id, details, title);
        books.Add(id, book);
        return true;
    }

    public Boolean addBook(Book book)
    {
        if (books.ContainsKey(book.getId()))
        {
            return false;
        }

        books.Add(book.getId(), book);
        return true;
    }

    public bool remove(Book b)
    {
        return remove(b.getId());
    }

    public bool remove(int id)
    {
        if (!books.ContainsKey(id)) 
        {
            return false;
        }
        books.Remove(id);
        return true;
    }

    public Book find(int id)
    {
        return books[id];
    }
}

/*
* This class represents the UserManager  
* which is responsible for managing the users, 
* their membership etc.
*/
class UserManager
{
    private Dictionary<int, User> users;

    public UserManager()
    {
        users = new Dictionary<int, User>();
    }
    public Boolean addUser(int id, String details, 
                                   String name)
    {
        if (!users.ContainsKey(id)) 
        {
            return false;
        }
        User user = new User(id, details, name);
        users.Add(id, user);
        return true;
    }

    public Boolean addUser(User user)
    {
        if (users.ContainsKey(user.getId()))
        {
            return false;
        }

        users.Add(user.getId(), user);
        return true;
    }

    public bool remove(User u)
    {
        return remove(u.getId());
    }

    public bool remove(int id)
    {
        if (users.ContainsKey(id)) 
        {
            return false;
        }
        users.Remove(id);
        return true;
    }

    public User find(int id)
    {
        return users[id];
    }
}

/*
* This class represents the Display, which is responsible 
* for displaying the book, it's pages and contents.  
* It also shows the current user. * It provides the method
* turnPageForward, turnPageBackward, refreshPage etc.
*/
class Display
{
    private Book activeBook;
    private User activeUser;
    private int pageNumber = 0;

    public void displayUser(User user)
    {
        activeUser = user;
        refreshUsername();
    }

    public void displayBook(Book book)
    {
        pageNumber = 0;
        activeBook = book;

        refreshTitle();
        refreshDetails();
        refreshPage();
    }

    public void turnPageForward()
    {
        pageNumber++;
        Console.WriteLine("Turning forward to page no " +
                  pageNumber + " of book having title " +
                                  activeBook.getTitle());
        refreshPage();
    }

    public void turnPageBackward()
    {
        pageNumber--;
        Console.WriteLine("Turning backward to page no " +
                   pageNumber + " of book having title " + 
                                   activeBook.getTitle());
        refreshPage();
    }

    public void refreshUsername()
    {
        /* updates username display */
        Console.WriteLine("User name " + 
                  activeUser.getName() + 
                       " is refreshed");
    }

    public void refreshTitle()
    {
        /* updates title display */
        Console.WriteLine("Title of the book " +
                         activeBook.getTitle() + 
                                  " refreshed");
    }

    public void refreshDetails()
    {
        /* updates details display */
        Console.WriteLine("Details of the book " +
                           activeBook.getTitle() + 
                                    " refreshed");
    }

    public void refreshPage()
    {
        /* updated page display */
        Console.WriteLine("Page no " + pageNumber + 
                                     " refreshed");
    }
}

/* 
* The classes for User and Book simply hold data  
* and provide little functionality.
* This class represents the Book which is 
* a simple POJO
*/
class Book
{
    private int bookId;
    private String details;
    private String title;

    public Book(int id, String details, 
                        String title)
    {
        bookId = id;
        this.details = details;
        this.title = title;
    }

    public int getId()
    {
        return bookId;
    }

    public void setId(int id)
    {
        bookId = id;
    }

    public String getDetails()
    {
        return details;
    }

    public void setDetails(String details)
    {
        this.details = details;
    }

    public String getTitle()
    {
        return title;
    }

    public void setTitle(String title)
    {
        this.title = title;
    }
}

/*
* This class represents the User 
* which is a simple POJO
*/
class User
{
    private int userId;
    private String name;
    private String details;

    public void renewMembership()
    {
    }

    public User(int id, String details,
                        String name)
    {
        this.userId = id;
        this.details = details;
        this.name = name;
    }

    public int getId()
    {
        return userId;
    }

    public void setId(int id)
    {
        userId = id;
    }

    public String getDetails()
    {
        return details;
    }

    public void setDetails(String details)
    {
        this.details = details;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}

// This class is used to test the Application
public class AppTest
{
    public static void Main(String[] args)
    {

        OnlineReaderSystem 
              onlineReaderSystem = new OnlineReaderSystem();

        Book dsBook = new Book(1, "It contains Data Structures", "Ds");
        Book algoBook = new Book(2, "It contains Algorithms", "Algo");

        onlineReaderSystem.getLibrary().addBook(dsBook);
        onlineReaderSystem.getLibrary().addBook(algoBook);

        User user1 = new User(1, " ", "Ram");
        User user2 = new User(2, " ", "Gopal");

        onlineReaderSystem.getUserManager().addUser(user1);
        onlineReaderSystem.getUserManager().addUser(user2);

        onlineReaderSystem.setActiveBook(algoBook);
        onlineReaderSystem.setActiveUser(user1);

        onlineReaderSystem.getDisplay().turnPageForward();
        onlineReaderSystem.getDisplay().turnPageForward();
        onlineReaderSystem.getDisplay().turnPageBackward();
    }
}

// This code is contributed by 29AjayKumar

JavaScript

// Define Book class
class Book {
    constructor(id, details, title) {
        this.bookId = id;
        this.details = details;
        this.title = title;
    }
}

// Define User class
class User {
    constructor(id, details, name) {
        this.userId = id;
        this.details = details;
        this.name = name;
    }
}

// Define UserManager class
class UserManager {
    constructor() {
        this.users = new Map();
    }

    addUser(id, details, name) {
        if (this.users.has(id)) {
            return false;
        }
        let user = new User(id, details, name);
        this.users.set(id, user);
        return true;
    }

    remove(id) {
        return this.users.delete(id);
    }

    find(id) {
        return this.users.get(id);
    }
}

// Define Library class
class Library {
    constructor() {
        this.books = new Map();
    }

    addBook(id, details, title) {
        if (this.books.has(id)) {
            return false;
        }
        let book = new Book(id, details, title);
        this.books.set(id, book);
        return true;
    }

    remove(id) {
        return this.books.delete(id);
    }

    find(id) {
        return this.books.get(id);
    }
}

// Define Display class
class Display {
    constructor() {
        this.pageNumber = 0;
    }

    displayUser(user) {
        this.activeUser = user;
        this.refreshUsername();
    }

    displayBook(book) {
        this.pageNumber = 0;
        this.activeBook = book;
        this.refreshTitle();
        this.refreshDetails();
        this.refreshPage();
    }

    turnPageForward() {
        this.pageNumber++;
        console.log(`Turning forward to page no ${this.pageNumber} of book having title ${this.activeBook.title}`);
        this.refreshPage();
    }

    turnPageBackward() {
        if (this.pageNumber > 0) {
            this.pageNumber--;
        }
        console.log(`Turning backward to page no ${this.pageNumber} of book having title ${this.activeBook.title}`);
        this.refreshPage();
    }

    refreshUsername() {
        console.log(`User name ${this.activeUser.name} is refreshed`);
    }

    refreshTitle() {
        console.log(`Title of the book ${this.activeBook.title} refreshed`);
    }

    refreshDetails() {
        console.log(`Details of the book ${this.activeBook.title} refreshed`);
    }

    refreshPage() {
        console.log(`Page no ${this.pageNumber} refreshed`);
    }
}

// Define OnlineReaderSystem class
class OnlineReaderSystem {
    constructor() {
        this.userManager = new UserManager();
        this.library = new Library();
        this.display = new Display();
    }

    setActiveBook(book) {
        this.activeBook = book;
        this.display.displayBook(book);
    }

    setActiveUser(user) {
        this.activeUser = user;
        this.display.displayUser(user);
    }
}

// Test the application
let onlineReaderSystem = new OnlineReaderSystem();

let algoBook = new Book(1, "It contains Algorithms", "Algo");

onlineReaderSystem.library.addBook(algoBook.bookId, algoBook.details, algoBook.title);

let user1 = new User(1, " ", "Ram");

onlineReaderSystem.userManager.addUser(user1.userId, user1.details, user1.name);

onlineReaderSystem.setActiveBook(algoBook);
onlineReaderSystem.setActiveUser(user1);

onlineReaderSystem.display.turnPageForward();
onlineReaderSystem.display.turnPageForward();
onlineReaderSystem.display.turnPageBackward();

Python3

# This class represents the Book which is a simple POJO
class Book:
    def __init__(self, id, details, title):
        self.bookId = id
        self.details = details
        self.title = title

# This class represents the User which is a simple POJO
class User:
    def __init__(self, id, details, name):
        self.userId = id
        self.details = details
        self.name = name

# This class represents the Library which is responsible for storing and searching the books.
class Library:
    def __init__(self):
        self.books = {}

    def addBook(self, id, details, title):
        if id in self.books:
            return False
        self.books[id] = Book(id, details, title)
        return True

    def remove(self, id):
        if id not in self.books:
            return False
        del self.books[id]
        return True

    def find(self, id):
        return self.books.get(id)

# This class represents the UserManager which is responsible for managing the users, their membership etc.
class UserManager:
    def __init__(self):
        self.users = {}

    def addUser(self, id, details, name):
        if id in self.users:
            return False
        self.users[id] = User(id, details, name)
        return True

    def remove(self, id):
        if id not in self.users:
            return False
        del self.users[id]
        return True

    def find(self, id):
        return self.users.get(id)

# This class represents the Display, which is responsible for displaying the book, it's pages and contents. It also shows the current user.
class Display:
    def __init__(self):
        self.activeBook = None
        self.activeUser = None
        self.pageNumber = 0

    def displayUser(self, user):
        self.activeUser = user
        self.refreshUsername()

    def displayBook(self, book):
        self.pageNumber = 0
        self.activeBook = book
        self.refreshTitle()
        self.refreshDetails()
        self.refreshPage()

    def turnPageForward(self):
        self.pageNumber += 1
        print(f"Turning forward to page no {self.pageNumber} of book having title {self.activeBook.title}")
        self.refreshPage()

    def turnPageBackward(self):
        self.pageNumber -= 1
        print(f"Turning backward to page no {self.pageNumber} of book having title {self.activeBook.title}")
        self.refreshPage()

    def refreshUsername(self):
        print(f"User name {self.activeUser.name} is refreshed")

    def refreshTitle(self):
        print(f"Title of the book {self.activeBook.title} refreshed")

    def refreshDetails(self):
        print(f"Details of the book {self.activeBook.title} refreshed")

    def refreshPage(self):
        print(f"Page no {self.pageNumber} refreshed")

# This class represents the system
class OnlineReaderSystem:
    def __init__(self):
        self.userManager = UserManager()
        self.library = Library()
        self.display = Display()
        self.activeBook = None
        self.activeUser = None

    def setActiveBook(self, book):
        self.activeBook = book
        self.display.displayBook(book)

    def setActiveUser(self, user):
        self.activeUser = user
        self.display.displayUser(user)

# This function is used to test the Application
def main():
    onlineReaderSystem = OnlineReaderSystem()

    dsBook = Book(1, "It contains Data Structures", "Ds")
    algoBook = Book(2, "It contains Algorithms", "Algo")

    onlineReaderSystem.library.addBook(1, "It contains Data Structures", "Ds")
    onlineReaderSystem.library.addBook(2, "It contains Algorithms", "Algo")

    user1 = User(1, " ", "Ram")
    user2 = User(2, " ", "Gopal")

    onlineReaderSystem.userManager.addUser(1, " ", "Ram")
    onlineReaderSystem.userManager.addUser(2, " ", "Gopal")

    onlineReaderSystem.setActiveBook(algoBook)
    onlineReaderSystem.setActiveUser(user1)

    onlineReaderSystem.display.turnPageForward()
    onlineReaderSystem.display.turnPageForward()
    onlineReaderSystem.display.turnPageBackward()

if __name__ == "__main__":
    main()

Mastering System Design Course by Geeksforneveropen

Want to get a Software Developer/Engineer job at a leading tech company? or Want to make a smooth transition from SDE I to SDE II or Senior Developer profiles? If yes, then you’re required to dive deep into the System Design world! A decent command over System Design concepts is very much essential, especially for working professionals, to get a much-needed advantage over others during tech interviews. 

System-Design-Course-By-neveropen

And that’s why, neveropen is providing you with an in-depth interview-centric Mastering System Design Course that will help you prepare for the questions related to System Designs for Google, Amazon, Adobe, Uber, and other product-based companies.

Last Updated :
26 Mar, 2024
Like Article
Save Article


Previous

<!–

8 Min Read | Java

–>


Next


<!–

8 Min Read | Java

–>

Share your thoughts in the comments

Dominic Rubhabha-Wardslaus
Dominic Rubhabha-Wardslaushttp://wardslaus.com
infosec,malicious & dos attacks generator, boot rom exploit philanthropist , wild hacker , game developer,
RELATED ARTICLES

Most Popular

Recent Comments