# Código heredado

Legacy code o código heredado es código fuente relacionado con un sistema operativo o una tecnología de computación sin soporte técnico. El término también puede aplicarse a código insertado en software más moderno para integrar u ofrecer soporte a una función creada en el pasado; por ejemplo dar soporte a una interfaz en serie incluso aunque muchos sistemas modernos no tienen un puerto serial. También puede aplicarse el término en el caso en que se de soporte a formatos de archivo más antiguos, que pueden haberse programado con caracteres que no pertenecen a ASCII tales como EBCDIC.

## Características

En la práctica, la mayor parte del código tiene una dependencia en cierto grado de la plataforma (hardware) para el que ha sido creado, a no ser que el programador utilice un lenguaje de programación independiente de la plataforma (ej. Java) o se trata de componentes del software con tal nivel de abstracción que no dependen del hardware (especialmente aplicaciones). Cuando un fabricante actualiza una plataforma (o esta se queda obsoleta), puede que el código ya no funcione sin modificaciones, es entonces cuando se habla de legacy code. Gran parte del trabajo de un ingeniero de software puede ser el tener que actualizar continuamente el código para evitar esto.
El término se usa normalmente para código fuente, pero también puede aplicarse a código ejecutable (executable) que no puede ejecutarse en versiones posteriores del sistema o que requiere de una capa de compatibilidad para ello. Un ejemplo puede ser una aplicación clásica de Macintosh que no funciona en Mac OS X, pero sí en el entorno clásico, o una aplicación Win16 en Windows XP usando la función Windows on Windows de XP.

## Interpretaciones modernas

Recientemente la comunidad de ingeniería de software ha desarrollado otras interpretaciones para el término "código heredado" donde cabe destacar código fuente heredado de algún otro sitio y código fuente heredado de una versión antigua del software. La obra de Michael Feathers Trabajando de forma efectiva con legacy code, introdujo una definición de legacy code cómo código sin testear, reseñando las dificultades de trabajar con "código heredado" por la falta de pruebas de regresión automatizadas. Según Falk Sippach, el tratamiento de código legado representa un ciclo perfecto de dependencias:
* Para entender el código heredado generalmente hace falta aplicar refactorizaciones.
* Sin embargo, es indispensable realizar pruebas cuando se refactoriza, pero,
* ¿Cómo escribir pruebas si todavía no se entiende el código?
Afortunadamente existen algunas técnicas que se aplican al momento de refactorizar código heredado y que permiten "entrar" en el ciclo perfecto:

### Copia dorada

Se hace una copia del código heredado al cual se le hacen cambios "triviales" que consisten en agregar código para llevar una pista de auditoría sobre el comportamiento del código. A continuación, en otra copia, se refactoriza el código y luego se comparan las pistas de la "copia dorada" y de la versión refactorizada. Ambos deben coincidir.

### Prueba de superclase

Se crea una clase que extiende la clase que se quiere probar y en ella se escriben las pruebas de métodos. De esta forma, la clase original no ha cambiado.

### Extraer funciones puras

Abstraer como funciones puras (funciones sin efectos de borde) parte del comportamiento de los métodos a refactorizar.

### Eliminar duplicaciones

Aplicar el principio No te repitas cuando haya código repetido.

### Extraer clases

Verificar si las clases heredadas cumplen con el principio de responsabilidad única y extraer clases con responsabilidad única a partir de las clases que no respetan este principio.

### Inversión de dependencias

Verificar si hay módulos de alto nivel que dependen de módulos de bajo nivel y aplicar el principio de inversión de dependencias.