Giao diện quản trị
Thuộc phần Lập trình hướng đối tượng trong hành trình Java của Coddy. Bài học 81 trên 87.
Thử thách
DễHãy mở rộng Hệ thống quản lý thư viện bằng Giao diện quản trị! Một thư viện thực tế cần có các chức năng quản trị: thêm sách mới vào bộ sưu tập, xóa sách không còn phù hợp và đăng ký thành viên mới. Bạn sẽ tạo một giao diện xác định các thao tác quản trị này, rồi triển khai chúng trong một lớp quản trị riêng.
Bạn sẽ tiếp tục xây dựng dựa trên code hiện có trong năm tệp:
Book.java: Giữ nguyên lớp Book với tất cả chức năng hiện có: isbn, title, author, isAvailable, borrowedBy, getDetails() và các phương thức getter/setter phù hợp.User.java: Giữ nguyên lớp User với id, name, ArrayList borrowedBooks, borrowBook(), returnBook(), getBorrowedCount() và toString().Library.java: Giữ nguyên lớp Library với tất cả phương thức hiện có. Thêm phương thức mớiremoveBook(String isbn)để tìm và xóa sách khỏi bộ sưu tập theo ISBN. Phương thức này cần trả vềtruenếu tìm thấy và xóa được sách, nếu không thì trả vềfalse. Chỉ có thể xóa sách khi sách hiện đang có sẵn, tức là chưa được mượn.LibraryAdmin.java: Tạo một giao diện có tênLibraryAdminđể xác định các thao tác quản trị cần có. Giao diện của bạn cần khai báo ba phương thức:addBook(String isbn, String title, String author)- trả về giá trị boolean cho biết thao tác có thành công hay khôngremoveBook(String isbn)- trả về giá trị boolean cho biết thao tác có thành công hay khôngregisterUser(String id, String name)- trả về giá trị boolean cho biết thao tác có thành công hay không
Sau đó, tạo một lớp có tên
AdminServicetriển khai giao diện này. AdminService cần giữ tham chiếu đến một Library, được truyền vào qua hàm khởi tạo, và triển khai cả ba phương thức bằng cách ủy quyền cho Library, đồng thời đưa ra thông báo phù hợp. Khi thêm sách, hãy tạo một Book mới rồi thêm vào thư viện. Khi đăng ký người dùng, hãy tạo một User mới rồi đăng ký họ.Main.java: Hãy trình diễn hệ thống quản trị của bạn! Bạn sẽ nhận một loạt lệnh quản trị dưới dạng một chuỗi, các lệnh được phân tách bằng dấu phẩy. Mỗi lệnh có một trong các định dạng sau:ADD_BOOK:isbn:title:authorREMOVE_BOOK:isbnREGISTER_USER:id:nameBORROW:userId:isbn
Tạo một Library và một AdminService. Xử lý từng lệnh rồi in kết quả:
- Với ADD_BOOK: in
Added: [title]nếu thành công - Với REMOVE_BOOK: in
Removed: [isbn]nếu thành công, hoặcCannot remove: [isbn]nếu sách không tồn tại hoặc đang được mượn - Với REGISTER_USER: in
Registered: [name] - Với BORROW: sử dụng chức năng mượn sách hiện có của thư viện
Sau khi xử lý tất cả lệnh, in
Library status:, rồi in thông tin chi tiết và trạng thái còn hay đã được mượn của từng cuốn sách theo định dạng[details] - [Available/Borrowed].
Bạn sẽ nhận một đầu vào: chuỗi lệnh được phân tách bằng dấu phẩy.
Ví dụ, với đầu vào REGISTER_USER:U001:Alice,ADD_BOOK:ISBN-001:Clean Code:Robert Martin,ADD_BOOK:ISBN-002:Design Patterns:Gang of Four,BORROW:U001:ISBN-001,REMOVE_BOOK:ISBN-001,REMOVE_BOOK:ISBN-002, đầu ra sẽ là:
Registered: Alice
Added: Clean Code
Added: Design Patterns
Alice borrowed Clean Code
Cannot remove: ISBN-001
Removed: ISBN-002
Library status:
[ISBN-001] Clean Code by Robert Martin - BorrowedHãy chú ý cách giao diện quản trị đưa ra một hợp đồng rõ ràng cho các thao tác quản trị, trong khi phần triển khai AdminService xử lý logic thực tế. Hệ thống ngăn xóa sách đang được mượn, đồng thời cho phép xóa sách hiện có sẵn. Việc tách riêng giao diện và phần triển khai là một nguyên tắc OOP quan trọng, giúp code dễ bảo trì và kiểm thử hơn!
Tự làm thử
import java.util.Scanner;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Đọc các lệnh được phân tách bằng dấu phẩy
String input = scanner.nextLine();
String[] commands = input.split(",");
// Tạo Library và AdminService
Library library = new Library();
AdminService adminService = new AdminService(library);
// Xử lý từng lệnh
for (String command : commands) {
String[] parts = command.split(":");
String operation = parts[0];
if (operation.equals("ADD_BOOK")) {
String isbn = parts[1];
String title = parts[2];
String author = parts[3];
if (adminService.addBook(isbn, title, author)) {
System.out.println("Added: " + title);
}
} else if (operation.equals("REMOVE_BOOK")) {
String isbn = parts[1];
if (adminService.removeBook(isbn)) {
System.out.println("Removed: " + isbn);
} else {
System.out.println("Cannot remove: " + isbn);
}
} else if (operation.equals("REGISTER_USER")) {
String id = parts[1];
String name = parts[2];
if (adminService.registerUser(id, name)) {
System.out.println("Registered: " + name);
}
} else if (operation.equals("BORROW")) {
String userId = parts[1];
String isbn = parts[2];
library.borrowBook(userId, isbn);
}
}
// In ra trạng thái thư viện
System.out.println("Library status:");
ArrayList<Book> allBooks = library.getAllBooks();
for (Book book : allBooks) {
String status = book.isAvailable() ? "Available" : "Borrowed";
System.out.println(book.getDetails() + " - " + status);
}
}
}
Tất cả bài học trong Lập trình hướng đối tượng
1Kiến thức cơ bản về lập trình hướng đối tượng
Tệp bên ngoàiGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcTrường (thuộc tính)Phương thức khởi tạoNạp chồng phương thức khởi tạoÔn tập: Máy tính đơn giản4Kế thừa
Kế thừa cơ bản (extends)Từ khóa superGhi đè phương thức (@Override)Chuỗi gọi hàm khởi tạoLớp ObjectKế thừa đơn và đa cấpVì sao không hỗ trợ kế thừa nhiều lớpÔn tập: Phân cấp lớp Employee7Phương thức đặc biệt và lớp Object
Phương thức toString()equals() và hashCode()Phương thức clone()compareTo() và ComparableGiao diện ComparatorÔn tập: sắp xếp tùy chỉnh10Xử lý ngoại lệ trong OOP
Phân cấp lớp ngoại lệNgoại lệ tùy chỉnhLỗi có kiểm tra và không kiểm traMẫu try-with-resourcesÔn tập: người dùng đã xác thực13Dự án: Quản lý thư viện
Tổng quan dự án và thiết kế UMLLớp sách và người dùngHệ thống mượn sáchChức năng tìm kiếmGiao diện quản trịTích hợp xử lý ngoại lệKiểm thử và tích hợp2Bộ điều chỉnh quyền truy cập và đóng gói
Tổng quan về các mức truy cậpPhương thức getter và setterẨn thông tinTừ khóa finalÔn tập: Trình quản lý tài khoản ngân hàng5Tính đa hình
Kiến thức cơ bản về nạp chồng phương thứcGhi đè phương thức (thời gian chạy)Chuyển kiểu lên và chuyển kiểu xuốngToán tử instanceofLớp và phương thức trừu tượngÔn tập: máy tính hình học8Khái niệm OOP nâng cao
Kết hợp và kế thừaKết tập và hợp thànhLớp bên trong, lớp lồng nhau và lớp ẩn danhKiểu enum và phương thức enumBản ghi (Java 16+)Lớp sealed (Java 17+)3Thuộc tính lớp và thành viên tĩnh
Biến của instance và biến tĩnhPhương thức tĩnhKhối tĩnhHằng số (static final)Ôn tập: bộ đếm và tiện ích6Giao diện và lớp trừu tượng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnPhương thức mặc định và tĩnh trong giao diệnLớp trừu tượng và giao diệnGiao diện hàmÔn tập: hệ thống thanh toán9Kiểu tổng quát
Giới thiệu về kiểu tổng quátLớp tổng quátPhương thức tổng quátTham số kiểu có giới hạnKý tự đại diện (?, extends, super)Ôn tập: vùng chứa tổng quát12Mẫu thiết kế, phần 2
Mẫu CommandMẫu AdapterMẫu DecoratorMẫu Template MethodMẫu StateMẫu CompositeMẫu IteratorTự luyện tập: Trình biên dịch Java online