Following is my code for a library management system. I am pretty new to OOD and trying to learn it. I am specially looking for ways where any design patterns can be useful here. I tried to make classes so that I follow Single Responsibility principle. Would appreciate any feedback for it.
/*
This class is similar to admin with more priviliges
1. Add books
2. remove Books
*/
public class Admin extends Person{
private String libname;
Admin(String name, String phoneNo, String address, String libname){
this.name = name;
this.address = address;
this.phoneNo = phoneNo;
this.libname = libname;
}
public void addBook(int id, String author, Genre gen){
Library.getInstance(libname).addBookItem(id, author, gen);
}
public void removeBook(int id){
Library.getInstance(libname).removeBookItem(id);
}
}
public class Book {
int id;
String author;
Genre genre; // can be converted to enums
}
/*
1. extends Book class
2. It handles additional fields like reservations
*/
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalTime;
public class BookItem extends Book{
private LocalTime resStartdate;
private LocalTime resEndDate;
BookItem(int id, String author, Genre genre){
this.id = id;
this.author = author;
this.genre = genre;
this.resStartdate = LocalTime.now();
this.resEndDate = this.resStartdate;
}
public LocalTime getResEndDate() {
return resEndDate;
}
public void setResEndDate(LocalTime resEndDate) {
this.resEndDate = resEndDate;
}
public LocalTime getResStartdate() {
return resStartdate;
}
public void setResStartdate(LocalTime resStartdate) {
this.resStartdate = resStartdate;
}
}
import java.util.ArrayList;
import java.util.List;
public class Catalog {
static String libName;
// Catalog(String libName){
// Catalog.l = Library.getInstance(libName);
// }
public int temp(){
return 0;
}
public static List<BookItem> searchByAuthor(String author){
List<BookItem> result = new ArrayList<>();
// logic
List<BookItem> bookItemList = Library.getInstance(libName).bookItemList;
for(BookItem temp : bookItemList){
if(temp.author == author){
result.add(temp);
}
}
printResult(result);
return result;
}
public static List<BookItem> searchByGenre(Genre g){
List<BookItem> result = new ArrayList<>();
// logic
List<BookItem> bookItemList = Library.getInstance(libName).bookItemList;
for(BookItem temp : bookItemList){
if(temp.genre == g){
result.add(temp);
}
}
printResult(result);
return result;
}
private static void printResult(List<BookItem> result){
if(result.size() == 0){
System.out.println("No Books Found.");
return ;
}
System.out.println("Following books Found: ");
for(BookItem item : result) {
System.out.println("ID:: " + item.id +
" Author:: " + item.author +
" Genre:: " + item.genre
);
}
}
}
public enum Genre {
HORROR,
SCIFI,
ROMANTIC,
FICTION;
}
import java.util.ArrayList;
import java.util.List;
public class Library {
String name;
private static Library instance;
List<BookItem> bookItemList;
private Library(String libName){
this.name = libName;
bookItemList = new ArrayList<>();
}
public static Library getInstance(String libname){
if(instance == null){
instance = new Library(libname);
return instance;
}
return instance;
}
public void addBookItem(int id, String author, Genre gen){
bookItemList.add(new BookItem(id, author, gen));
}
public void removeBookItem(int id){
for(int i = 0;i<bookItemList.size();i++){
if(bookItemList.get(i).id == id){
bookItemList.remove(i);
break;
}
}
}
}
// Responsibilty of Member class
/*
1. search books by title, author -- dne
2. Reserve a book
3. Return the book
*/
import java.util.ArrayList;
import java.util.List;
public class Member extends Person{
private List<Reservation> myActiveReservations;
Member(String name, String phoneNo, String address){
this.name = name;
this.phoneNo = phoneNo;
this.address = address;
this.myActiveReservations = new ArrayList<>();
}
public List<BookItem> searchByGenre(Genre bookGenre){
return Catalog.searchByGenre(bookGenre);
}
public List<BookItem> searchByAuthor(String author){
return Catalog.searchByAuthor(author);
}
public boolean reserve(BookItem item){
// try to create a reservation for it.
// If successful, add it to the active reservations list and return true
// If not successful, return false
Reservation res = Reservation.createReservation(item, this);
if(res == null){
System.out.println("Not able to reserve Book");
return false;
}
this.myActiveReservations.add(res);
System.out.println("Reserved Book");
return true;
}
public void returnBook(Reservation res){
// fine calculator
int fine = Payment.fineCalculator(res);
Reservation.checkout(res);
myActiveReservations.remove(res);
System.out.println("Returned Book");
}
public List<Reservation> getActiveReservations(){
return this.myActiveReservations;
}
}
/*
This class handles matter related to fine calculation
*/
import java.time.Duration;
import java.time.LocalTime;
public class Payment {
private static int fineRate = 5;
public static int fineCalculator(Reservation res){
BookItem item = res.item;
LocalTime currTime = LocalTime.now();
if(currTime.isAfter(item.getResEndDate())){
Duration duration = Duration.between(currTime, item.getResEndDate());
int days = (int) duration.toDays();
int fine = days*fineRate;
System.out.println(" Please pay fine: "+days);
return fine;
}
return 0;
}
}
public abstract class Person {
String name;
String phoneNo;
String address;
}
/*
Class Responsiblity
Create a reservation against a book item and a user
*/
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalTime;
public class Reservation {
BookItem item;
Member member;
// private constructor
private Reservation(BookItem item, Member member){
this.item = item;
this.member = member;
}
public static Reservation createReservation(BookItem item, Member member){
LocalTime currTime = LocalTime.now();
if(item.getResEndDate().isBefore(currTime)){
// reservation possible
// return a reservation object
item.setResStartdate(currTime);
item.setResEndDate(currTime.plusHours(24*7));
return new Reservation(item, member);
}
return null;
}
public static void checkout(Reservation res){
BookItem item = res.item;
LocalTime currTime = LocalTime.now();
item.setResStartdate(currTime);
item.setResEndDate(currTime);
}
}
import java.util.List;
public class Main {
public static void main(String[] args) {
// create a library
String libName = "UW-Madison";
Catalog.libName = libName;
// Library ourLib = Library.getInstance(libName);
// create admins
Admin ad1 = new Admin("Pankaj","7896","Madison",libName);
// create members
Member m1 = new Member("Pranavi","6758","Atlanta");
// add books to library
ad1.addBook(1,"Oscar", Genre.FICTION);
ad1.addBook(2,"Piastri", Genre.HORROR);
ad1.addBook(3,"Pedro", Genre.ROMANTIC);
// search functionality
List<BookItem> res = m1.searchByAuthor("Piastri");
// m1.searchByGenre(Genre.FICTION);
// m1.searchByAuthor("Pankaj");
// reserving a book
if(res.size() > 0){
m1.reserve(res.get(0));
// print member's active res list
for(Reservation resItem : m1.getActiveReservations()){
System.out.println(resItem.item.author +
resItem.item.genre+
resItem.item.getResStartdate().toString()+
resItem.item.getResEndDate().toString()+
resItem.member.name
);
}
}
m1.returnBook(m1.getActiveReservations().get(0));
System.out.println(m1.getActiveReservations().size());
}
}
Trying to learn better ways to make my code more modular. Also trying to learn where I can use some design patterns in the code if they make it better.