class ModeloIA:def__init__(self):self.datos = []self.modelo =Nonedef cargar_datos(self, ruta):# Mezcla lógica de lectura de datos con procesamientowithopen(ruta, "r") as f:self.datos = [line.strip().split(",") for line in f]self.limpiar_datos()def limpiar_datos(self):# Limpieza de datos dentro del mismo móduloself.datos = [fila for fila inself.datos iflen(fila) ==3]def entrenar_modelo(self):# Lógica de entrenamiento dentro del mismo móduloself.modelo =sum(len(fila) for fila inself.datos)def predecir(self, entrada):returnself.modelo *len(entrada) ifself.modelo elseNone
class ModeloIA:def__init__(self):self.modelo =Nonedef entrenar(self, datos):# Simulación de entrenamientoself.modelo =sum(len(fila) for fila in datos)def predecir(self, entrada):returnself.modelo *len(entrada) ifself.modelo elseNone# Acoplamiento fuerte: depende directamente de ModeloIAclass ProcesadorDatos:def__init__(self):self.datos = []self.modelo = ModeloIA()def cargar_datos(self, ruta):withopen(ruta, "r") as f:self.datos = [line.strip().split(",") for line in f]self.limpiar_datos()self.modelo.entrenar(self.datos) # Acoplamiento fuerte: entrenar directamente aquídef limpiar_datos(self):self.datos = [fila for fila inself.datos iflen(fila) ==3]def predecir(self, entrada):returnself.modelo.predecir(entrada) # Llama directamente al modelo
class ProcesadorDatos:def init(self):self.datos = []def cargar_datos(self, ruta):withopen(ruta, "r") as f:self.datos = [line.strip().split(",") for line in f]self.limpiar_datos()def limpiar_datos(self):self.datos = [fila for fila inself.datos iflen(fila) ==3]def obtener_datos(self):returnself.datosclass ModeloIA:def init(self):self.modelo =Nonedef entrenar(self, datos):self.modelo =sum(len(fila) for fila in datos)def predecir(self, entrada):returnself.modelo *len(entrada) ifself.modelo elseNoneprocesador = ProcesadorDatos()procesador.cargar_datos("datos.csv")datos = procesador.obtener_datos()modelo = ModeloIA()modelo.entrenar(datos)prediccion = modelo.predecir([1, 2, 3])print(prediccion)
RECUERDA
Reutilizar código NO es ❌ copiar y pegar ❌
El código reutilizable debe diseñarse para que funcione bien en distintos contextos sin modificaciones.
Por ejemplo, al realizar pruebas automáticas estamos cambiando el contexto:
Llamando a funciones de forma aislada
Pasando datos falsos
Simulando el comportamiento de librerías externas
Principios de Diseño de Software
Son directrices que ayudan a crear software mantenible, reutilizable y escalable.
Aplicables en el diseño de sistemas orientados a objetos y arquitectura de software.
Algunos principios fundamentales…
DRY (Don’t Repeat Yourself)
Evitar duplicación de código
KISS (Keep It Simple, Stupid)
Diseñar soluciones simples y comprensibles
YAGNI (You Ain’t Gonna Need It)
No implementar funcionalidades innecesarias
Separation of Concerns
Dividir el software en módulos con responsabilidades claras
Para poder diseñar y comprender sistemas complejos necesitamos visualizarlos usando herramientas que nos permitan ver solamente la información más relevante.
Lenguajes visuales (diagramas)
UML
UML (Unified Modeling Language) es un lenguaje de modelado visual estándar para representar el diseño de sistemas de software.
Facilita la comunicación entre desarrolladores, analistas y otros interesados en el proyecto.
Permite modelar estructuras, comportamientos e interacciones dentro de un sistema.
Es independiente del lenguaje de programación y se usa en múltiples dominios.