🔁 Prototype - EmilioCrespoPeran/pattern-designs GitHub Wiki
📚 Descripción del patrón
El patrón Prototype permite crear nuevos objetos copiando uno ya existente, útil cuando el proceso de creación es costoso o requiere una configuración compleja.
🧩 Enunciado del ejercicio
Modela un sistema de construcción de planos arquitectónicos. Cada plano puede ser clonado siempre que sus datos sean válidos.
Clases involucradas:
Plano
con atributos: tipo, alto, ancho, habitaciones, arquitecto, zonaComunal.- Interfaz
ClonableElemento<T>
con métodosclonar()
yesValido()
. - La clase
ZonaComunal
también implementaClonableElemento
.
Requisitos:
- La clonación debe hacer copia profunda (
deep copy
) de listas y objetos compuestos. - Si los datos son inválidos, lanzar
CloneNotSupportedException
.
🧪 Test
@SpringBootTest
public class PrototypePlanoTests {
@Test
void alClonar_unPlanoDebeMantenerTodosLosValoresIncluyendoZona() throws CloneNotSupportedException {
ZonaComunal zona = new ZonaComunal("Parque Central", 200, true);
Plano original = new Plano("Departamento", 80, 100, List.of("Sala", "Cocina", "Baño"), "Arq. Gómez", zona);
Plano copia = original.clonar();
assertEquals(original.getTipo(), copia.getTipo());
assertEquals(original.getAlto(), copia.getAlto());
assertEquals(original.getAncho(), copia.getAncho());
assertEquals(original.getHabitaciones(), copia.getHabitaciones());
assertEquals(original.getArquitecto(), copia.getArquitecto());
assertEquals(original.getZonaComunal().getNombre(), copia.getZonaComunal().getNombre());
assertNotSame(original, copia);
assertNotSame(original.getZonaComunal(), copia.getZonaComunal());
}
@Test
void alModificarLaCopia_noDebeAfectarAlOriginal() throws CloneNotSupportedException {
ZonaComunal zona = new ZonaComunal("Azotea", 80, false);
Plano original = new Plano("Casa", 100, 120, List.of("Sala", "Habitación"), "Arq. Perez", zona);
Plano copia = original.clonar();
copia.getHabitaciones().add("Garaje");
copia.getZonaComunal().setNombre("Nueva Zona");
assertNotEquals(original.getHabitaciones().size(), copia.getHabitaciones().size());
assertNotEquals(original.getZonaComunal().getNombre(), copia.getZonaComunal().getNombre());
}
@Test
void alClonar_conZonaInvalidaDebeLanzarExcepcion() {
ZonaComunal zona = new ZonaComunal("", -10, false); // inválida
Plano plano = new Plano("Oficina", 60, 70, List.of("Cubículo", "Recepción"), "Arq. Vega", zona);
assertThrows(CloneNotSupportedException.class, plano::clonar);
}
@Test
void alClonar_sinZonaComunalDebeLanzarExcepcion() {
Plano plano = new Plano("Loft", 50, 50, List.of("Área única"), "Arq. Silva", null);
assertThrows(CloneNotSupportedException.class, plano::clonar);
}
}