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¡Demos vida a tu sistema de biblioteca implementando la lógica central de préstamos! Crearás un sistema centralizado que coordina los libros y los usuarios, aplicando las reglas de la biblioteca, como los límites de préstamo y asegurándose de que los libros solo puedan prestarse cuando estén disponibles.
Seguirás construyendo sobre tu estructura existente de cuatro archivos:
Book.cs: Conserva tu clase Book con las propiedadesId,Title,AuthoreIsAvailable, junto con los métodosBorrow()yReturn()de la lección anterior.User.cs: Conserva tu clase User conName,MemberId,BorrowedCounty los métodos para gestionar los 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 libros queMaxBooks.Library.cs: Aquí es donde se reúne 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 comprobar si el libro existe, si el usuario existe, si el libro está disponible y si el usuario puede pedir prestados más libros. Devuelve mensajes apropiados para cada caso de error o para una operación exitosa.ReturnBook(string bookId, int memberId): gestiona las devoluciones comprobando 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 no exista el ID del libroUser not found: cuando no exista el ID del miembro{Title} is not available: cuando el libro ya esté prestado{Name} has reached the borrowing limit: cuando el usuario ya tenga 3 libros{Name} borrowed {Title}: cuando el préstamo se realice correctamente
Tu método ReturnBook debe devolver:
Book not foundoUser not found: para IDs no válidos{Name} did not borrow {Title}: cuando el usuario intente devolver un libro que no tiene{Name} returned {Title}: cuando la devolución se realice correctamente
Recibirás las siguientes entradas:
- Nombre de la biblioteca
- Número de libros, después cada libro como
id|title|author - Número de usuarios, después cada usuario como
name|memberId - Número de operaciones, después 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 debe 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 coordinadora: valida todas las condiciones antes de permitir las operaciones, manteniendo las clases Book y User centradas 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 UsuarioLógica del Sistema de PréstamosLINQ para BúsquedasInterfaz de Consola / Interfaz de AdministradorPruebas Unitarias (NUnit/xUnit)Practica por tu cuenta: Compilador de C# online