Incorporar las reglas de préstamo al objeto

JavaBeginner
Practicar Ahora

Introducción

Un mostrador comunitario presta herramientas físicas a miembros registrados. Dos taladros pueden tener el mismo nombre y pertenecer a préstamos distintos. Una herramienta en mantenimiento debe seguir sin estar disponible, y solo el prestatario registrado puede devolver una herramienta prestada.

Incorporarás estas reglas a un objeto Java y usarás un pequeño bucle de comandos preparado. Este primer laboratorio mantiene los cambios en memoria; el siguiente enseña a guardarlos. Debes conocer clases, métodos, campos privados, listas y excepciones básicas de Java. Tiempo de lectura y práctica estimado por el autor: 45 minutos.

Prestar una herramienta sin perder su identidad

En este paso, ejecutarás un préstamo normal, leerás el objeto preparado y añadirás la pequeña regla que lo protege de un segundo préstamo.

Abre la pestaña Terminal. cd selecciona la carpeta del proyecto; todos los comandos posteriores del shell en este laboratorio parten de ella. Si una línea mal escrita aún no se ha ejecutado, pulsa Ctrl+U para borrarla y vuelve a escribirla. Si aparece «file not found», ejecuta de nuevo este cd en vez de reiniciar el entorno.

cd /home/labex/project/tool-library

La aplicación preparada ya compila. javac es el compilador Java, -encoding UTF-8 selecciona la codificación del código fuente, -d out coloca las clases compiladas en out y *.java selecciona los archivos fuente Java de esta carpeta.

javac -encoding UTF-8 -d out *.java

Una compilación correcta no imprime nada. Después de editar, compila correctamente antes de cada inicio; de lo contrario, Java podría ejecutar clases antiguas. java inicia el programa, -Dfile.encoding=UTF-8 selecciona su codificación de texto, -cp out selecciona las clases compiladas y Desk es la clase de entrada. desk.tsv aporta los registros; --memory desactiva el guardado en este laboratorio.

java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv --memory

Estás dentro del programa del mostrador, no en el shell. Escribe cada línea y pulsa Enter:

borrow A11 M01
list
quit

Debes ver Accepted: A11 BORROWED M01. A12 es otro Drill, pero sigue AVAILABLE: el ID identifica una herramienta física, mientras que su nombre puede repetirse. quit vuelve al shell. Este préstamo normal funciona antes de la reparación, pero el código aún no impide que se vuelva a prestar. Como esta ejecución usó --memory, el archivo original no cambia y la siguiente ejecución empieza de nuevo.

Lee el código fuente preparado con cat, que muestra un archivo sin editarlo:

cat Tool.java

Una herramienta almacena un id estable, un name visible, un state, un borrower y una note. Un enum tiene un conjunto fijo de valores con nombre: AVAILABLE significa que nadie tiene la herramienta, BORROWED que la tiene un miembro y MAINTENANCE bloquea el préstamo. El guion - representa la ausencia de prestatario. Los campos privados solo pueden cambiar mediante métodos. Lee borrow: actualmente asigna BORROWED y un nuevo miembro sin comprobar el estado anterior. Predice qué sobrescribiría un segundo préstamo. El constructor, los getters y el enum ya están completos; consérvalos.

El marco de comandos también está preparado:

cat Desk.java

Busca la llamada found.borrow(c[2]) y el try/catch que la rodea. El bucle comprueba que exista el ID del miembro, pero un Tool debe proteger su propio estado. Una IllegalArgumentException se convierte en Rejected: ... y el bucle sigue abierto. La comprobación del estado debe ejecutarse antes de cualquiera de las asignaciones; lanzar la excepción después de modificarlo dejaría aplicado parcialmente un préstamo rechazado.

Antes de editar, crea una copia de seguridad solo del código fuente. mkdir -p crea una carpeta si hace falta; cp copia un archivo. Son tus propias copias de seguridad, no respuestas completas. No copies ni restablezcas los datos del mostrador o de los miembros.

mkdir -p work
cp Tool.java work/Tool-before-borrow.java.txt

Abre el archivo existente en nano, un editor de texto del terminal:

nano Tool.java

En nano, ^ en la barra de atajos significa Ctrl. Mantén Ctrl pulsado mientras presionas la otra tecla; no escribas el símbolo. Pulsa Ctrl+W, escribe state = State.BORROWED; y pulsa Enter para encontrar la asignación dentro de borrow. Pulsa Ctrl+A para ir al principio de esa línea. Usa las flechas para colocar el cursor y Backspace para corregir caracteres. Inserta esta condición de protección encima de la asignación, dejando las dos asignaciones existentes y el resto de la clase en su sitio:

        if (state != State.AVAILABLE) {
            throw new IllegalArgumentException("Tool is not available");
        }

Aquí, != significa «no es igual a». La condición rechaza tanto un préstamo existente como el mantenimiento; no cambia la identidad, el nombre ni la nota. Escribe la rama dentro del método existente en vez de reemplazar la clase. Revisa las llaves y el punto y coma.

Pulsa Ctrl+O para guardar, Enter para confirmar el nombre de archivo existente y Ctrl+X para salir. Para abandonar un error sin guardar, pulsa Ctrl+X y responde N cuando se pregunte si quieres guardar. Vuelve a abrir el archivo para intentarlo de nuevo. Desde el shell, nano Tool.java lo abre otra vez; Ctrl+W encuentra el mismo punto de referencia. Si hay un error de compilación, lee el archivo y la línea indicados, corrige esa ubicación en nano, guarda y recompila. No inicies el programa después de una compilación fallida.

