Mô hình sách và người dùng
Thuộc phần Lập trình hướng đối tượng trong hành trình C# của Coddy. Bài học 63 trên 70.
Thử thách
DễHãy mở rộng Library System bằng cách bổ sung nhiều chức năng hơn cho các mô hình Book và User. Bạn sẽ thêm tính năng theo dõi trạng thái sách, khả năng mượn sách cho người dùng và tính đóng gói phù hợp để bảo vệ dữ liệu.
Bạn sẽ tiếp tục làm việc với cấu trúc gồm bốn tệp:
Book.cs: Bổ sung mã định danh duy nhất và tính năng theo dõi trạng thái cho lớp Book. Mỗi cuốn sách cần cóId(string),Title(string),Author(string) vàIsAvailable(bool, mặc định là true). Thêm các phương thứcBorrow()vàReturn()để thay đổi trạng thái sẵn có và trả về thông báo cho biết thao tác thành công hay thất bại. Nếu có người cố mượn một cuốn sách không có sẵn, hãy trả về"{Title} is not available". Nếu họ cố trả một cuốn sách vốn đã có sẵn, hãy trả về"{Title} was not borrowed". Các thao tác thành công cần trả về"{Title} has been borrowed"hoặc"{Title} has been returned".User.cs: Mở rộng lớp User để theo dõi những cuốn sách đã mượn. ThêmName(string),MemberId(int) và một danh sách riêng để lưu mã sách đã mượn. Thêm thuộc tính chỉ đọcBorrowedCountđể trả về số sách người dùng hiện đang mượn. Thêm các phương thứcAddBorrowedBook(string bookId)vàRemoveBorrowedBook(string bookId)để quản lý sách người dùng đã mượn. Đồng thời thêm phương thứcHasBook(string bookId), trả về true nếu người dùng đã mượn cuốn sách cụ thể đó.Library.cs: Lớp Library cần quản lý các bộ sưu tập sách và người dùng. Thêm các phương thứcAddBook(Book book)vàRegisterUser(User user)để thêm sách và người dùng vào thư viện. Thêm phương thứcGetBookById(string id)để trả về cuốn sách có mã đó (hoặc null nếu không tìm thấy), và phương thứcGetUserById(int memberId)hoạt động tương tự với người dùng.Program.cs: Kết hợp mọi thứ bằng cách xử lý các thao tác thư viện dựa trên đầu vào.
Bạn sẽ nhận các đầu vào sau:
- Tên thư viện
- Số sách cần thêm
- Với mỗi cuốn sách:
id|title|author - Số người dùng cần đăng ký
- Với mỗi người dùng:
name|memberId - Số thao tác cần thực hiện
- Với mỗi thao tác:
action|bookId|memberId, trong đó action làborrowhoặcreturn
Với mỗi thao tác, hãy in ra kết quả của hành động mượn hoặc trả sách. Sau khi hoàn tất mọi thao tác, hãy in bản tóm tắt cho từng người dùng, gồm tên và số sách họ hiện đang mượn, theo định dạng {Name}: {BorrowedCount} book(s).
Ví dụ, nếu đầu vào là:
Downtown Library
2
B001|Clean Code|Robert Martin
B002|Design Patterns|Gang of Four
2
Alice|101
Bob|102
4
borrow|B001|101
borrow|B002|101
borrow|B001|102
return|B001|101Đầu ra sẽ là:
Clean Code has been borrowed
Design Patterns has been borrowed
Clean Code is not available
Clean Code has been returned
Alice: 1 book(s)
Bob: 0 book(s)Lưu ý Alice mượn thành công hai cuốn sách, nhưng khi Bob cố mượn Clean Code, cuốn sách Alice đã mượn, thao tác sẽ thất bại. Sau khi Alice trả Clean Code, số sách cô ấy đang mượn giảm xuống còn 1. Điều này cho thấy các mô hình phối hợp với nhau như thế nào để thực thi các quy tắc của thư viện!
Tự làm thử
using System;
using System.Collections.Generic;
namespace LibrarySystem
{
class Program
{
public static void Main(string[] args)
{
// Đọc tên thư viện
string libraryName = Console.ReadLine();
// Tạo instance của Library với tên thư viện
Library library = new Library(libraryName);
// Đọc số lượng sách
int numBooks = Convert.ToInt32(Console.ReadLine());
// Đọc và thêm sách
for (int i = 0; i < numBooks; i++)
{
string bookInput = Console.ReadLine();
string[] bookParts = bookInput.Split('|');
string bookId = bookParts[0];
string bookTitle = bookParts[1];
string bookAuthor = bookParts[2];
Book book = new Book(bookId, bookTitle, bookAuthor);
library.AddBook(book);
}
// Đọc số lượng người dùng
int numUsers = Convert.ToInt32(Console.ReadLine());
// Đọc và đăng ký người dùng
List<User> usersList = new List<User>();
for (int i = 0; i < numUsers; i++)
{
string userInput = Console.ReadLine();
string[] userParts = userInput.Split('|');
string userName = userParts[0];
int memberId = Convert.ToInt32(userParts[1]);
User user = new User(userName, memberId);
library.RegisterUser(user);
usersList.Add(user);
}
// Đọc số lượng thao tác
int numOperations = Convert.ToInt32(Console.ReadLine());
// Xử lý các thao tác
for (int i = 0; i < numOperations; i++)
{
string operationInput = Console.ReadLine();
string[] opParts = operationInput.Split('|');
string action = opParts[0];
string bookId = opParts[1];
int memberId = Convert.ToInt32(opParts[2]);
Book book = library.GetBookById(bookId);
User user = library.GetUserById(memberId);
if (action == "borrow")
{
string result = book.Borrow();
Console.WriteLine(result);
if (result.Contains("has been borrowed"))
{
user.AddBorrowedBook(bookId);
}
}
else if (action == "return")
{
string result = book.Return();
Console.WriteLine(result);
if (result.Contains("has been returned"))
{
user.RemoveBorrowedBook(bookId);
}
}
}
// In ra thông tin tóm tắt cho từng người dùng
foreach (User user in usersList)
{
Console.WriteLine($"{user.Name}: {user.BorrowedCount} book(s)");
}
}
}
}Tất cả bài học trong Lập trình hướng đối tượng
1Các khái niệm cơ bản về lập trình hướng đối tượng
Tệp bên ngoàiKhông gian tên và chỉ thịGiới thiệu về lớp và đối tượngTừ khóa thisPhương thức và tham sốTrường và thuộc tínhHàm khởi tạoKhởi tạo đối tượngÔn tập: Máy tính đơn giản4Kế thừa
Cú pháp kế thừa cơ bản (:)Từ khóa 'base'Từ khóa virtual và overrideLớp sealedLớp cơ sở 'object'Ôn tập: hệ phân cấp nhân viên7Tính năng nâng cao
Nạp chồng toán tửBộ lập chỉ mục (this[])Ghi đè ToString()Phương thức mở rộngÔn tập: Danh sách tùy chỉnh10Các mẫu thiết kế phần 1
Giới thiệu về mẫu thiết kếSingleton an toàn với luồngMẫu FactoryMẫu Observer (sự kiện)Mẫu Strategy2Thuộc tính và thành viên tĩnh
Thuộc tính tự độngThuộc tính chỉ đọc hoặc chỉ ghiTrường và phương thức tĩnhLớp tĩnhThành viên có thân biểu thức5Đa hình và interface
Đa hình lúc biên dịch và lúc chạyInterface và lớp trừu tượngNhiều interfaceInterface tường minhUpcasting và downcastingÔn tập: bộ tính toán hình học8Các khái niệm OOP nâng cao
Ưu tiên composition hơn kế thừaGenerics (lớp và phương thức)Delegate và sự kiệnAttribute và reflectionGiao diện IDisposable và câu lệnh usingKiến thức cơ bản về dependency injection11Các mẫu thiết kế phần 2
Mẫu lệnhMẫu bộ chuyển đổiMẫu trang tríMẫu phương thức khuôn mẫuMẫu trạng tháiMẫu tổ hợp3Kiến trúc lớp
Dữ liệu instance và dữ liệu tĩnhTừ khóa 'readonly' và 'const'Trường lưu trữÔn tập: Trình quản lý tài khoản ngân hàng6Đóng gói
Bộ điều chỉnh quyền truy cậpThuộc tính để đóng góiTriển khai ẩn dữ liệuCác mẫu bất biếnÔn tập: hồ sơ học sinh12Dự án: hệ thống thư viện
Cấu trúc dự ánMô hình sách và người dùngLogic hệ thống mượn sáchLINQ để tìm kiếmGiao diện console / giao diện quản trịKiểm thử đơn vị (NUnit/xUnit)Tự luyện tập: Trình biên dịch C# online