-
Responsabilidades mal asignadas
Program.Mainmezcla lógica de negocio (hotel, veterinaria).Mascotausa unstringpara el tipo de animal → rompe el principio Open/Closed.HotelMascotasno controla instancias, se pueden crear múltiples hoteles.
-
Violaciones a SOLID
- SRP:
Programhace todo,Mascotamaneja tipo de animal como texto. - DIP:
Programdepende directamente de implementaciones concretas (ServicioVeterinario,HotelMascotas).
- SRP:
- Abstract Factory → para crear mascotas (
Perro,Gato). - Singleton → para asegurar que solo exista un
HotelMascotas. - SRP → separar responsabilidades (Main solo orquesta).
- DIP → uso de interfaces (
IServicioVeterinario,IHotelMascotas).
## Código Refactorizado con instrucciones
- name: Instalar .NET 8 y preparar entorno para Clínica Veterinaria y Hotel de Mascotas
hosts: localhost
become: yes
tasks:
- name: Actualizar sistema
apt:
update_cache: yes
upgrade: dist
- name: Instalar herramientas necesarias
apt:
name:
- apt-transport-https
- ca-certificates
- curl
- software-properties-common
state: present
- name: Descargar repositorio de Microsoft
command: wget https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb -O /tmp/packages-microsoft-prod.deb
- name: Instalar repositorio de Microsoft
command: dpkg -i /tmp/packages-microsoft-prod.deb
- name: Actualizar caché apt
apt:
update_cache: yes
- name: Instalar .NET SDK 8.0
apt:
name: dotnet-sdk-8.0
state: present
- name: Crear directorio del proyecto
file:
path: /home/ubuntu/clinica_mascotas_app
state: directory
- name: Crear archivo del proyecto
copy:
dest: /home/ubuntu/clinica_mascotas_app/clinica_mascotas_app.csproj
content: |
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
</Project>
- name: Crear código base con errores comunes para refactorizar
copy:
dest: /home/ubuntu/clinica_mascotas_app/Program.cs
content: |
using System;
namespace ClinicaMascotas
{
// ===============================
// Punto de entrada
// ===============================
public class Program
{
public static void Main(string[] args)
{
// Abstract Factory para crear mascotas
IMascotaFactory perroFactory = new PerroFactory();
IMascotaFactory gatoFactory = new GatoFactory();
Mascota dog = perroFactory.CrearMascota("Firulais");
Mascota cat = gatoFactory.CrearMascota("Mishi");
// DIP: dependemos de interfaces, no de implementaciones concretas
IServicioVeterinario servicio = new ServicioVeterinario();
IHotelMascotas hotel = HotelMascotas.GetInstance();
// Uso del servicio veterinario
servicio.RegistrarConsulta(dog);
servicio.RegistrarVacuna(cat);
// Uso del hotel (Singleton)
hotel.AsignarHabitacion(dog);
hotel.AsignarHabitacion(cat);
}
}
// ===============================
// Entidad Mascota
// ===============================
public abstract class Mascota
{
public string Nombre { get; private set; }
public string Tipo { get; private set; }
protected Mascota(string nombre, string tipo)
{
Nombre = nombre;
Tipo = tipo;
}
}
public class Perro : Mascota
{
public Perro(string nombre) : base(nombre, "Perro") { }
}
public class Gato : Mascota
{
public Gato(string nombre) : base(nombre, "Gato") { }
}
// ===============================
// Abstract Factory
// ===============================
public interface IMascotaFactory
{
Mascota CrearMascota(string nombre);
}
public class PerroFactory : IMascotaFactory
{
public Mascota CrearMascota(string nombre) => new Perro(nombre);
}
public class GatoFactory : IMascotaFactory
{
public Mascota CrearMascota(string nombre) => new Gato(nombre);
}
// ===============================
// Servicios veterinarios (SRP + DIP)
// ===============================
public interface IServicioVeterinario
{
void RegistrarConsulta(Mascota mascota);
void RegistrarVacuna(Mascota mascota);
}
public class ServicioVeterinario : IServicioVeterinario
{
public void RegistrarConsulta(Mascota mascota)
{
Console.WriteLine($"Consulta registrada para {mascota.Nombre}");
}
public void RegistrarVacuna(Mascota mascota)
{
Console.WriteLine($"Vacuna aplicada a {mascota.Nombre}");
}
}
// ===============================
// Hotel de mascotas (Singleton + DIP)
// ===============================
public interface IHotelMascotas
{
void AsignarHabitacion(Mascota mascota);
}
public class HotelMascotas : IHotelMascotas
{
private static HotelMascotas _instance;
private static readonly object _lock = new object();
// Constructor privado → Singleton
private HotelMascotas() { }
public static HotelMascotas GetInstance()
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
_instance = new HotelMascotas();
}
}
return _instance;
}
public void AsignarHabitacion(Mascota mascota)
{
Console.WriteLine($"Habitación asignada a {mascota.Nombre}");
}
}
} - name: Compilar la aplicación
command: dotnet build /home/ubuntu/clinica_mascotas_app/clinica_mascotas_app.csproj
args:
chdir: /home/ubuntu/clinica_mascotas_app
- name: Ejecutar la aplicación
command: dotnet run
args:
chdir: /home/ubuntu/clinica_mascotas_app
async: 10
poll: 0
🧾 Propuesta de calificación
Basándome en lo que cumple hasta ahora y las mejoras posibles, te propongo:
Calificación sugerida: 87 / 100
Motivos:
Realizaste un buen refactor que aplica Abstract Factory, Singleton y principios SOLID.
Integraste los componentes en un flujo funcional que cumple el propósito del dominio veterinaria / hotel.
No implementaste aún algunos patrones esperados (Builder, Prototype) ni pruebas, lo cual limita la profundidad del diseño para esta entrega.
Las mejoras señaladas son de tipo robustez, extensibilidad y calidad de código, más que errores fundamentales que invalidarían lo que hiciste.