Todo proyecto tiene uno de esos archivos. Lo abres y la barra de desplazamiento se vuelve fina como un hilo.
Este contenido continúa el artículo anterior Código oloroso #3.
Puede llamarse AppManager, MainViewController o DataStore. También es el archivo que más cambia y más conflictos provoca en el equipo.
Es un God Object.
En 『AntiPatterns』, publicado en 1998, se denomina The Blob (Información de publicación). Describe una masa que crece absorbiendo continuamente responsabilidades y datos del entorno.
Qué es un God Object
No se decide solo por el número de líneas. Un tipo de 2.000 líneas que hace una sola cosa sigue siendo simplemente un tipo grande (Estudio para identificar God Class).
Lo que distingue a un God Object es el alcance de lo que conoce. Si se cumplen las tres condiciones, casi seguro lo es.
- **Sabe demasiado.**Red, base de datos, estado de pantalla, credenciales y pagos conviven en un solo tipo.
importLa lista lo delata. - **Demasiadas cosas lo conocen.**Se referencia desde todo el proyecto. Si es un singleton, las rutas de referencia quedan ocultas y el problema empeora.
- **El estado está disperso.**Tiene treinta propiedades, pero nadie sabe qué combinaciones son válidas.
Ya no se puede responder si es posible que isLoading sea true mientras error tampoco sea nil.
En iOS, este papel suele estar claro: el controlador de vista.
El diseño de una pantalla, las llamadas de red, la fuente de datos de la tabla, las transiciones y la gestión del estado terminan en un solo archivo.
Esta estructura se llama Massive View Controller. También son habituales los tipos cuyo nombre incluye AppDelegate y Manager.
Por qué sigue creciendo
Nadie quiso construirlo así. Ese es el punto.
Un God Object no es una decisión de diseño, sino el resultado de la gravedad.
Supongamos que hay que añadir una función. Todos los datos necesarios ya están en esta clase.
| Elección | Coste |
|---|---|
| Añadir un método a la clase existente | 20 minutos |
| Crear un tipo nuevo | Pasar dependencias, preparar la inicialización y gestionar el ciclo de vida: medio día |
Cada elección es razonable, pero siempre apunta en la misma dirección. Así, un archivo de 200 líneas se convierte en uno de 4.000 tres años después.
Cada etapa de crecimiento tiene una justificación legítima, por eso es difícil deshacerla.
Además aparece el efecto de las ventanas rotas. Nadie protesta por añadir 50 líneas a un archivo que ya tiene 3.000.
La resistencia psicológica es distinta cuando se añaden 50 líneas a un archivo de 200.
Dónde duele
El daño aparece de cuatro formas.
- **Las pruebas se vuelven imposibles.**Para crear este tipo hacen falta red, base de datos y sesión de usuario. Quieres validar una lógica de cálculo pura, pero el servidor debe estar activo.
- **Se bloquea el trabajo en paralelo.**Tres personas desarrollan funciones distintas, pero todas modifican el mismo archivo. Los conflictos son constantes y los cambios se mezclan durante la revisión.
- **No se puede conocer el alcance de una modificación.**Para predecir qué romperá cambiar una propiedad hay que conocer las 4.000 líneas. Como nadie las conoce, se añade otra propiedad y el archivo vuelve a crecer.
- **No se puede reutilizar.**Otra pantalla necesita su lógica de formato de fechas, pero extraerla arrastra toda la clase. Así que se copia y pega.
La primera es especialmente grave. Sin pruebas no se puede dividir; como no se divide, sigue creciendo.
Este ciclo es la verdadera razón por la que un God Object sobrevive tanto tiempo.
Cómo detectar que crece
Usa señales, no sensaciones.
Señal 1 · Frecuencia de cambios en Git
Es el indicador más práctico. Si extraes la lista de archivos más modificados durante el último año, el God Object suele aparecer arriba.
git log --format=format: --name-only --since=1.year.ago \
| grep '\.swift$' | sort | uniq -c | sort -rn | head -20
Cambiar a menudo indica que el archivo cambia por razones distintas: una medición real de la violación del principio de responsabilidad única.
Señal 2 · Cohesión
Si los métodos solo tocan conjuntos distintos de propiedades, probablemente ese tipo sean en realidad dos.
Cinco métodos que usan solo A y B, y seis que usan solo C y D, ya muestran un posible límite.
Señal 3 · Regla de longitud del tipo
Con SwiftLint, type_body_length y file_length vienen activadas de forma predeterminada.
La advertencia predeterminada es de 250 líneas para el cuerpo del tipo y 400 para el archivo; puedes ajustarla al proyecto. Los números son arbitrarios, pero cruzar el límite inicia una conversación, y eso ya tiene valor.
Orden de extracción
Reescribirlo todo de una vez casi siempre falla. Hay un orden.
| # | Etapa | Qué hacer |
|---|---|---|
| 1 | Crear una red | Si no hay pruebas, empieza por crear pruebas de caracterización |
| 2 | Separar la lógica sin estado | Extrae primero el formato de fechas, la validación de cadenas y el cálculo de importes |
| 3 | Separar grupos de estado | Agrupa en un tipo las propiedades que cambian juntas |
| 4 | Separar por rol | Divide en fuente de datos, coordinador, modelo de vista y controladores de vista hijos |
| 5 | Cortar la ruta de absorción | Define dónde va el código nuevo y establece un umbral |
Una prueba de caracterización no registra si el código es correcto, sino cómo funciona ahora. Es una técnica descrita por Michael Feathers en 『Working Effectively with Legacy Code』.
El objetivo es moverlo conservando el comportamiento, así que el comportamiento actual es la línea base.
La segunda etapa es la más fácil: extrae lógica que no usa el estado de la instancia. Aquí el archivo suele reducirse visiblemente.
En la tercera etapa, los enum de Swift resultan útiles. Si tres estados de pantalla siempre cambian juntos, son un único objeto de estado.
// Antes: pueden expresarse combinaciones no válidas
var isLoading = false
var items: [Item] = []
var error: Error?
// Después: solo existe uno de los tres
enum ViewState {
case loading
case loaded([Item])
case failed(Error)
}
Agruparlos con enum elimina las combinaciones imposibles.
En iOS, la ruta de la cuarta etapa está clara: fuente de datos de tabla en un tipo separado, transiciones en un coordinador, estado y reglas de presentación en un modelo de vista, y pantallas grandes en controladores de vista hijos.
Si falta la quinta etapa, en seis meses volverá a ser igual. Define dónde va el código nuevo y establece un umbral con reglas de longitud o acuerdos de revisión para impedir que la siguiente función vuelva al mismo archivo.
Dos formas de fallar al dividirlo
| Forma de fallo | Qué ocurre |
|---|---|
| Cambiar solo los nombres | Dividiste AppManager en UserManager, DataManager y NetworkManager, pero los tres se referencian por completo. El God Object solo se convirtió en un God Cluster. |
| Dividirlo demasiado | Si divides una clase de 4.000 líneas en 40 tipos, esta vez desaparece el flujo. Es el código ravioli del artículo anterior. |
Al dividir, comprueba también que las dependencias fluyan en una sola dirección.
El objetivo no es crear fragmentos, sino que cada fragmento cambie solo por su propio motivo. El número de fragmentos es solo el resultado.
Resumen
- Un God Object se identifica por lo que conoce, no por su tamaño. Si conoce mucho, muchos lo conocen y el estado está disperso, encaja.
- Crece no por ser un mal diseño, sino porque cada vez se elige la opción más barata.
- El mayor daño es que no se puede probar. Sin pruebas no se divide; sin división sigue creciendo.
- La lista superior de frecuencia de cambios en Git es un indicador práctico.
- El orden es pruebas de caracterización → lógica sin estado → grupos de estado → separación por roles; al final se bloquea el camino para que vuelva a crecer.
El próximo artículo trata el problema posterior a dividir un God Object: tener que modificar doce archivos para cambiar una función, la cirugía de escopeta.
Fuentes y criterios de verificación
- AntiPatterns — Wiley · datos oficiales · verificado 2026-08-17 · base: información de publicación de AntiPatterns de 1998 y contexto de The Blob
- Human Perception on God Class Detection — Springer Nature · texto original del artículo · verificado 2026-08-17 · base: experimento controlado sobre diferencias entre personas y herramientas al identificar God Class

![Imagen de portada de [Código oloroso #4] Guía completa del God Object](/assets/images/posts/c44a316d-1d8c-4de3-8558-2b5452bdbcfe/god-object-dependency-overload.jpg)