First lab

This commit is contained in:
Daniel
2024-10-04 16:37:57 +03:00
parent 051469d832
commit 4fb352b089
21 changed files with 877 additions and 12 deletions

7
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

2
.idea/misc.xml generated
View File

@@ -8,7 +8,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_22" project-jdk-name="openjdk-23" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_23" project-jdk-name="openjdk-23" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

124
.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@@ -13,5 +13,5 @@
<maven.compiler.target>23</maven.compiler.target> <maven.compiler.target>23</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
</project> </project>

View File

@@ -1,17 +1,7 @@
package org.lumijiez; package org.lumijiez;
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
// to see how IntelliJ IDEA suggests fixing it.
System.out.printf("Hello and welcome!");
for (int i = 1; i <= 5; i++) {
//TIP Press <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.
System.out.println("i = " + i);
}
} }
} }

View File

@@ -0,0 +1,155 @@
package org.lumijiez.labs.first;
import org.lumijiez.labs.first.books.Book;
import org.lumijiez.labs.first.books.GeneralBook;
import org.lumijiez.labs.first.books.ReferenceBook;
import org.lumijiez.labs.first.repositories.InMemoryLibraryRepository;
import org.lumijiez.labs.first.repositories.InMemoryUserRepository;
import org.lumijiez.labs.first.repositories.LibraryRepository;
import org.lumijiez.labs.first.repositories.UserRepository;
import org.lumijiez.labs.first.services.BorrowingService;
import org.lumijiez.labs.first.services.BorrowingServiceImpl;
import org.lumijiez.labs.first.services.EmailNotificationService;
import org.lumijiez.labs.first.services.Notification;
import org.lumijiez.labs.first.users.ProfessorUser;
import org.lumijiez.labs.first.users.StudentUser;
import org.lumijiez.labs.first.users.User;
import java.util.Scanner;
public class Library {
static String[][] booksData = {
{"Clean Code", "A handbook of agile software craftsmanship."},
{"Java Concurrency in Practice", "A comprehensive guide to writing concurrent applications in Java."},
{"Effective Java (2nd Edition)", "The definitive guide to programming in Java."},
{"Head First Java", "An engaging introduction to the Java programming language."},
{"Java: The Complete Reference", "A complete guide to the Java programming language and its features."},
{"Design Patterns", "Elements of reusable object-oriented software."},
{"Refactoring", "Improving the design of existing code."},
{"Introduction to Java Programming", "Comprehensive introduction to Java programming."},
{"Java Network Programming", "A guide to network programming in Java."},
{"Java Performance: The Definitive Guide", "Getting the most out of Java."}
};
static String[][] referenceBooksData = {
{"Java Language Specification", "The official reference for the Java language."},
{"Java API Documentation", "Comprehensive documentation for the Java APIs."},
{"The Art of Java", "A detailed reference guide to Java programming."},
{"Java in a Nutshell", "A quick reference guide for Java developers."},
{"Java: A Beginner's Guide", "An introductory guide for beginners."}
};
private static final LibraryRepository libraryRepository = new InMemoryLibraryRepository();
private static final UserRepository userRepository = new InMemoryUserRepository();
private static final Notification notificationService = new EmailNotificationService();
private static final BorrowingService borrowingService = new BorrowingServiceImpl(notificationService);
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
for (String[] bookData : booksData) {
GeneralBook book = new GeneralBook(bookData[0], bookData[1]);
libraryRepository.addBook(book);
}
for (String[] bookData : referenceBooksData) {
ReferenceBook book = new ReferenceBook(bookData[0], bookData[1]);
libraryRepository.addBook(book);
}
System.out.println("Welcome to the Library System!");
boolean running = true;
while (running) {
System.out.println("\nPlease choose an option:");
System.out.println("1. Add a Student User");
System.out.println("2. Add a Teacher User");
System.out.println("3. Borrow a Book");
System.out.println("4. Return a Book");
System.out.println("5. List Available Books");
System.out.println("6. List Users");
System.out.println("7. Exit");
int option = Integer.parseInt(scanner.nextLine());
switch (option) {
case 1:
addUser(scanner, "student");
break;
case 2:
addUser(scanner, "teacher");
break;
case 3:
borrowBook(scanner);
break;
case 4:
returnBook(scanner);
break;
case 5:
libraryRepository.listAvailableBooks();
break;
case 6:
userRepository.listUsers();
break;
case 7:
running = false;
System.out.println("Exiting the system. Goodbye!");
break;
default:
System.out.println("Invalid option. Please try again.");
}
}
scanner.close();
}
private static void addUser(Scanner scanner, String userType) {
System.out.print("Enter user name: ");
String userName = scanner.nextLine();
User user;
if (userType.equals("student")) {
user = new StudentUser(userName);
} else {
user = new ProfessorUser(userName);
}
userRepository.addUser(user);
System.out.println(userType.substring(0, 1).toUpperCase() + userType.substring(1) + " User '" + userName + "' added.");
}
private static void borrowBook(Scanner scanner) {
System.out.print("Enter user name: ");
String userName = scanner.nextLine();
System.out.print("Enter book title to borrow: ");
String bookTitle = scanner.nextLine();
User user = userRepository.getUserByName(userName);
Book book = libraryRepository.getBookByTitle(bookTitle);
if (user != null && book != null) {
borrowingService.borrowBook(user, book);
} else {
System.out.println("User or book not found.");
}
}
private static void returnBook(Scanner scanner) {
System.out.print("Enter user name: ");
String userName = scanner.nextLine();
System.out.print("Enter book title to return: ");
String bookTitle = scanner.nextLine();
User user = userRepository.getUserByName(userName);
Book book = libraryRepository.getBookByTitle(bookTitle);
if (user != null && book != null) {
borrowingService.returnBook(user, book);
} else {
System.out.println("User or book not found.");
}
}
}

