Skip to content

Instantly share code, notes, and snippets.

@ggMartinez
Last active July 25, 2022 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ggMartinez/7fdfbf16dba986ac8b776c66e13bb33a to your computer and use it in GitHub Desktop.
Save ggMartinez/7fdfbf16dba986ac8b776c66e13bb33a to your computer and use it in GitHub Desktop.
Porque no usar Switch?

Porque no usar Switch?

El maldito Switch

Cuando escribimos codigo, a veces usamos la sentencia Switch/Case. Es tentador. Nos enseñaron que "son buenos". "Soluciona" un problema de "forma eficiente".

Es parte de los lenguajes, esta ahi y funciona. Pero siempre recuerden: que algo funcione, no quiere decir que este bien hecho o sea correcto.

El problema con Switch/Case, es que no es mantenible. Es imundo. Es profano. Es sucio. Es muy 1990. Switch viola un lote de buenas practicas modernas de desarrollo, acuerdos internacionales, derechos humanos y acuerdos intergalacticos.

Analicemos un caso

Veamos un caso de uso de Switch, que daño le hace a la humanidad, y como solucionarlo.

<?php
   enum Fruit{
      case Apple,
      case Orange,
      case Banana
   }
   
   $icons = [
         "apple" => "🍎",
         "orange" => "🍊",
         "banana" => "🍌"
   ];
      
   class FruitHelper{
      
      public function GetFruitColor($fruit){
         switch(fruit){
            case fruit::Apple: return "Green";
            case fruit::Orange: return "Orange"
            case fruit::Banana: return "Yellow";
         }
      }

      public function GetFruitIcon($fruit){
         switch(fruit){
            case fruit::Apple: return $icons['apple'];
            case fruit::Orange: return $icons['orange'];
            case fruit::Banana: return $icons['banana'];
         }
      }
   }

Este codigo es el demonio. No es mantenible.

Si, por ejemplo, agreguemos "Kiwi" al enum Fruits, y "🥝" al array $icons. Agregar un valor a ambos requiere modificar y actualizar el codigo de cada sentencia switch en el codigo.

Por ejemplo, estamos forzados a modificar la clase FruitHelper. No parece dificil, pero en una base de codigo mucho mas grande y compleja puede desatar la tercera guerra mundial. Consumiria mucho tiempo implementar el cambio. Ademas, seria facil olvidarnos realizar la modificacion en alguna de los switch, por lo que es propenso a errores.

Para hacer que el switch sea menos propenso a errores podriamos lanzar una excepcion en el bloque default de cada switch. Pero el problema es mas complejo que lanzar una simple excepcion. Eso seria querer detener una hemorragia con una curita. Necesitamos una alternativa a las sentencias switch.

Por ultimo, como la sentencia switch implica realizar modificaciones en las clases (las cuales pueden ser muchas), viola el principio abierto-cerrado de los principios SOLID:

"Las entidades de software(clases, modulos, funciones, etc) deben estar abiertas para su extensión, pero cerradas para su modificación”.

Robert C. Martin (Dios mismo)

En resumen: Las sentencias switch son diabolicas porque son propensas a errores y no son mantenibles.

Como evitarlos

Simple, no es 1990. Tenemos programacion orientada a objetos, y sobretodo, polimorfismo.

Podemos por ejemplo, realizar lo siguiente:

   abstract class Fruit{
      abstract public function GetIcon();
      abstract public function GetColor();
   }
   
   class Apple extends Fruit{
      public function GetColor(){
         return "Green";
      }
      public function GetIcon(){
         return "🍎";
      }
   }
   class Orange extends Fruit{
      public function GetColor(){
         return "Orange";
      }
      
      public function GetIcon(){
         return "🍊";
      }
   }
   class Banana extends Fruit{
      public function GetColor(){
         return "Yellow";
      }
      
      public function GetIcon(){
      return "🍌";
      }
   }

Reemplazamos los valores del enum con una clase. Fruit::Banana ahora esta representado por la clase Banana.

Ahora, es facil crear "Kiwi - 🥝": solamente tenemos que crear una clase llamada Kiwi. Mejor aun, no hay necesidad de modificar la clase FruitHelper, ni ninguna clase de las frutas existentes. Respetamos el principio abierto-cerrado. 👍

Conclusion

En resumen, podemos usar polimorfismo en lugar de Switches. Es menos propenso a errores, mas entendible y mas mantenible. Ademas, tiramos a la basura la clase FruitHelper, ya que es un todo-en-uno que tiene demasiada responsabilidad (viola el principio de Responsabildad Unica de SOLID).

Si bien no es un mundo perfecto, ni solucion perfecta, ya que agregar un nuevo metodo a la clase abstracta Fruit implica modificar cada subclase, es mucho mas facil trabajar de esta forma.

Referencia

https://www.linkedin.com/pulse/why-switch-statements-bad-th%C3%A9o-farnole-/?trk=public_profile_article_view

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment