Lógica del Sistema de Préstamos
Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy — lección 64 de 70.
Desafío
Fácil¡Vamos a dar vida a tu Sistema de Biblioteca implementando la lógica central de préstamos! Crearás un sistema centralizado que coordina entre libros y usuarios, aplicando reglas de la biblioteca como los límites de préstamo y asegurando que los libros solo se puedan prestar cuando estén disponibles.
Continuarás construyendo sobre tu estructura existente de cuatro archivos:
Book.cs: Mantén tu clase Book con las propiedadesId,Title,AuthoreIsAvailable, junto con los métodosBorrow()yReturn()de la lección anterior.User.cs: Mantén tu clase User conName,MemberId,BorrowedCounty los métodos para gestionar libros prestados. Añade una constanteMaxBooksestablecida en 3 que represente el número máximo de libros que un usuario puede pedir prestados a la vez. Añade un métodoCanBorrow()que devuelva true solo si el usuario ha pedido prestados menos deMaxBooks.Library.cs: Aquí es donde se une la lógica de tu sistema de préstamos. Tu clase Library debe tener colecciones de libros y usuarios, además de métodos para añadirlos. Implementa dos métodos clave:BorrowBook(string bookId, int memberId)- Coordina el proceso de préstamo. Debe verificar si el libro existe, si el usuario existe, si el libro está disponible y si el usuario puede pedir prestados más libros. Devuelve los mensajes apropiados para cada caso de fallo o éxito.ReturnBook(string bookId, int memberId)- Gestiona las devoluciones verificando que el usuario realmente tenga el libro antes de procesar la devolución.
Program.cs: Procesa las operaciones de la biblioteca y muestra los resultados.
Tu método BorrowBook debe devolver estos mensajes según la situación:
"Book not found"- cuando el ID del libro no existe"User not found"- cuando el ID del miembro no existe"{Title} is not available"- cuando el libro ya está prestado"{Name} has reached the borrowing limit"- cuando el usuario ya tiene 3 libros"{Name} borrowed {Title}"- en caso de préstamo exitoso
Tu método ReturnBook debe devolver:
"Book not found"o"User not found"- para IDs inválidos"{Name} did not borrow {Title}"- cuando el usuario intenta devolver un libro que no tiene"{Name} returned {Title}"- en caso de devolución exitosa
Recibirás las siguientes entradas:
- Nombre de la biblioteca
- Número de libros, luego cada libro como
id|title|author - Número de usuarios, luego cada usuario como
name|memberId - Número de operaciones, luego cada operación como
action|bookId|memberId
Imprime el resultado de cada operación en su propia línea.
Por ejemplo, si las entradas son:
Central Library
4
B001|The Hobbit|Tolkien
B002|1984|Orwell
B003|Dune|Herbert
B004|Foundation|Asimov
2
Alice|101
Bob|102
6
borrow|B001|101
borrow|B002|101
borrow|B003|101
borrow|B004|101
borrow|B001|102
return|B002|101La salida debería ser:
Alice borrowed The Hobbit
Alice borrowed 1984
Alice borrowed Dune
Alice has reached the borrowing limit
The Hobbit is not available
Alice returned 1984Observa cómo la clase Library actúa como el coordinador: valida todas las condiciones antes de permitir las operaciones, manteniendo tus clases Book y User enfocadas en sus propias responsabilidades. ¡Esta separación hace que tu código sea más fácil de mantener y probar!
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 añadir 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
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);
}
// 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]);
if (action == "borrow")
{
string result = library.BorrowBook(bookId, memberId);
Console.WriteLine(result);
}
else if (action == "return")
{
string result = library.ReturnBook(bookId, memberId);
Console.WriteLine(result);
}
}
}
}
}
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 Usuario