View File

@@ -0,0 +1,202 @@
# Laboratory 0 - Library Management System
## Author: Schipschi Daniil / FAF-223
----
## Objectives:
* Implement the first two letters of SOLID in a simple project.
## Implementation
The Library Management System allows users (students and professors) to borrow and return books while managing the underlying book and user storage efficiently. This implementation employs several creational design patterns while adhering to SOLID principles.
### Key SOLID Principles
1. **Single Responsibility Principle (SRP)**: Each class has one specific responsibility, ensuring that changes in one area of the application don't affect others.
- **Book Interface**: Responsible for defining book-related properties and behaviors.
- **User Repository**: Focused solely on managing user data without coupling to book operations.
- **Library Repository**: Focused solely on managing book data.
- **Notification Service**: Handles user notifications independently.
**Example: Book Interface**
```java
public interface Book {
String getTitle();
String getDescription();
}
```
Each class implementing this interface can have its unique implementation. For example:
**Example: GeneralBook Implementation**
```java
public class GeneralBook implements Book {
private String title;
private String description;
public GeneralBook(String title, String description) {
this.title = title;
this.description = description;
}
@Override
public String getTitle() {
return title;
}
@Override
public String getDescription() {
return description;
}
}
```
2. **Open/Closed Principle (OCP)**: The system is open for extension but closed for modification. New types of users or books can be added without changing existing code.
- **Book Types**: You can add new book types (e.g., `EBook`) by extending the `Book` interface without modifying existing classes.
**Example: EBook Implementation**
```java
public class EBook implements Book {
private String title;
private String description;
private String fileFormat;
public EBook(String title, String description, String fileFormat) {
this.title = title;
this.description = description;
this.fileFormat = fileFormat;
}
@Override
public String getTitle() {
return title;
}
@Override
public String getDescription() {
return description;
}
public String getFileFormat() {
return fileFormat;
}
}
```
- **User Types**: New user types (e.g., `AdminUser`) can be implemented by creating new classes that implement the `User` interface.
**Example: AdminUser Implementation**
```java
public class AdminUser implements User {
private String name;
public AdminUser(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
// Admin-specific functionalities can be added here
}
```
### Code Snippets
**User Repository Interface**
```java
public interface UserRepository {
void addUser(User user);
User getUserByName(String userName);
void listUsers();
}
```
**InMemoryUserRepository Implementation**
```java
public class InMemoryUserRepository implements UserRepository {
private final List<User> users = new ArrayList<>();
@Override
public void addUser(User user) {
users.add(user);
}
@Override
public User getUserByName(String userName) {
return users.stream()
.filter(user -> user.getName().equalsIgnoreCase(userName))
.findFirst()
.orElse(null);
}
@Override
public void listUsers() {
users.forEach(user -> System.out.println(user.getName()));
}
}
```
**Notification Interface**
```java
public interface Notification {
void notifyUser(String message);
}
```
**EmailNotificationService Implementation**
```java
public class EmailNotificationService implements Notification {
@Override
public void notifyUser(String message) {
System.out.println("Email sent: " + message);
}
}
```
**Borrowing Service Interface**
```java
public interface BorrowingService {
void borrowBook(User user, Book book);
void returnBook(User user, Book book);
}
```
**Borrowing Service Implementation**
java
public class BorrowingServiceImpl implements BorrowingService {
private final Notification notificationService;
public BorrowingServiceImpl(Notification notificationService) {
this.notificationService = notificationService;
}
@Override
public void borrowBook(User user, Book book) {
notificationService.notifyUser(user.getName() + " borrowed " + book.getTitle() + ".");
}
@Override
public void returnBook(User user, Book book) {
notificationService.notifyUser(user.getName() + " returned " + book.getTitle() + ".");
}
}
```
### Conclusion
This Library Management System effectively demonstrates the application of SOLID principles:
- **Single Responsibility Principle (S)** is maintained by clearly separating the responsibilities of managing users, books, and notifications, which allows for focused changes in each area.
- **Open/Closed Principle (O)** is illustrated through the extensible design of the `Book` and `User` classes. New types can be added easily without modifying existing functionality, thereby promoting a flexible and maintainable system.
This design leads to a more modular, maintainable codebase, making future enhancements straightforward.
---

View File

@@ -0,0 +1,11 @@
package org.lumijiez.labs.first.books;
import java.time.LocalDate;
public interface Book {
String getTitle();
boolean canBeBorrowed();
String getContent();
LocalDate getDueDate();
}

View File

@@ -0,0 +1,46 @@
package org.lumijiez.labs.first.books;
import java.time.LocalDate;
public class GeneralBook implements Book {
private String title;
private String content;
private boolean borrowed;
private LocalDate dueDate;
public GeneralBook(String title, String content) {
this.title = title;
this.content = content;
this.borrowed = false;
}
@Override
public String getTitle() {
return this.title;
}
@Override
public boolean canBeBorrowed() {
return !borrowed;
}
@Override
public String getContent() {
return this.content;
}
@Override
public LocalDate getDueDate() {
return dueDate;
}
public void borrow(LocalDate dueDate) {
this.borrowed = true;
this.dueDate = dueDate;
}
public void returnBook() {
this.borrowed = false;
this.dueDate = null;
}
}

View File

@@ -0,0 +1,34 @@
package org.lumijiez.labs.first.books;
import java.time.LocalDate;
public class ReferenceBook implements Book {
private String title;
private String content;
public ReferenceBook(String title, String content) {
this.title = title;
this.content = content;
}
@Override
public String getTitle() {
return this.title;
}
@Override
public boolean canBeBorrowed() {
return false;
}
@Override
public String getContent() {
return this.content;
}
@Override
public LocalDate getDueDate() {
return null;
}
}

View File

@@ -0,0 +1,43 @@
package org.lumijiez.labs.first.repositories;
import org.lumijiez.labs.first.books.Book;
import java.util.ArrayList;
import java.util.List;
public class InMemoryLibraryRepository implements LibraryRepository {
private final List<Book> books = new ArrayList<>();
@Override
public void addBook(Book book) {
books.add(book);
}
@Override
public void removeBook(Book book) {
books.remove(book);
}
@Override
public void listAvailableBooks() {
System.out.println("Available books:");
for (Book book : books) {
if (book.canBeBorrowed()) {
System.out.println(book.getTitle());
} else {
System.out.println(book.getTitle() + " [NOT FOR BORROW]");
}
}
}
@Override
public Book getBookByTitle(String title) {
for (Book book : books) {
if (book.getTitle().equals(title)) {
return book;
}
}
return null;
}
}

View File

@@ -0,0 +1,33 @@
package org.lumijiez.labs.first.repositories;
import org.lumijiez.labs.first.users.User;
import java.util.ArrayList;
import java.util.List;
public class InMemoryUserRepository implements UserRepository {
private final List<User> users = new ArrayList<>();
@Override
public void addUser(User user) {
users.add(user);
}
@Override
public User getUserByName(String userName) {
return users.stream()
.filter(user -> user.getName().equalsIgnoreCase(userName))
.findFirst()
.orElse(null);
}
@Override
public void listUsers() {
if (users.isEmpty()) {
System.out.println("No users in the system.");
} else {
users.forEach(user -> System.out.println(user.getName()));
}
}
}

View File

@@ -0,0 +1,11 @@
package org.lumijiez.labs.first.repositories;
import org.lumijiez.labs.first.books.Book;
public interface LibraryRepository {
void addBook(Book book);
void removeBook(Book book);
void listAvailableBooks();
Book getBookByTitle(String title);
}

View File

@@ -0,0 +1,9 @@
package org.lumijiez.labs.first.repositories;
import org.lumijiez.labs.first.users.User;
public interface UserRepository {
void addUser(User user);
User getUserByName(String userName);
void listUsers();
}

View File

@@ -0,0 +1,10 @@
package org.lumijiez.labs.first.services;
import org.lumijiez.labs.first.books.Book;
import org.lumijiez.labs.first.users.User;
public interface BorrowingService {
void borrowBook(User user, Book book);
void returnBook(User user, Book book);
}

View File

@@ -0,0 +1,27 @@
package org.lumijiez.labs.first.services;
import org.lumijiez.labs.first.books.Book;
import org.lumijiez.labs.first.users.User;
public class BorrowingServiceImpl implements BorrowingService {
private final Notification notificationService;
public BorrowingServiceImpl(Notification notificationService) {
this.notificationService = notificationService;
}
@Override
public void borrowBook(User user, Book book) {
if (user.borrowBook(book)) {
notificationService.notifyUser(user.getName() + " borrowed " + book.getTitle() + ".");
} else {
System.out.println("Could not borrow the book: " + book.getTitle());
}
}
@Override
public void returnBook(User user, Book book) {
user.returnBook(book);
notificationService.notifyUser(user.getName() + " returned " + book.getTitle() + ".");
}
}

View File

@@ -0,0 +1,21 @@
package org.lumijiez.labs.first.services;
import org.lumijiez.labs.first.books.Book;
import org.lumijiez.labs.first.users.User;
import java.time.LocalDate;
public class EmailNotificationService implements Notification {
@Override
public void notifyUser(String message) {
System.out.println("Sending email: " + message);
}
@Override
public void remindDueDate(Book book, User user) {
LocalDate dueDate = book.getDueDate();
if (dueDate != null) {
System.out.println("Reminder: " + user.getName() + ", your borrowed book " + book.getTitle() + " is due on " + dueDate);
}
}
}

View File

@@ -0,0 +1,11 @@
package org.lumijiez.labs.first.services;
import org.lumijiez.labs.first.books.Book;
import org.lumijiez.labs.first.users.User;
public interface Notification {
void notifyUser(String message);
void remindDueDate(Book book, User user);
}

View File

@@ -0,0 +1,59 @@
package org.lumijiez.labs.first.users;
import org.lumijiez.labs.first.books.Book;
import org.lumijiez.labs.first.books.GeneralBook;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class ProfessorUser implements User {
private final String name;
private final List<Book> borrowedBooks = new ArrayList<>();
private static final int BORROW_LIMIT = 50;
public ProfessorUser(String name) {
this.name = name;
}
@Override
public boolean borrowBook(Book book) {
if (borrowedBooks.size() >= BORROW_LIMIT) {
System.out.println(name + " has reached the borrowing limit.");
return false;
}
if (book.canBeBorrowed()) {
LocalDate dueDate = LocalDate.now().plusWeeks(4);
((GeneralBook) book).borrow(dueDate);
borrowedBooks.add(book);
System.out.println(name + " borrowed " + book.getTitle() + ". Due date: " + dueDate);
return true;
} else {
System.out.println(book.getTitle() + " cannot be borrowed.");
}
return false;
}
@Override
public void returnBook(Book book) {
borrowedBooks.remove(book);
((GeneralBook) book).returnBook();
System.out.println(name + " returned " + book.getTitle());
}
@Override
public String getName() {
return this.name;
}
@Override
public List<Book> getBorrowedBooks() {
return borrowedBooks;
}
@Override
public int getBorrowingLimit() {
return BORROW_LIMIT;
}
}

View File

@@ -0,0 +1,58 @@
package org.lumijiez.labs.first.users;
import org.lumijiez.labs.first.books.Book;
import org.lumijiez.labs.first.books.GeneralBook;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class StudentUser implements User {
private final String name;
private final List<Book> borrowedBooks = new ArrayList<>();
private static final int BORROW_LIMIT = 3;
public StudentUser(String name) {
this.name = name;
}
@Override
public boolean borrowBook(Book book) {
if (borrowedBooks.size() >= BORROW_LIMIT) {
System.out.println(name + " has reached the borrowing limit.");
return false;
}
if (book.canBeBorrowed()) {
LocalDate dueDate = LocalDate.now().plusWeeks(2);
((GeneralBook) book).borrow(dueDate);
borrowedBooks.add(book);
System.out.println(name + " borrowed " + book.getTitle() + ". Due date: " + dueDate);
return true;
} else {
System.out.println(book.getTitle() + " cannot be borrowed.");
}
return false;
}
@Override
public void returnBook(Book book) {
borrowedBooks.remove(book);
((GeneralBook) book).returnBook();
System.out.println(name + " returned " + book.getTitle());
}
@Override
public String getName() {
return this.name;
}
@Override
public List<Book> getBorrowedBooks() {
return borrowedBooks;
}
@Override
public int getBorrowingLimit() {
return BORROW_LIMIT;
}
}

View File

@@ -0,0 +1,14 @@
package org.lumijiez.labs.first.users;
import org.lumijiez.labs.first.books.Book;
import java.util.List;
public interface User {
boolean borrowBook(Book book);
void returnBook(Book book);
String getName();
List<Book> getBorrowedBooks();
int getBorrowingLimit();
}