Refactorización de código PHP: cuándo hacerla y cómo no dañar tu proyecto
\n\nTodo desarrollador PHP, tarde o temprano, se topa con código que quiere reescribir. Los proyectos legacy en PHP están llenos de "números mágicos" (magic numbers), funciones que ocupan toda la pantalla y clases que hacen de todo. Las manos te piden poner orden. Pero, ¿vale la pena? Y si es así, ¿cómo hacer una refactorización de código PHP segura y efectiva?
\n\nEn este artículo analizaremos cuándo la refactorización es realmente necesaria y cuándo es mejor dejar todo como está. Verás ejemplos reales de código malo y bueno en PHP, obtendrás un checklist de acciones y entenderás cómo no convertir una mejora de código en un desastre.
\n\n¿Cuándo está justificada la refactorización de código PHP?
\n\nLa refactorización es el cambio de la estructura interna del código sin alterar su comportamiento externo. Suena simple, pero en la práctica es una de las tareas más arriesgadas en el desarrollo. Estas son las señales de que es momento de mejorar tu código PHP:
\n\n- \n
- El código "huele mal" (code smells). Métodos largos, duplicación, clases dios (God objects), nombres de variables confusos. \n
- Añadir nueva funcionalidad se vuelve un suplicio. Si cada pull request rompe tres cosas en otros lugares, es una señal de alerta. \n
- No entiendes lo que hace un método una semana después de escribirlo. El código malo es aquel que necesita comentarios en cada línea. \n
- Se viola el principio de responsabilidad única (SRP). Una clase UserManager que crea usuarios, envía correos y genera informes es un candidato típico para refactorización. \n
Pero hay situaciones donde la refactorización de código PHP puede ser perjudicial:
\n- \n
- La fecha límite es mañana y el código funciona. \n
- No hay pruebas. Sin ellas, cualquier cambio es jugar a la ruleta rusa. \n
- El código se escribe "sobre la marcha" para un prototipo que se desechará mañana. \n
Reglas para una refactorización segura
\n\nAntes de lanzarte a la refactorización de código PHP, recuerda tres reglas de hierro:
\n\n- \n
- Cubre el código con pruebas. Al menos pruebas de integración. Si no hay pruebas, escríbelas para las partes críticas. \n
- Refactoriza en pasos pequeños. Un método a la vez. Sube los cambios, verifica, continúa. \n
- No mezcles refactorización con nuevas funcionalidades. Son dos tareas diferentes. Hazlas en commits separados. \n
Ejemplos de refactorización de código PHP: de malo a bueno
\n\nVeamos ejemplos reales. Supongamos que tenemos una función para calcular un descuento. Así se ve en un proyecto legacy típico:
\n\nAntes de la refactorización (código malo)
\nfunction calculateDiscount($user, $order) {\n $discount = 0;\n if ($user->isVip()) {\n $discount = 10;\n if ($order->getTotal() > 1000) {\n $discount = 15;\n }\n }\n if (date('Y-m-d') == '2025-12-31') {\n $discount = $discount + 5;\n }\n if ($order->getItemsCount() > 5) {\n $discount = $discount + 3;\n }\n return $discount;\n}\n\nProblemas: fechas mágicas, números constantes, mezcla de lógicas (usuario, pedido, fecha). Si mañana aparece una nueva promoción, la función se hará aún más larga.
\n\nDespués de la refactorización PHP (código bueno)
\nclass DiscountCalculator {\n private const NEW_YEAR_DATE = '2025-12-31';\n \n public function calculate(User $user, Order $order): int {\n $discount = $this->getBaseDiscount($user) \n + $this->getHolidayBonus() \n + $this->getVolumeBonus($order);\n \n return min($discount, 50); // no más del 50%\n }\n \n private function getBaseDiscount(User $user): int {\n if ($user->isVip() && $user->getTotalSpent() > 1000) {\n return 15;\n }\n return $user->isVip() ? 10 : 0;\n }\n \n private function getHolidayBonus(): int {\n retu