---
title: "Reemplazar código de tipo con subclases"
type: "refactoring-technique"
slug: "replace-type-code-with-subclasses"
url: "http://localhost:3000/es/replace-type-code-with-subclasses.md"
category: "Organizing Data"
description: "Problema: tienes un tipo codificado que afecta directamente al comportamiento del programa (los valores de este campo disparan distinto código en condicionales). Solución: crea subclases para cada valor del tipo codificado. Luego extrae los comportamientos relevantes de la clase original a estas subclases. Reemplaza el código de control de flujo con polimorfismo."
---
# Reemplazar código de tipo con subclases

> Problema: tienes un tipo codificado que afecta directamente al comportamiento del programa (los valores de este campo disparan distinto código en condicionales). Solución: crea subclases para cada valor del tipo codificado. Luego extrae los comportamientos relevantes de la clase original a estas subclases. Reemplaza el código de control de flujo con polimorfismo.

## Problem

Tienes un tipo codificado que afecta directamente al comportamiento del programa (los valores de este campo disparan distinto código en condicionales).

## Solution

Crea subclases para cada valor del tipo codificado. Luego extrae los comportamientos relevantes de la clase original a estas subclases. Reemplaza el código de control de flujo con polimorfismo.

## Why Refactor

Esta técnica de refactorización es una variante más complicada de [Reemplazar código de tipo con clase](/es/replace-type-code-with-class).

Como en el primer método de refactorización, tienes un conjunto de valores simples que constituyen todos los valores permitidos para un campo. Aunque estos valores a menudo se especifican como constantes y tienen nombres comprensibles, su uso hace que tu código sea muy propenso a errores, ya que en la práctica siguen siendo primitivos. Por ejemplo, tienes un método que acepta uno de estos valores en los parámetros. En cierto momento, en lugar de la constante `USER_TYPE_ADMIN` con el valor `"ADMIN"`, el método recibe la misma cadena en minúsculas (`"admin"`), lo que provocará la ejecución de algo distinto de lo que el autor (tú) pretendía.

Aquí estamos tratando con código de control de flujo como los condicionales `if`, `switch` y `?:`. En otras palabras, los campos con valores codificados (como `$user->type === self::USER_TYPE_ADMIN`) se usan dentro de las condiciones de estos operadores. Si usáramos aquí [Reemplazar código de tipo con clase](/es/replace-type-code-with-class), lo mejor sería mover todas estas construcciones de control de flujo a una clase responsable del tipo de datos. En última instancia, esto crearía, por supuesto, una clase de tipo muy similar a la original, con los mismos problemas.

## Benefits

* Elimina el código de control de flujo. En lugar de un `switch` voluminoso en la clase original, mueve el código a las subclases apropiadas. Esto mejora la adhesión al _Principio de Responsabilidad Única_ y hace el programa más legible en general.
* Si necesitas añadir un nuevo valor para un tipo codificado, todo lo que tienes que hacer es añadir una nueva subclase sin tocar el código existente (cf. el _Principio Abierto/Cerrado_).
* Al reemplazar el código de tipo con clases, allanamos el camino para la indicación de tipos (type hinting) de métodos y campos a nivel del lenguaje de programación. Esto no sería posible usando simples valores numéricos o de cadena contenidos en un tipo codificado.

## How to Refactor

1. Usa [Autoencapsular campo](/es/self-encapsulate-field) para crear un getter para el campo que contiene el código de tipo.
2. Haz privado el constructor de la superclase. Crea un método de fábrica estático con los mismos parámetros que el constructor de la superclase. Debe contener el parámetro que tomará los valores iniciales del código de tipo. Dependiendo de este parámetro, el método de fábrica creará objetos de varias subclases. Para ello, en su código deberás crear un gran condicional pero, al menos, será el único cuando sea verdaderamente necesario; de lo contrario, se encargarán las subclases y el polimorfismo.
3. Crea una subclase única para cada valor del código de tipo. En ella, redefine el getter del código de tipo para que devuelva el valor correspondiente del código de tipo.
4. Elimina el campo con el código de tipo de la superclase. Haz su getter abstracto.
5. Ahora que tienes subclases, puedes empezar a mover los campos y métodos de la superclase a las subclases correspondientes (con ayuda de [Bajar campo](/es/push-down-field) y [Bajar método](/es/push-down-method)).
6. Cuando se haya movido todo lo posible, usa [Reemplazar condicional con polimorfismo](/es/replace-conditional-with-polymorphism) para deshacerte de las condiciones que usan el código de tipo de una vez por todas.
## Relations

**Similar techniques**

- [Reemplazar código de tipo con clase](/es/replace-type-code-with-class.md)
- [Reemplazar código de tipo con estado/estrategia](/es/replace-type-code-with-state-strategy.md)

**Opposite refactorings**

- [Reemplazar Subclase con Campos](/es/replace-subclass-with-fields.md)

**Eliminates smells**

- [Obsesión por los tipos primitivos](/es/smells/primitive-obsession.md)

