4. Aplicación patrón de diseño Python - Jacoroch/PocketGymbro-Project GitHub Wiki

Descripción de los Cambios

Escogimos Builder Pattern debido a que Esto permite separar la construcción de un objeto complejo (una rutina de ejercicios con diferentes parámetros como duración, tipo de ejercicios, etc.) de su representación

Ejemplo de uso:

Implementar un "WorkoutPlanBuilder" que permita crear diferentes tipos de planes de ejercicios (cardio, fuerza, etc.) paso a paso, añadiendo ejercicios individuales y configurando sus detalles.

Creación de la Clase RoutineBuilder

Se ha añadido una nueva clase RoutineBuilder en el archivo builders.py dentro de la aplicación gymapp. Esta clase encapsula la lógica para construir rutinas de ejercicio día por día, permitiendo que la construcción de la rutina sea más clara y modular.

Ubicación: gymapp/builders.py

class RoutineBuilder:
    def __init__(self):
        self.routine = {
            "Lunes": {},
            "Martes": {},
            "Miercoles": {},
            "Jueves": {},
            "Viernes": {},
            "Sabado": {},
            "Domingo": {}
        }

    def add_day_routine(self, day, approx_time, rest_time, warm_up, exercises):
        """
        Add routine details for a given day.
        """
        self.routine[day] = {
            "Tiempo_Aproximado": approx_time,
            "Tiempo_de_Descanso": rest_time,
            "Calentamiento": warm_up,
            "Ejercicios": exercises
        }
        return self

    def add_rest_day(self, day):
        """
        Mark a day as a rest day.
        """
        self.routine[day] = {"Descanso": "Descanso"}
        return self

    def build(self):
        """
        Return the final routine structure.
        """
        return self.routine

Responsabilidades del Builder:

Construir una rutina semanal, añadiendo detalles de ejercicio para cada día. Separar la lógica de días de ejercicio y días de descanso, facilitando su manipulación. Permitir la adición de nuevos elementos o reglas de manera sencilla, sin cambiar la estructura de las views. Refactorización de la View weeklyRutina

La lógica para crear y estructurar la rutina semanal se ha trasladado de la view weeklyRutina al RoutineBuilder, haciendo la view más limpia y sencilla. Ahora, la view se enfoca principalmente en manejar la solicitud del usuario y pasar los datos necesarios al Builder para construir la rutina.

Antes: La view weeklyRutina contenía la lógica para procesar cada día de la semana, manejar los detalles de cada ejercicio, y controlar cómo se estructuraba la rutina.

Después: Ahora la view utiliza RoutineBuilder para construir la rutina y solo pasa los detalles necesarios al Builder. Esto permite que el manejo de la rutina sea más claro y facilita la modificación de la lógica de construcción en el futuro.

Código Modificado de la View weeklyRutina:

from .builders import RoutineBuilder

@login_required
def weeklyRutina(request):
    if request.method == 'POST':
        if request.POST.get('action') == 'Save':
            respuesta_v = repuestaJson(request.POST.get('r'))
            Rutina_Semanal.objects.update_or_create(user=request.user, defaults={'horario': respuesta_v})
            return redirect('/main')

        user_input = request.POST.get('user_input')
        place = request.POST.get('place')
        perfil = Perfil.objects.get(user=request.user)
        deporte = perfil.deporte_practicado
        objetivo = perfil.objetivos
        condiciones = perfil.condiciones_medicas
        genero = perfil.genero
        edad = calcular_edad(perfil.fecha_Nacimiento)
        
        try:
            equipa = Equipamiento_Del_Usuario.objects.get(user=request.user)
            equipa = equipa.equp_gimnasio if place == 'Gym' else equipa.equp_casa
            equipa = equipa or 'No especificado'
        except ObjectDoesNotExist:
            equipa = 'No especificado'

        # Solicitud de generación de rutina
        solicitud = '''Necesito que actues como un entrenador deportivo de alta calidad... (La misma solicitud que usabas)'''
        
        # Llamar al servicio de generación de rutina y obtener la respuesta
        respuestaVanilla = get_completion(solicitud)
        respuestaDict = repuestaJson(respuestaVanilla)

        # Usar el RoutineBuilder para crear la rutina
        builder = RoutineBuilder()
        
        # Añadir ejercicios a los días de la semana usando el builder
        for day, details in respuestaDict.items():
            if "Descanso" in details:
                builder.add_rest_day(day)
            else:
                builder.add_day_routine(
                    day=day,
                    approx_time=details.get("Tiempo_Aproximado", ""),
                    rest_time=details.get("Tiempo_de_Descanso", ""),
                    warm_up=details.get("Calentamiento", ""),
                    exercises=details.get("Ejercicios", {})
                )

        # Construir la rutina final
        weekly_routine = builder.build()

        return render(request, 'rutina_s.html', {'respuestaV': respuestaVanilla, 'entreno': weekly_routine})
    else:
        return render(request, 'rutina_s.html')

Beneficios de Implementar el Builder Pattern

Modularidad:

La lógica de construcción de la rutina ahora está separada en una clase dedicada (RoutineBuilder), lo que facilita añadir nuevas funcionalidades o cambiar la lógica de construcción sin afectar la view.

Reutilización de Código:

El RoutineBuilder se puede reutilizar en cualquier otra parte de la aplicación donde sea necesario construir una rutina semanal, asegurando consistencia en la estructura de las rutinas.

Mantenimiento Mejorado:

Al mover la lógica de construcción a una clase separada, el código se vuelve más fácil de mantener y entender, reduciendo la complejidad de las views.