First lab
This commit is contained in:
7
.idea/encodings.xml
generated
Normal file
7
.idea/encodings.xml
generated
Normal 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
2
.idea/misc.xml
generated
@@ -8,7 +8,7 @@
|
||||
</list>
|
||||
</option>
|
||||
</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" />
|
||||
</component>
|
||||
</project>
|
||||
124
.idea/uiDesigner.xml
generated
Normal file
124
.idea/uiDesigner.xml
generated
Normal 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>
|
||||
2
pom.xml
2
pom.xml
@@ -13,5 +13,5 @@
|
||||
<maven.compiler.target>23</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -1,17 +1,7 @@
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
155
src/main/java/org/lumijiez/labs/first/Library.java
Normal file
155
src/main/java/org/lumijiez/labs/first/Library.java
Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
202
src/main/java/org/lumijiez/labs/first/README.md
Normal file
202
src/main/java/org/lumijiez/labs/first/README.md
Normal 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.
|
||||
|
||||
---
|
||||
11
src/main/java/org/lumijiez/labs/first/books/Book.java
Normal file
11
src/main/java/org/lumijiez/labs/first/books/Book.java
Normal 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();
|
||||
}
|
||||
|
||||
46
src/main/java/org/lumijiez/labs/first/books/GeneralBook.java
Normal file
46
src/main/java/org/lumijiez/labs/first/books/GeneralBook.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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() + ".");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
58
src/main/java/org/lumijiez/labs/first/users/StudentUser.java
Normal file
58
src/main/java/org/lumijiez/labs/first/users/StudentUser.java
Normal 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;
|
||||
}
|
||||
}
|
||||
14
src/main/java/org/lumijiez/labs/first/users/User.java
Normal file
14
src/main/java/org/lumijiez/labs/first/users/User.java
Normal 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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user