Modele książki i użytkownika
Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 63 z 70.
Wyzwanie
ŁatwyRozbudujmy Twój system biblioteczny, tworząc bardziej funkcjonalne modele książek i użytkowników. Dodasz śledzenie statusu książek, możliwość ich wypożyczania przez użytkowników oraz odpowiednią enkapsulację, aby chronić dane.
Kontynuujesz pracę z czterema plikami:
Book.cs: Rozbuduj klasę Book o unikalny identyfikator i śledzenie statusu. Każda książka powinna miećId(string),Title(string),Author(string) orazIsAvailable(bool, domyślnie true). Dodaj metodyBorrow()iReturn(), które zmieniają status dostępności i zwracają komunikat informujący o powodzeniu lub niepowodzeniu. Jeśli ktoś spróbuje wypożyczyć niedostępną książkę, zwróć"{Title} is not available". Jeśli spróbuje zwrócić książkę, która jest już dostępna, zwróć"{Title} was not borrowed". Pomyślne operacje powinny zwracać"{Title} has been borrowed"lub"{Title} has been returned".User.cs: Rozbuduj klasę User, aby śledziła wypożyczone książki. UwzględnijName(string),MemberId(int) oraz prywatną listę do przechowywania identyfikatorów wypożyczonych książek. Dodaj tylko do odczytu właściwośćBorrowedCount, która zwraca liczbę książek, które użytkownik ma obecnie wypożyczone. Uwzględnij metodyAddBorrowedBook(string bookId)iRemoveBorrowedBook(string bookId)do zarządzania wypożyczonymi książkami użytkownika. Dodaj też metodęHasBook(string bookId), która zwraca true, jeśli użytkownik wypożyczył daną książkę.Library.cs: Klasa Library powinna przechowywać kolekcje książek i użytkowników. Uwzględnij metodyAddBook(Book book)iRegisterUser(User user), aby dodawać książki i użytkowników do biblioteki. Dodaj metodęGetBookById(string id), która zwraca książkę o podanym identyfikatorze (lub null, jeśli nie została znaleziona), oraz metodęGetUserById(int memberId), która działa podobnie dla użytkowników.Program.cs: Połącz wszystkie elementy, przetwarzając operacje biblioteczne na podstawie danych wejściowych.
Otrzymasz następujące dane wejściowe:
- Nazwa biblioteki
- Liczba książek do dodania
- Dla każdej książki:
id|title|author - Liczba użytkowników do zarejestrowania
- Dla każdego użytkownika:
name|memberId - Liczba operacji do wykonania
- Dla każdej operacji:
action|bookId|memberId, gdzie action toborrowlubreturn
Dla każdej operacji wypisz wynik wypożyczenia lub zwrotu. Po wykonaniu wszystkich operacji wypisz podsumowanie dla każdego użytkownika, zawierające jego imię i nazwisko oraz liczbę aktualnie wypożyczonych książek, w formacie {Name}: {BorrowedCount} book(s).
Na przykład, jeśli dane wejściowe to:
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|101Wynik powinien być następujący:
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)Zauważ, że Alice pomyślnie wypożycza dwie książki, ale gdy Bob próbuje wypożyczyć Clean Code (którą Alice ma już wypożyczoną), operacja kończy się niepowodzeniem. Gdy Alice zwraca Clean Code, liczba wypożyczonych przez nią książek spada do 1. To pokazuje, jak Twoje modele współpracują, aby egzekwować zasady biblioteki!
Spróbuj swoich sił
using System;
using System.Collections.Generic;
namespace LibrarySystem
{
class Program
{
public static void Main(string[] args)
{
// Wczytaj nazwę biblioteki
string libraryName = Console.ReadLine();
// Utwórz instancję Library z nazwą biblioteki
Library library = new Library(libraryName);
// Wczytaj liczbę książek
int numBooks = Convert.ToInt32(Console.ReadLine());
// Wczytaj i dodaj książki
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);
}
// Wczytaj liczbę użytkowników
int numUsers = Convert.ToInt32(Console.ReadLine());
// Wczytaj i zarejestruj użytkowników
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);
}
// Wczytaj liczbę operacji
int numOperations = Convert.ToInt32(Console.ReadLine());
// Przetwórz operacje
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);
}
}
}
// Wyświetl podsumowanie dla każdego użytkownika
foreach (User user in usersList)
{
Console.WriteLine($"{user.Name}: {user.BorrowedCount} book(s)");
}
}
}
}Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrznePrzestrzenie nazw i dyrektywyWprowadzenie do klas i obiektówSłowo kluczowe „this”Metody i parametryPola a właściwościKonstruktoryInicjalizatory obiektówPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawowa składnia dziedziczenia (:)Słowo kluczowe 'base'Słowa kluczowe virtual i overrideKlasy sealedBazowa klasa 'object'Powtórzenie – hierarchia pracowników7Zaawansowane funkcje
Przeciążanie operatorówIndeksery (this[])Nadpisywanie ToString()Metody rozszerzającePodsumowanie – własna lista2Właściwości i składowe statyczne
Właściwości automatyczneWłaściwości tylko do odczytu i zapisuPola i metody statyczneKlasy statyczneSkładowe z ciałem wyrażeniowym5Polimorfizm i interfejsy
Polimorfizm czasu kompilacji a czasu wykonaniaInterfejs a klasa abstrakcyjnaWiele interfejsówJawne implementowanie interfejsówRzutowanie w górę i w dółPowtórka — kalkulator kształtów8Zaawansowane koncepcje OOP
Kompozycja zamiast dziedziczeniaTypy generyczne (klasy i metody)Delegaty i zdarzeniaAtrybuty i refleksjaIDisposable i instrukcja usingPodstawy wstrzykiwania zależności11Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytu3Architektura klas
Dane instancji a dane statyczneSłowa kluczowe 'readonly' i 'const'Pola zapasowePowtórzenie — menedżer kont bankowych6Hermetyzacja
Modyfikatory dostępuWłaściwości w hermetyzacjiImplementacja ukrywania danychWzorce niezmiennościPowtórka — dane studentów9Argumenty zmiennej liczby
Słowo kluczowe „params”Parametry opcjonalneArgumenty nazwanePrzeciążanie metod12Projekt: System biblioteczny
Struktura projektuModele książki i użytkownikaLogika systemu wypożyczeńWyszukiwanie za pomocą LINQInterfejs konsolowy / interfejs administratoraTesty jednostkowe (NUnit/xUnit)Poćwicz samodzielnie: Kompilator C# online