Si necesitas deshacer todas las modificaciones del código fuente de este paso, el siguiente comando de recuperación restaura únicamente tu copia anterior de Tool.java. Pierdes esas modificaciones, así que úsalo solo cuando quieras empezar de nuevo esta edición del código; nunca restablece datos. Es una opción de recuperación, no el siguiente paso habitual:

cp work/Tool-before-borrow.java.txt Tool.java

Después de guardar la condición de protección (o de rehacerla tras la recuperación), compila e inicia:

javac -encoding UTF-8 -d out *.java
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv --memory

Escribe estos comandos del mostrador en orden:

borrow A11 M01
list
borrow A11 M02
borrow A13 M01
borrow TYPO M01
borrow A12 M02
list
quit

El primer préstamo se acepta. El préstamo duplicado y el de mantenimiento se rechazan intencionadamente con Rejected: Tool is not available. TYPO produce un rechazo por ID desconocido; corrige el ID en la línea siguiente sin restablecer el entorno. A12 todavía puede prestarse de forma independiente a M02. La lista final debe conservar A11 → M01 y el estado y la nota de mantenimiento de A13. quit vuelve al shell; desk.tsv permanece intacto. El método de devolución sigue incompleto y será el trabajo del siguiente paso.

Permitir que solo devuelva la herramienta el prestatario registrado

En este paso, completarás la transición inversa y conservarás los demás préstamos.

Empieza en la misma pestaña Terminal, desde el indicador del shell. La devolución solo es válida desde BORROWED y cuando el miembro indicado coincide con borrower. Para las cadenas Java, .equals() compara su contenido; ! niega esa comparación. Cuando ambas comprobaciones se cumplen, establece el estado en AVAILABLE y borra el prestatario asignándole -. Lanzar primero la excepción impide que una devolución fallida cambie solo parte del objeto.

Conserva la condición de protección del préstamo. Antes de la siguiente edición, crea otra copia de seguridad solo del código fuente para que la recuperación conserve el método de préstamo completado:

cp Tool.java work/Tool-before-return.java.txt
nano Tool.java

Pulsa Ctrl+W, busca state = State.AVAILABLE; y pulsa Enter. Es la primera asignación dentro de giveBack. Pulsa Ctrl+A para ir al principio de esa línea. Inserta las dos comprobaciones siguientes antes de ella; conserva la asignación del estado existente y borrower = "-"; después de ambas comprobaciones. No reemplaces la clase ni elimines la protección del préstamo.

        if (state != State.BORROWED) {
            throw new IllegalArgumentException("Tool is not borrowed");
        }
        if (!borrower.equals(member)) {
            throw new IllegalArgumentException("Borrower does not match");
        }

La primera rama rechaza una herramienta disponible o en mantenimiento. Solo una herramienta prestada llega a la comprobación de identidad. Compara el miembro con el prestatario registrado, no con un nombre visible. Revisa las llaves y pulsa Ctrl+O, Enter, Ctrl+X para guardar y salir. Si cometes un error sin guardar, Ctrl+X, N lo descarta. Corrige los errores de compilación reabriendo el archivo y buscando el método correspondiente; compila correctamente antes de iniciar. Para descartar deliberadamente las modificaciones de este paso conservando la protección del préstamo, usa cp work/Tool-before-return.java.txt Tool.java y después rehaz solo la edición de devolución. No restaures la copia anterior a la protección del préstamo.

Vuelve a compilar para que el programa use el código fuente actual y abre un nuevo mostrador en memoria. En este laboratorio, cada ejecución parte del archivo original.

javac -encoding UTF-8 -d out *.java
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv --memory

Escribe estos comandos del mostrador en orden:

list
return A14 M01
return A13 M03
return A14 M03
borrow A14 M02
list
quit

La primera lista muestra el préstamo existente A14 → M03. El prestatario incorrecto recibe Rejected: Borrower does not match. Devolver la herramienta en mantenimiento produce Rejected: Tool is not borrowed. Ninguno de los rechazos cambia el objeto. La devolución correcta produce Accepted: A14 AVAILABLE -, y M02 puede tomarla prestada después. A13 sigue en mantenimiento; A11 y A12 conservan sus ID y notas independientes.

Has expresado dos transiciones permitidas: AVAILABLE → BORROWED y BORROWED → AVAILABLE. No hay una transición de devolución desde MAINTENANCE, y esta aplicación no incluye un comando para gestionar el mantenimiento. Un rechazo es un resultado normal del negocio; no termina el bucle de comandos. Puedes ejecutar otra vez el programa para practicar. En este laboratorio, los cambios desaparecen deliberadamente tras quit; conserva el código fuente y continúa con el laboratorio independiente de persistencia para entender por qué.

Resumen

Usaste un enum y el estado privado del objeto para proteger los préstamos de herramientas. Las herramientas con el mismo nombre conservaron ID distintos, las acciones inválidas no alteraron el objeto y una devolución válida permitió prestar la herramienta a otro miembro. Guardar los resultados entre ejecuciones es el siguiente objetivo.