03 - La Forja: el modelo del gremio
La plantilla vive en arrays paralelos que se desincronizan a la primera, la clase de juego sigue siendo un número (1) que solo entiende un switch, la validación está repartida por todo el código y la forja todavía no existe ni como modelo. Este paso construye de una vez el modelo del gremio con las herramientas del tema: clases, visibilidad, getters y setters, constructores, this, miembros estáticos y enumerados; y herencia y super, métodos de Object, polimorfismo, composición, clases abstractas e interfaces.
1. Qué se pide
- El héroe, como objeto:
- Un héroe, una unidad: todos sus datos viven juntos, no repartidos en arrays con posiciones casadas a ojo. La plantilla pasa a ser un array de objetos.
- La clase de juego deja de ser un número: es un enum con nombre propio — y cada clase lleva consigo lo que la distingue (para el poder de combate, cada una aporta su valor).
- Cada héroe recibe un identificador único que nadie teclea: lo asigna el diseño y no se repite entre héroes.
- Lo que no es válido se detiene donde se guarda: un solo punto decide qué es un nivel (o un nombre, o una clase) correcto, y el resto del programa no repite la comprobación. Esta validación es rudimentaria a propósito — el tema 05 la endurecerá con excepciones —, pero el punto único se construye ya.
- Los
switchcon números mágicos desaparecen: la opción del menú se convierte en el enum una sola vez, y a partir de ahí el programa solo habla de clases con nombre.
- La jerarquía:
Heroees una clase abstracta desde el principio: lo común de todo héroe vive en la superclase, y lo específico de cada clase de juego, en su subclase — cada una con su atributo distintivo (la fuerza del guerrero, el maná del mago, la precisión del arquero) y su habilidad con nombre.- El poder de combate de un héroe sale de lo común más lo específico de su clase, y cada objeto sabe describirse en su ficha sin que nadie pregunte de cuál es: ahí está el polimorfismo.
- Los atributos y los métodos comunes no se repiten en las subclases: para eso está el constructor de la superclase.
- La forja:
- Nace el almacén de ítems: nombre y rareza (enum: común, raro, épico, legendario), y de cada uno hay tres tipos con comportamiento propio — arma con daño, armadura con defensa y poción de curación.
- Consumir es una acción que no vale para todo: lo consumible se declara en una interfaz; el resto del programa no adivina.
- La forja no debe guardar dos veces el mismo ítem: dos ítems se identifican por nombre y rareza con
equalsyhashCode. Hoy solo se garantiza la condición a mano — la estructura que la exigirá llega en el 04.
- El estado:
- El gremio es un objeto propio: un guerrero es un héroe (herencia), pero el gremio tiene una plantilla y una forja (composición).
- La app sigue pasando todas las pruebas anteriores.
Cuidado con la tentación: la relación entre las clases de juego es herencia (el guerrero *es un* héroe); la relación entre el gremio y sus colecciones es composición (el gremio *tiene* una plantilla). No las intercambies por comodidad.
2. Con qué
- Todo lo del tema: clases y objetos, visibilidad de los miembros, getters y setters, constructores,
this, miembros estáticos y enum; y herencia ysuper, clases abstractas, interfaces, polimorfismo y enlazado dinámico, composición frente a herencia, y los métodos deObject:toStringpara las fichas yequals/hashCodepara la identidad de los ítems.
3. Decisiones tuyas
- ¿Qué contiene un héroe? Distingue lo esencial (sus datos), lo derivado (lo que se calcula: el poder, la ficha) y lo asignado (lo que el usuario nunca teclea).
- ¿Qué atributos son
privatey qué getters se publican? Regla de la casa: se publica lo mínimo que alguien necesita usar. - ¿Qué lleva el enum de la clase: solo el nombre, o también lo que depende de cada una? ¿Y cómo obtiene el resto del programa lo que el enum guarda?
- ¿Quién asigna el identificador y desde dónde se cuenta? Ese contador vivirá tiempo: en el paso 11 es protagonista.
- ¿Qué es exactamente común a todo héroe — y por eso vive en la superclase — y qué es único de cada clase de juego?
- ¿Qué describen las habilidades y cómo se redactan las fichas? ¿Dónde conviene
toStringy dónde un método propio? - ¿Qué hace a dos ítems “el mismo ítem”? Fíjate bien: la identidad se decide antes de que ninguna colección la use.
- ¿Qué métodos exige la interfaz de lo consumible y quiénes la implementan?
- ¿Dónde vive ahora el estado del gremio (plantilla, forja, contadores)? ¿La clase del menú deja de tener variables sueltas? ¿Y el límite de plazas se sigue contando igual con objetos?
4. Comprobación
- Registrar un héroe deja un objeto completo: listar y buscar muestran sus datos juntos, y ninguna posición puede desincronizarse del resto.
- No se puede crear un héroe genérico: la superclase no lo permite, y las subclases sí. Registrar un héroe de cada clase y listar: cada uno con su habilidad y su poder distintos.
- Añadir una cuarta clase de juego no toca el listado ni la ficha: solo nace una subclase, y el poder de la ficha varía de clase en clase porque lo específico pesa.
- El identificador aparece en la ficha sin que nadie lo haya tecleado, y dos héroes no lo comparten.
- Un nivel sin sentido no se guarda ni se calla: el punto de control lo decide, aunque hoy la consecuencia sea solo un aviso.
- En el código ya no quedan números de clase sueltos que interpretar: un solo lugar hace la conversión entre lo que teclea el usuario y el enum.
- Dos ítems con mismo nombre y rareza se consideran iguales; si difieren en cualquiera de las dos cosas, no. Se comprueba a mano: la colección que lo exigirá llega en el 04.
- Consumir una poción aplica su efecto al héroe; equipar un arma o una armadura no pasa por el consumo, porque no lo ofrecen.
- La clase del menú ya no tiene variables sueltas del gremio: el objeto que tiene plantilla y forja las concentra.
- Las pruebas del paso 02 siguen pasando: menú, listado, búsqueda y variantes con la misma consola.
5. Pendientes
- El array de la plantilla y el de la forja siguen fijando techos artificiales → colecciones (04).
- Consumir una poción exige eliminar elementos mientras se recorre el inventario: ahí hace falta un iterador seguro → (04).
equals/hashCodedeItemespera su consumidor: unSetque rechace duplicados → (04).- El usuario teclea letras en el nivel y la aplicación tumba, y el punto de control sigue avisando sin lanzar nada → excepciones (05).