La mirada del replicante

No uses switch

09 de Julio de 2021

Vale, puede que me haya pasado. Antes que te tires a por mí voy a matizar el título un poquito. No uses switch en un lenguaje orientado a objetos. Es importante esta matización porque las razones por las que no deberías usar switch sólo se pueden aplicar a lenguajes orientados a objetos. De hecho, en otros lenguajes que no son orientados a objetos (como C) es inevitable usar la sentencia switch. Aclarado esto vamos al meollo: ¿Para qué usamos un switch? Normalmente, para tomar una decisión dependiendo de las alternativas. Esto suelen ser los tipos de un enumerado o los subtipos de una estructura o clase. Entonces, cada vez que queramos hacer algo con respecto a una variable del tipo del enum, montamos un switch con cada uno de los posibles valores del enum (o subtipo). De aquí en adelante mencionaré únicamente el enum, pero es aplicable a los subtipos.

Y esto, recalco, se hace cada vez. Así que terminamos preguntando por los posibles valores del enum en distintas partes del código.

Bien, y ahora ¿qué pasa si queremos añadir un nuevo valor al enum? Pues nos encontramos el primer antipatrón: cirugía a escopetazos. Esto viene a ser que tenemos que ir “escaneando” todo el código buscando aquellos sitios donde tengas un switch preguntando por los posibles valores del enum y añadir la implementación para la nueva opción.

Pero no es el único problema. Añadir un nuevo case a los switch supone modificar código ya escrito, con el riesgo de introducir problemas a un código que ya funciona. De esto es justo lo que nos advierte el principio open-closed, la U de SOLID: Un módulo de software debe estar abierto a la extensión pero cerrado a la modificación. Así que también violamos este principio.

En vez de usar switch podemos aplicar el refactor Replace conditional with Polymorphism [Refactoring, Martin Fowler]. En general, se trata de reemplazar el switch (o un if-else equivalente) por una jerarquía de clases y, usando polimorfismo, pasar la implementación de cada case a un método en cada una de las subclases (una por case). ¿Esto significa que no debes usar nunca un switch? No, pero su uso debería de estar justificado. En un lenguaje orientado a objetos debería ser extraño su uso.