Модели книг и пользователей
Часть раздела Объектно-ориентированное программирование путешествия по C# на Coddy — урок 63 из 70.
Задание
ЛегкоДавайте расширим вашу систему библиотеки (Library System), добавив более богатый функционал для моделей Book и User. Вы добавите отслеживание статуса для книг, возможности заимствования для пользователей и надлежащую инкапсуляцию для защиты ваших данных.
Вы продолжите работать со структурой из четырех файлов:
Book.cs: Улучшите ваш класс Book, добавив уникальный идентификатор и отслеживание статуса. Каждая книга должна иметьId(string),Title(string),Author(string) иIsAvailable(bool, по умолчанию true). Добавьте методыBorrow()иReturn(), которые меняют статус доступности и возвращают сообщение об успехе или неудаче. Если кто-то пытается взять недоступную книгу, верните"{Title} is not available". Если пытаются вернуть книгу, которая и так доступна, верните"{Title} was not borrowed". Успешные операции должны возвращать"{Title} has been borrowed"или"{Title} has been returned".User.cs: Расширьте ваш класс User для отслеживания взятых книг. ВключитеName(string),MemberId(int) и приватный список для хранения IDs взятых книг. Добавьте свойство только для чтенияBorrowedCount, которое возвращает, сколько книг сейчас находится у пользователя. Включите методыAddBorrowedBook(string bookId)иRemoveBorrowedBook(string bookId)для управления взятыми книгами пользователя. Также добавьте методHasBook(string bookId), который возвращает true, если пользователь взял именно эту книгу.Library.cs: Ваш класс Library должен хранить коллекции книг и пользователей. Включите методыAddBook(Book book)иRegisterUser(User user)для наполнения библиотеки. Добавьте методGetBookById(string id), который возвращает книгу с этим ID (или null, если не найдена), иGetUserById(int memberId), который работает аналогично для пользователей.Program.cs: Объедините всё вместе, обрабатывая операции библиотеки на основе входных данных.
Вы получите следующие входные данные:
- Название библиотеки
- Количество добавляемых книг
- Для каждой книги:
id|title|author - Количество регистрируемых пользователей
- Для каждого пользователя:
name|memberId - Количество выполняемых операций
- Для каждой операции:
action|bookId|memberId, где action либоborrow, либоreturn
Для каждой операции выведите результат действия borrow или return. После всех операций выведите сводку для каждого пользователя с указанием его имени и количества книг, которые у него сейчас находятся, в формате {Name}: {BorrowedCount} book(s).
Например, если входные данные следующие:
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Вывод должен быть таким:
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)Обратите внимание, как Alice успешно берет две книги, но когда Bob пытается взять Clean Code (которая уже у Alice), операция завершается неудачей. После того как Alice возвращает Clean Code, её счетчик уменьшается до 1. Это демонстрирует, как ваши модели работают вместе для обеспечения правил библиотеки!
Попробуйте сами
using System;
using System.Collections.Generic;
namespace LibrarySystem
{
class Program
{
public static void Main(string[] args)
{
// Прочитать название библиотеки
string libraryName = Console.ReadLine();
// Создать экземпляр Library с названием библиотеки
Library library = new Library(libraryName);
// Прочитать количество книг
int numBooks = Convert.ToInt32(Console.ReadLine());
// Прочитать и добавить книги
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);
}
// Прочитать количество пользователей
int numUsers = Convert.ToInt32(Console.ReadLine());
// Прочитать и зарегистрировать пользователей
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);
}
// Прочитать количество операций
int numOperations = Convert.ToInt32(Console.ReadLine());
// Обработать операции
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);
}
}
}
// Вывести сводку для каждого пользователя
foreach (User user in usersList)
{
Console.WriteLine($"{user.Name}: {user.BorrowedCount} book(s)");
}
}
}
}Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыПространства имен и директивыВведение в классы и объектыКлючевое слово 'this'Методы и параметрыПоля и свойстваКонструкторыИнициализаторы объектовИтоги — Простой калькулятор4Наследование
Основы синтаксиса наследования (:)Ключевое слово 'base'Ключевые слова Virtual и OverrideЗапечатанные классыБазовый класс 'object'Итоги — Иерархия сотрудников7Продвинутые возможности
Перегрузка операторовИндексаторы (this[])Переопределение ToString()Методы расширенияПовторение — Пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПотокобезопасный SingletonПаттерн FactoryПаттерн Observer (События)Паттерн Strategy13Финальные испытания
Платформа для онлайн-обученияКомпонент игрового персонажаСервис аренды транспорта2Свойства и статические члены
Автоматически реализуемые свойстваСвойства только для чтения и записиСтатические поля и методыСтатические классыЧлены в виде выражений5Полиморфизм и интерфейсы
Полиморфизм: компиляция vs выполнениеИнтерфейс vs абстрактный классМножественные интерфейсыЯвные интерфейсыUpcasting и DowncastingИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция вместо наследованияGenerics (классы и методы)Делегаты и событияАтрибуты и рефлексияIDisposable и оператор usingОсновы Dependency Injection11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Архитектура классов
Экземплярные и статические данныеКлючевые слова 'readonly' и 'const'Опорные поляПовторение — Менеджер банковских счетов6Инкапсуляция
Модификаторы доступаСвойства для инкапсуляцииРеализация скрытия данныхПаттерны неизменяемостиИтоги — Записи студентов9Переменное количество аргументов
Ключевое слово 'params'Необязательные параметрыИменованные аргументыПерегрузка методов12Проект: Система библиотеки
Структура проектаМодели книг и пользователейЛогика системы выдачи книгLINQ для поискаКонсольный UI / Интерфейс администратораUnit-тестирование (NUnit/xUnit)