Modelos de Libro y Usuario
Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy — lección 63 de 70.
Desafío
FácilExpandamos tu sistema de biblioteca construyendo los modelos Book y User con una funcionalidad más rica. Añadirás seguimiento de estado para los libros, capacidad de préstamo para los usuarios y un encapsulamiento adecuado para mantener tus datos seguros.
Continuarás trabajando con tu estructura de cuatro archivos:
Book.cs: Mejora tu clase Book con un identificador único y seguimiento de estado. Cada libro debe tener unId(string),Title(string),Author(string) eIsAvailable(bool, con valor predeterminado true). Añade los métodosBorrow()yReturn()que cambien el estado de disponibilidad y devuelvan un mensaje indicando éxito o fallo. Si alguien intenta tomar prestado un libro no disponible, devuelve"{Title} is not available". Si intentan devolver un libro que ya está disponible, devuelve"{Title} was not borrowed". Las operaciones exitosas deben devolver"{Title} has been borrowed"o"{Title} has been returned".User.cs: Expande tu clase User para realizar un seguimiento de los libros prestados. IncluyeName(string),MemberId(int) y una lista privada para almacenar los IDs de los libros prestados. Añade una propiedad de solo lecturaBorrowedCountque devuelva cuántos libros tiene el usuario actualmente. Incluye los métodosAddBorrowedBook(string bookId)yRemoveBorrowedBook(string bookId)para gestionar los libros prestados del usuario. También añade un métodoHasBook(string bookId)que devuelva true si el usuario ha tomado prestado ese libro específico.Library.cs: Tu clase Library debe mantener colecciones de libros y usuarios. Incluye los métodosAddBook(Book book)yRegisterUser(User user)para poblar la biblioteca. Añade un métodoGetBookById(string id)que devuelva el libro con ese ID (o null si no se encuentra), yGetUserById(int memberId)que funcione de manera similar para los usuarios.Program.cs: Reúne todo procesando las operaciones de la biblioteca en función de las entradas.
Recibirás las siguientes entradas:
- Nombre de la biblioteca
- Número de libros a añadir
- Para cada libro:
id|title|author - Número de usuarios a registrar
- Para cada usuario:
name|memberId - Número de operaciones a realizar
- Para cada operación:
action|bookId|memberIddonde action esborroworeturn
Para cada operación, imprime el resultado de la acción borrow o return. Después de todas las operaciones, imprime un resumen para cada usuario mostrando su nombre y cuántos libros tiene prestados actualmente en el formato {Name}: {BorrowedCount} book(s).
Por ejemplo, si las entradas son:
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|101La salida debería ser:
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)Observa cómo Alice toma prestados con éxito dos libros, pero cuando Bob intenta tomar prestado Clean Code (que Alice ya tiene), la operación falla. Después de que Alice devuelve Clean Code, su conteo baja a 1. ¡Esto demuestra cómo tus modelos trabajan juntos para hacer cumplir las reglas de la biblioteca!
Pruébalo tú mismo
using System;
using System.Collections.Generic;
namespace LibrarySystem
{
class Program
{
public static void Main(string[] args)
{
// Leer el nombre de la biblioteca
string libraryName = Console.ReadLine();
// Crear una instancia de Library con el nombre de la biblioteca
Library library = new Library(libraryName);
// Leer el número de libros
int numBooks = Convert.ToInt32(Console.ReadLine());
// Leer y agregar libros
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);
}
// Leer el número de usuarios
int numUsers = Convert.ToInt32(Console.ReadLine());
// Leer y registrar usuarios
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);
}
// Leer el número de operaciones
int numOperations = Convert.ToInt32(Console.ReadLine());
// Procesar operaciones
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);
}
}
}
// Imprimir resumen para cada usuario
foreach (User user in usersList)
{
Console.WriteLine($"{user.Name}: {user.BorrowedCount} book(s)");
}
}
}
}Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosNamespaces y directivasIntro a clases y objetosLa palabra clave 'this'Métodos y parámetrosCampos vs PropiedadesConstructoresInicializadores de objetosResumen - Calculadora simple4Herencia
Sintaxis básica de herencia (:)La palabra clave 'base'Palabras clave Virtual y OverrideClases selladas (Sealed)La clase base 'object'Resumen: Jerarquía de empleados7Características avanzadas
Sobrecarga de operadoresIndexadores (this[])Sobrescritura de ToString()Métodos de extensiónResumen - Lista personalizada10Patrones de diseño - Parte 1
Introducción a los patrones de diseñoSingleton Thread-SafePatrón FactoryPatrón Observer (Eventos)Patrón Strategy2Propiedades y miembros estáticos
Propiedades autoimplementadasPropiedades de solo lectura y escrituraCampos y métodos estáticosClases estáticasMiembros con cuerpo de expresión5Polimorfismo e Interfaces
Polimorfismo: Compilación vs. EjecuciónInterfaz vs. Clase AbstractaInterfaces MúltiplesInterfaces ExplícitasUpcasting y DowncastingRepaso: Calculadora de Figuras8Conceptos avanzados de POO
Composición sobre herenciaGenéricos (clases y métodos)Delegados y eventosAtributos y ReflexiónIDisposable y la sentencia usingFundamentos de Inyección de dependencias11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Arquitectura de clases
Datos de instancia vs. estáticosPalabras clave 'readonly' y 'const'Campos de respaldoResumen - Gestor de cuentas bancarias6Encapsulamiento
Modificadores de accesoPropiedades para el encapsulamientoImplementación de ocultamiento de datosPatrones de inmutabilidadRepaso - Registros de estudiantes9Argumentos variables
La palabra clave 'params'Parámetros opcionalesArgumentos con nombreSobrecarga de métodos12Proyecto: Sistema de Biblioteca
Estructura del ProyectoModelos de Libro y UsuarioLógica del Sistema de PréstamosLINQ para BúsquedasInterfaz de Consola / Interfaz de AdministradorPruebas Unitarias (NUnit/xUnit)